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
