Cómo instalar cert-manager con validación HTTP en Kubernetes

Gestionar certificados SSL puede ser un dolor de cabeza, pero por suerte en Kubernetes podemos usar cert-manager y dejar que éste se encargue de todo para crear de forma fácil cualquier certificado que necesitemos.

En este how-to vamos a cubrir desde la instalación de cert-manager a cómo configurarlo para realizar la validación por HTTP. También aprenderemos a crear un nuevo certificado para nuestro host simplemente añadiendo una annotation a nuestro ingress.

¡Suena bien! ¿Qué necesito?

Deberías cumplir con estos requisitos:

  • Tener un clúster k8s funcional con nginx como ingress-controller
  • Tener helm instalado (lee aquí cómo instalar helm)
  • Tener un dominio en tu posesión que apunte hacia el clúster
  • Ganas de aprender algo nuevo 🙂

¡Empecemos!

Primero necesitamos añadir el repositorio de helm para cert-manager:

helm repo add jetstack https://charts.jetstack.io

Ahora procederemos a crear el nuevo namespace y hacer el deploy de cert-manager:

kubectl create ns cert-manager
helm upgrade --install cert-manager 
  --namespace cert-manager 
  --version v1.0.3 
  jetstack/cert-manager 
  --set installCRDs=true

Dale unos segundos de margen para que termine y deberías ver un mensaje de finalización con éxito.

Creando un ClusterIssuer

Podemos usar tanto un Issuer como un ClusterIssuer (namespace vs cluster-scoped). Es exactamente lo mismo, solo cambia el scope. El Issuer/ClusterIssuer representa la CA de la que queremos obtener el nuevo certificado, en este caso usaremos LetsEncrypt.

Fíjate a continuación que el objeto ClusterIssuer realmente es muy simple. Tanto el nombre como el nombre del secret pueden ser lo que tú quieras:

apiVersion: cert-manager.io/v1alpha3
kind: ClusterIssuer
metadata:
  name: my-cluster-issuer
spec:
  acme:
    email: {{ tu email }}
    privateKeySecretRef:
      name: my-cluster-issuer
    server: https://acme-v02.api.letsencrypt.org/directory
    solvers:
      - http01:
         ingress:
           class: nginx

Expidiendo un nuevo certificado

Vamos a hacer un deploy muy simple con un nginx, lo expondremos como servicio y después crearemos un ingress. Así pues, vamos allá:

kubectl create deployment nginx --image nginx:alpine --namespace test
kubectl expose deployment nginx --port 80 --target-port 80 --namespace test

Ahora crearemos un nuevo objeto ingress para hacer accesible el servicio a través del ingress controller. Recuerda reemplazar a continuación las ocurrencias del host con tu propio dominio:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
  labels:
    app: nginx
  name: nginx
  namespace: test
spec:
  rules:
  - host: nginx.{{ tu dominio }}
    http:
      paths:
      - backend:
          serviceName: nginx
          servicePort: 80
        path: /
  tls:
  - hosts:
    - nginx.{{ tu dominio }}
    secretName: nginx-certificate

Aplicamos el nuevo manifest:

kubectl apply -f ingress.yaml

Si ahora intentas acceder al host que has definido en el ingress verás un mensaje de error conforme tu certificado no es válido («Your connection is not private»). Para solucionarlo, vamos a expedir un nuevo certificado. Edita el ingress que has creado y añade la siguiente anotación, reemplazando el valor por el nombre que hayas puesto en tu ClusterIssuer:

cert-manager.io/cluster-issuer: my-cluster-issuer

Aplica el ingress de nuevo (o guarda los cambios si estás haciendo un edit) y revisa el estado del objeto «cert». Deberías ver algo así:

kubectl get cert -n test

NAME                READY   SECRET              AGE
nginx-certificate   False   nginx-certificate   21s

Ahora espera 1 o 2 minutos y cuando lo revises de nuevo…

kubectl get cert -n test

NAME                READY   SECRET              AGE
nginx-certificate   True    nginx-certificate   93s

… ¡hemos conseguido el certificado! Haz un test refrescando la página o abriendo una nueva pestaña y deberías ver el mensaje de bienvenida de Nginx. Si inspeccionas el certificado, verás que efectivamente éste ha sido expedido por LetsEncrypt:

Nginx letsencrypt certificate by cert-manager

Resumiendo

Lo que hemos visto aquí es:

  • Como instalar cert-manager
  • Como configurar un nuevo ClusterIssuer
  • Como expedir de forma sencilla un certificado

En líneas generales ha sido un proceso simple, ¿verdad? Es más, cuando sabes cómo funciona es muy fácil replicar este setup en cualquier clúster en cuestión de unos pocos minutos.

Cert-manager se encargará de la renovación de tus certificados. También puedes crear otros Issuers o ClusterIssuers que soporten otros CA o usar otros métodos de validación (DNS), pero eso es un tema algo más avanzado que dejaremos para más adelante.

Espero que hayas disfrutado con este how-to y que haya resultado útil. Recuerda que si necesitas cualquier cosa estaremos encantados de escucharte. ¡También puedes revisar nuestro blog para encontrar otras publicaciones útiles como ésta!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *