Qué es Cert-Manager y cómo configurar Cert-Manager para los certificados SSL en el cluster de Kubernetes en AWS usando Helm

Cert-Manager es un controlador utilizado para la gestión de certificados. Un Cert-Manager puede ayudar a emitir certificados de diferentes emisores como Let’s Encrypt, HashiCorp Vault, Venafi, un par de claves de firma simple o autofirmados. Cert-Manager valida los certificados, se asegura de que estén actualizados y los renueva antes de que caduquen. Cert-Manager está formado por varios componentes, como se menciona a continuación.

  1. Emisor: Los emisores, y los ClusterIssuers, son objetos en Kubernetes que representan a las autoridades de certificación (CA) que pueden generar certificados firmados.
  2. Certificado: Un Certificado es un recurso con espacio de nombre que hace referencia a un Emisor o ClusterIssuer y que se renovará y mantendrá actualizado.
  3. CertificateRequest: El CertificateRequest es un recurso namespaced que se utiliza para solicitar un certificado a un emisor o cluster issuer.
  4. Pedidos ACME: Un pedido representa una solicitud de certificado que se creará una vez que se haya creado un nuevo recurso CertificateRequest que haga referencia a un emisor ACME
  5. Desafíos ACME: Cuando se crea un recurso de Pedido, el controlador de pedidos creará recursos de Desafío para cada nombre DNS que se esté autorizando con el servidor ACME.
  6. Webhook: Se despliega como otro pod junto con los pods principales de Cert-Manager y tiene 3 funciones: ValidatingAdmissionWebhook, MutatingAdmissionWebhook y CustomResourceConversionWebhook.
  7. Inyector de CA: Ayuda a configurar los certificados para Validating Webhooks, Mutating Webhooks y Conversion Webhooks.

En este artículo, configuraremos un Gestor de Certificados con el emisor Let’s Encrypt. Aseguraremos nuestra aplicación de ejemplo utilizando los certificados TLS y tendremos HTTPS en nuestro Hostname para acceder a la aplicación utilizando Ingress. Para ello, añadiremos anotaciones al Ingress para que el recurso del certificado se cree en nuestro nombre.

Para conocer en detalle el Cert-Manager, visita la documentación oficial aquí. Este artículo se centra en la configuración del Cert-Manager mediante Helm y se supone que estás familiarizado con los conceptos relacionados con el Cert-Manager.

Requisitos previos

  1. Cuenta de AWS(Créala si no tienes una).
  2. Cluster de Kubernetes (Haz clic aquí para aprender a crear un Cluster de Kubernetes usando Kops y saber más sobre él).
  3. Controlador de entrada Nginx en el clúster K8S (Busca «Qué es el controlador de entrada y cómo desplegar el controlador de entrada Nginx en el clúster Kubernetes en AWS usando Helm» para aprender a configurar el controlador de entrada Nginx)
  4. Helm v3.5.3 (Haz clic aquí para aprender a instalar Helm en un servidor Ubuntu)
  5. Cubo S3 (Haz clic aquí para aprender a crear un cubo S3 en AWS).
  6. Nombre de dominio (Haz clic aquí para aprender a registrar un dominio en AWS).
  7. Rol IAM con permisos de administrador (Haz clic aquí para aprender a crear un rol IAM en AWS).

¿Qué vamos a hacer?

  1. Comprobar el controlador de entrada en el clúster
  2. Configurar un Cert-Manager
  3. Crear archivos de definición de objetos para una aplicación de ejemplo
  4. Configurar el emisor de Let’s Encrypt de producción y de ensayo
  5. Despliega una aplicación de ejemplo
  6. Despliega un objeto de entrada con TLS

Comprueba el controlador de entrada en el clúster

Antes de continuar, comprueba si tienes el controlador de entrada de Nginx funcionando en el clúster.

kubectl get pods
kubectl get svc

Comprueba el controlador de entrada en el clúster

Configurar el gestor de certificados

Note: I have used Helm binary present at my current location, hence you can see ./helm in screenshots.

Utiliza Helm v3.5.3 y ejecuta los siguientes comandos, esto instalará la carta Helm para Cert-Manager.

kubectl create namespace cert-manager
helm repo add jetstack https://charts.jetstack.io
helm repo update helm install cert-manager jetstack/cert-manager --namespace cert-manager --version v1.2.0 --set installCRDs=true

Configurar el Gestor de Certificados

En la captura de pantalla anterior, puedes ver que se ha instalado la Carta Helm para Cert-Manager.

Comprueba los pods que se han creado como parte del Cert-Manager.

kubectl get pods -A

Cert Manager Pods

Puedes ver 3 nuevos pods en el espacio de nombres «cert-manager».

Crea archivos de definición de objetos para una aplicación de ejemplo y emisores

Crea 1-nginx-main-app.yaml para la aplicación 1

Enlace Github: Haz clic aquí para copiar el archivo de mi repo de Github.

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: nginx
  name: nginx-deploy-main
spec:
  replicas: 1
  selector:
    matchLabels:
      run: nginx-main
  template:
    metadata:
      labels:
        run: nginx-main
    spec:
      containers:
      - image: nginx
        name: nginx


---
apiVersion: v1
kind: Service
metadata:
  name: nginx-deploy-main
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 80
  selector:
    run: nginx-main

Crea 2-nginx-green-app.yaml para la aplicación 2.

Enlace Github: Haz clic aquí para copiar el archivo de mi repositorio de Github.

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: nginx
  name: nginx-deploy-green
spec:
  replicas: 1
  selector:
    matchLabels:
      run: nginx-green
  template:
    metadata:
      labels:
        run: nginx-green
    spec:
      volumes:
      - name: webdata
        emptyDir: {}
      initContainers:
      - name: web-content
        image: busybox
        volumeMounts:
        - name: webdata
          mountPath: "/webdata"
        command: ["/bin/sh", "-c", 'echo "<h1>I am <font color=green>GREEN</font></h1>" > /webdata/index.html']
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - name: webdata
          mountPath: "/usr/share/nginx/html"


---
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-deploy-green
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 80
  selector:
    run: nginx-green          

Crea 3-nginx-blue-app.yaml para la aplicación 3

Enlace Github: Haz clic aquí para copiar el archivo de mi repo de Github.

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: nginx
  name: nginx-deploy-blue
spec:
  replicas: 1
  selector:
    matchLabels:
      run: nginx-blue
  template:
    metadata:
      labels:
        run: nginx-blue
    spec:
      volumes:
      - name: webdata
        emptyDir: {}
      initContainers:
      - name: web-content
        image: busybox
        volumeMounts:
        - name: webdata
          mountPath: "/webdata"
        command: ["/bin/sh", "-c", 'echo "<h1>I am <font color=blue>BLUE</font></h1>" > /webdata/index.html']
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - name: webdata
          mountPath: "/usr/share/nginx/html"


---
apiVersion: v1
kind: Service
metadata:
  name: nginx-deploy-blue
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 80
  selector:
    run: nginx-blue

Crea 4-tls-ingress.yaml para crear reglas de Ingress basadas en la ruta con Staging Issuer.

Enlace Github: Haz clic aquí para copiar el archivo de mi repositorio de Github.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    cert-manager.io/cluster-issuer: letsencrypt-staging
  name: ingress-resource-3
spec:
  tls:
  - hosts:
    - kops.devopslee.com
    secretName: sample-kubernetes-tls
  rules:
  - host: kops.devopslee.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-deploy-main
          servicePort: 80
      - path: /blue
        backend:
          serviceName: nginx-deploy-blue
          servicePort: 80
      - path: /green
        backend:
          serviceName: nginx-deploy-green
          servicePort: 80

Crea 5-tls-ingress-prod-issuer.yaml para crear reglas de entrada basadas en la ruta con el emisor de producción.

Enlace Github: Haz clic aquí para copiar el archivo de mi repositorio de Github.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    cert-manager.io/cluster-issuer: letsencrypt-production
  name: ingress-resource-3
spec:
  tls:
  - hosts:
    - kops.devopslee.com
    secretName: sample-kubernetes-tls
  rules:
  - host: kops.devopslee.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-deploy-main
          servicePort: 80
      - path: /blue
        backend:
          serviceName: nginx-deploy-blue
          servicePort: 80
      - path: /green
        backend:
          serviceName: nginx-deploy-green
          servicePort: 80

Crear staging_issuer.yaml para Let’s Encrypt Staging Issuer

Enlace Github: Haz clic aquí para copiar el archivo de mi repositorio de Github.

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    # Email address used for ACME registration
    email: your-email-id-here
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      # Name of a secret used to store the ACME account private key
      name: letsencrypt-staging-private-key
    # Add a single challenge solver, HTTP01 using nginx
    solvers:
    - http01:
        ingress:
          class: nginx

Crea production_issuer.yaml para el emisor de producción de Let’s Encrypt

Enlace Github: Haz clic aquí para copiar el archivo de mi repositorio de Github.

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-production
spec:
  acme:
    # Email address used for ACME registration
    email: your-email-id-here
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      # Name of a secret used to store the ACME account private key
      name: letsencrypt-production-private-key
    # Add a single challenge solver, HTTP01 using nginx
    solvers:
    - http01:
        ingress:
          class: nginx

Puedes encontrar todos estos archivos en mi repositorio de Github aquí.

Configurar el emisor de Let’s Encrypt de producción y de ensayo

Vamos a instalar el emisor de clústeres de ensayo y de producción.

Puesta enmarcha:

Staging tiene «servidor: https://acme-staging-v02.api.letsencrypt.org/directory»

kubectl logs cert-manager-56f5c44b5d-jn46m -n cert-manager -f
kubectl apply -f cluster-issuer/staging_issuer.yaml

Configurar el emisor del clúster de Let's Encrypt

Esto crea un secreto llamado «letsencrypt-staging-private-key».

kubectl get secret letsencrypt-staging-private-key -n cert-manager -o json

Comprueba el secreto de la puesta en escena

Producción:

Producción tiene «servidor: https://acme-v02.api.letsencrypt.org/directory»

kubectl logs cert-manager-56f5c44b5d-jn46m -n cert-manager -f
kubectl apply -f cluster-issuer/production_issuer.yaml

Configurar el emisor del clúster de producción de Let's Encrypt

Esto crea un secreto llamado «letsencrypt-production-private-key».

kubectl get secret letsencrypt-production-private-key -n cert-manager -o json

Comprueba el secreto de producción

Despliega una aplicación de ejemplo

Vamos a desplegar nuestras 3 aplicaciones de ejemplo.

kubectl apply -f sample-app/1-nginx-main-app.yaml
kubectl apply -f sample-app/2-nginx-green-app.yaml
kubectl apply -f sample-app/3-nginx-blue-app.yaml
Check the deployments, pods, and services created by the above commands.
kubectl get deployments
kubectl get pods kubectl
get service

Despliega una aplicación de ejemplo

Despliegue de Ingress

En primer lugar, vamos a desplegar un Ingress con Staging Issuer.

kubectl apply -f sample-app/4-tls-ingress.yaml
kubectl get ingress
kubectl describe ingress ingress-resource-3

Crear entrada con emisor de etapas

Una vez creado el recurso Ingress, puedes ver todo lo que ha ocurrido en segundo plano para emitir el certificado para la sección TLS del Ingress.

kubectl get certificate -A
kubectl get certificaterequests.cert-manager.io -A
kubectl get orders.acme.cert-manager.io -A
kubectl get challenges.acme.cert-manager.io -A
kubectl get certificate  -o json | grep secretName
kubectl get secret sample-kubernetes-tls -o yaml

Comprueba el certificado, la solicitud de certificado, el pedido y el secreto

Ahora se puede acceder a la aplicación a través de HTTPS, pero como hemos utilizado el Entorno de Escenificación del emisor Let’s Encrypt obtendremos una advertencia «Tu conexión a este sitio no es segura».

Prueba las URLs con HTTPS, certificados de Staging

Despliega Ingress con el emisor de producción.

Ahora, vamos a eliminar el Ingress utilizando el Staging y a crear un nuevo Ingress apuntando al emisor de Producción.

kubectl delete -f sample-app/4-tls-ingress.yaml
kubectl apply -f sample-app/5-tls-ingress-prod-issuer.yaml
kubectl get ingress
kubectl describe ingress ingress-resource-3

Crear entrada con emisor de producción

Esta vez, si intentas acceder a la aplicación, no recibirás ninguna advertencia como «La conexión a este sitio no es segura».

Prueba las URL con HTTPS, certificados de Producción

Conclusión

En este artículo, hemos visto los pasos para configurar un Cert-Manager en el Cluster de Kubernetes. Desplegamos una aplicación de ejemplo y enrutamos el tráfico a través de la entrada basándonos en la ruta y aseguramos la conexión con HTTPS utilizando un certificado emitido por el emisor del clúster Let’s Encrypt. Primero emitimos un certificado utilizando el entorno de Let’s Encrypt Staging y luego utilizamos el entorno de Let’s Encrypt de producción

También te podría gustar...