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.
- Emisor: Los emisores, y los ClusterIssuers, son objetos en Kubernetes que representan a las autoridades de certificación (CA) que pueden generar certificados firmados.
- 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.
- CertificateRequest: El CertificateRequest es un recurso namespaced que se utiliza para solicitar un certificado a un emisor o cluster issuer.
- 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
- 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.
- Webhook: Se despliega como otro pod junto con los pods principales de Cert-Manager y tiene 3 funciones: ValidatingAdmissionWebhook, MutatingAdmissionWebhook y CustomResourceConversionWebhook.
- 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
- Cuenta de AWS(Créala si no tienes una).
- Cluster de Kubernetes (Haz clic aquí para aprender a crear un Cluster de Kubernetes usando Kops y saber más sobre él).
- 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)
- Helm v3.5.3 (Haz clic aquí para aprender a instalar Helm en un servidor Ubuntu)
- Cubo S3 (Haz clic aquí para aprender a crear un cubo S3 en AWS).
- Nombre de dominio (Haz clic aquí para aprender a registrar un dominio en AWS).
- Rol IAM con permisos de administrador (Haz clic aquí para aprender a crear un rol IAM en AWS).
¿Qué vamos a hacer?
- Comprobar el controlador de entrada en el clúster
- Configurar un Cert-Manager
- Crear archivos de definición de objetos para una aplicación de ejemplo
- Configurar el emisor de Let’s Encrypt de producción y de ensayo
- Despliega una aplicación de ejemplo
- 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
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
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
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
Esto crea un secreto llamado «letsencrypt-staging-private-key».
kubectl get secret letsencrypt-staging-private-key -n cert-manager -o json
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
Esto crea un secreto llamado «letsencrypt-production-private-key».
kubectl get secret letsencrypt-production-private-key -n cert-manager -o json
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
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
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
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».
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
Esta vez, si intentas acceder a la aplicación, no recibirás ninguna advertencia como «La conexión a este sitio no es segura».
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