Cert-Manager es un controlador utilizado para la gestión de certificados. Un administrador de certificados puede ayudar a emitir certificados de diferentes emisores como Let's Encrypt, HashiCorp Vault, Venafi, un par de claves de firma simple o autofirmado. Cert-Manager valida los certificados, se asegura de que estén actualizados y los renueva antes de que caduquen. Cert-Manager se compone de varios componentes como se menciona a continuación.
- Emisor : Emisores y ClusterIssuers son objetos en Kubernetes que representan autoridades de certificación (CA) que pueden generar certificados firmados.
- Certificado : Un Certificado es un recurso con espacio de nombres que hace referencia a un Emisor o ClusterIssuer y se renovará y mantendrá actualizado.
- Solicitud de certificado : CertificateRequest es un recurso de espacio de nombres que se utiliza para solicitar un certificado de un emisor o emisor de clúster.
- 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 de DNS que se autorice con el servidor ACME.
- Webhook :se implementa como otro pod junto con los pods principales de Cert-Manager y tiene 3 funciones: ValidatingAdmissionWebhook, MutatingAdmissionWebhook y CustomResourceConversionWebhook.
- CA Inyectado r:Ayuda a configurar certificados para Validación de webhooks, Mutación de webhooks y Conversión de webhooks.
En este artículo, configuraremos un administrador de certificados con el emisor de Let's Encrypt. Protegeremos nuestra aplicación de muestra usando los certificados TLS y tendremos HTTPS en nuestro nombre de host para acceder a la aplicación usando Ingress. Para hacer esto, agregaremos anotaciones al Ingress para que el recurso de certificado se cree en nuestro nombre.
Para conocer en detalle acerca de Cert-Manager, visite la documentación oficial aquí. El objetivo de este artículo es configurar Cert-Manager usando Helm y se supone que está familiarizado con los conceptos relacionados con Cert-Manager.
Requisitos previos
- Cuenta de AWS (cree si no tiene una).
- Clúster de Kubernetes (haga clic aquí para aprender a crear un clúster de Kubernetes con Kops y obtener más información al respecto).
- Controlador de entrada de Nginx en el clúster K8S (busque "¿Qué es el controlador de entrada y cómo implementar el controlador de entrada de Nginx en el clúster de Kubernetes en AWS usando Helm" para aprender a configurar el controlador de entrada de Nginx)
- Helm v3.5.3 (Haga clic aquí para aprender a instalar Helm en Ubuntu Server)
- Cubo de S3 (haga clic aquí para aprender a crear un cubo de S3 en AWS).
- Nombre de dominio (haga clic aquí para aprender a registrar un dominio en AWS).
- Rol de IAM con permisos de administrador (haga clic aquí para aprender a crear un rol de IAM en AWS).
¿Qué haremos?
- Comprobar el controlador de entrada en el clúster
- Configurar un administrador de certificados
- Crear archivos de definición de objetos para una aplicación de muestra
- Configurar puesta en escena y producción Let's Encrypt Issuer
- Implementar una aplicación de muestra
- Implementar un objeto de entrada con TLS
Comprobar controlador de entrada en el clúster
Antes de continuar, compruebe si tiene el controlador de entrada de Nginx ejecutándose en el clúster.
kubectl get pods
kubectl get svc
Administrador de certificados de configuración
Note: I have used Helm binary present at my current location, hence you can see ./helm in screenshots.
Use Helm v3.5.3 y ejecute los siguientes comandos, esto instalará Helm Chart 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, puede ver que se instaló Helm Chart para Cert-Manager.
Compruebe los pods que se han creado como parte de Cert-Manager.
kubectl get pods -A
Puede ver 3 pods nuevos en el espacio de nombres "cert-manager".
Crear archivos de definición de objetos para una aplicación de muestra y emisores
Cree 1-nginx-main-app.yaml para la aplicación 1
Enlace de Github:haga clic aquí para copiar el archivo de mi repositorio 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
Cree 2-nginx-green-app.yaml para la aplicación 2.
Enlace de Github:haga 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
Cree 3-nginx-blue-app.yaml para la aplicación 3
Enlace de Github:haga clic aquí para copiar el archivo de mi repositorio 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
Cree 4-tls-ingress.yaml para crear reglas de entrada basadas en rutas con Staging Issuer.
Enlace de Github:haga 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
Cree 5-tls-ingress-prod-issuer.yaml para crear reglas de ingreso basadas en rutas con Production Issuer.
Enlace de Github:haga 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
Cree staging_issuer.yaml para Let's Encrypt Staging Issuer
Enlace de Github:haga 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
Cree production_issuer.yaml para Let's Encrypt Production Issuer
Enlace de Github:haga 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
Puede encontrar todos estos archivos en mi repositorio de Github aquí.
Configurar la puesta en escena y producción Let's Encrypt Issuer
Instalaremos el Emisor de clúster de producción y ensayo.
Puesta en escena :
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 :
La 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
Implementar una aplicación de muestra
Implementemos nuestras 3 aplicaciones de muestra.
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
Implementar entrada
Primero, implementemos un Ingress con Staging Issuer.
kubectl apply -f sample-app/4-tls-ingress.yaml
kubectl get ingress
kubectl describe ingress ingress-resource-3
Después de crear el recurso Ingress, puede ver todo lo que sucedió en segundo plano para emitir el certificado para la sección TLS de 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 dado que hemos utilizado el entorno de prueba del emisor de Let's Encrypt, recibiremos una advertencia "Su conexión a este sitio no es segura".
Implemente Ingress con Production Issuer.
Ahora, eliminemos el Ingress usando Staging y creemos un nuevo Ingress apuntado 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 intenta acceder a la aplicación, no recibirá ninguna advertencia como "La conexión a este sitio no es segura".
Conclusión
En este artículo, vimos los pasos para configurar un administrador de certificados en el clúster de Kubernetes. Implementamos una aplicación de muestra y enrutamos el tráfico a través del ingreso en función de la ruta y aseguramos la conexión con HTTPS mediante el uso de un certificado emitido por el emisor del clúster Let's Encrypt. Primero emitimos un certificado usando el entorno de ensayo de Let's Encrypt y luego usamos el entorno de producción de Let's Encrypt