15%

Ahorra 15%<\/span> en todos los servicios de hosting

Pon a prueba tus habilidades y obtén Descuento<\/span> en cualquier plan de hosting

Usa el código:

Skills
Comenzar
22.10.2024

Cert-Manager en Kubernetes: Guía completa de configuración para la gestión automatizada de certificados TLS

Cert-Manager es un controlador Kubernetes de código abierto que automatiza completamente el ciclo de vida de los certificados TLS — desde la emisión inicial hasta la validación y renovación — integrándose directamente con autoridades de certificación como Let’s Encrypt, HashiCorp Vault y sistemas PKI privados. Elimina los flujos de trabajo manuales de certificados al tratar los certificados como recursos nativos de Kubernetes, gestionados de forma declarativa mediante Custom Resource Definitions (CRDs).

Para cualquier clúster Kubernetes en producción, los certificados TLS vencidos o mal configurados son una de las causas más comunes de tiempo de inactividad no planificado. Cert-Manager resuelve esto reconciliando continuamente el estado de los certificados, renovando automáticamente las credenciales antes de su vencimiento y almacenando el material de clave resultante en Secrets de Kubernetes que los controladores Ingress y las cargas de trabajo pueden consumir de inmediato.

Por Qué Cert-Manager Es el Estándar para la Automatización TLS en Kubernetes

Antes de que Cert-Manager se convirtiera en la solución de facto, los equipos o bien programaban renovaciones de certbot en nodos individuales, rotaban manualmente los certificados entre namespaces, o dependían de integraciones específicas de proveedores de nube que generaban dependencia del proveedor. Cert-Manager unifica todos estos enfoques bajo un único plano de control nativo de Kubernetes.

Ventajas clave sobre los enfoques ad-hoc:

  • Gestión declarativa: La intención del certificado se expresa como un manifiesto YAML, con control de versiones junto al código de la aplicación.
  • Reconciliación automática: El bucle del controlador detecta la divergencia entre el estado deseado y el real del certificado y lo corrige sin intervención humana.
  • Soporte multi-emisor: Un único clúster puede usar simultáneamente Let’s Encrypt para servicios públicos, una CA interna para mTLS de service-mesh y HashiCorp Vault para cargas de trabajo sensibles a secretos.
  • Registro de auditoría: Cada objeto CertificateRequest se persiste en la API de Kubernetes, proporcionando un historial completo de emisión.

Ejecutar Kubernetes en una plataforma de VPS Hosting con almacenamiento respaldado por NVMe y acceso root completo le brinda el control necesario para configurar resolvers DNS personalizados, gestionar reglas de firewall para los desafíos HTTP-01 de ACME e instalar CRDs a nivel de clúster sin restricciones — todos requisitos previos para un despliegue de Cert-Manager de nivel productivo.

Arquitectura Central: Cómo Funciona Cert-Manager Internamente

Comprender la arquitectura interna de Cert-Manager previene configuraciones incorrectas y le ayuda a depurar fallos de emisión rápidamente.

La Máquina de Estados del Ciclo de Vida del Certificado

Cert-Manager gestiona los certificados a través de una máquina de estados determinista. Cada recurso Certificate transita por los siguientes estados:

  1. Pending — El objeto Certificate existe pero ningún CertificateRequest válido ha sido completado.
  2. Issuing — Se ha creado un CertificateRequest y se ha enviado al emisor configurado.
  3. Ready — Un certificado válido y no vencido está almacenado en el Secret de Kubernetes referenciado.
  4. Renewal Pending — El certificado está dentro de la ventana renewBefore (por defecto: 30 días antes del vencimiento) y se está procesando un nuevo CertificateRequest.

El controlador monitorea todos los objetos Certificate en todo el clúster y reconcilia continuamente su estado. Si un Secret se elimina manualmente, Cert-Manager detecta el recurso faltante e inmediatamente activa la re-emisión — un comportamiento de auto-recuperación crítico que previene interrupciones accidentales.

Componentes CRD Principales

RecursoAlcancePropósito
`Issuer`NamespaceDefine una configuración de CA para un único namespace
`ClusterIssuer`A nivel de clústerDefine una configuración de CA utilizable por todos los namespaces
`Certificate`NamespaceDeclara el certificado TLS deseado y sus propiedades
`CertificateRequest`NamespaceRastrea una solicitud de firma de certificado única en un momento determinado
`Order`NamespaceRepresenta una orden ACME con una CA (p. ej., Let’s Encrypt)
`Challenge`NamespaceRastrea un único desafío ACME (HTTP-01 o DNS-01)

Los recursos Order y Challenge son creados automáticamente por el emisor ACME — raramente interactúa con ellos directamente, pero inspeccionarlos es la ruta principal de depuración cuando la emisión se detiene.

Almacenamiento de Certificados y Formato de Secret

Una vez emitido, Cert-Manager escribe tres claves de datos en el Secret de Kubernetes de destino:

  • tls.crt — La cadena de certificados completa (hoja + intermedios), codificada en PEM.
  • tls.key — La clave privada, codificada en PEM.
  • ca.crt — El certificado de la CA emisora (se rellena para CAs internas; puede estar vacío para emisores ACME).

Los controladores Ingress, las mallas de servicios y los pods de aplicaciones montan este Secret directamente. El formato es compatible con NGINX, Traefik, Istio, Linkerd y la mayoría de los demás consumidores TLS nativos de Kubernetes.

Emisores Compatibles y Cuándo Usar Cada Uno

ACME (Let’s Encrypt y Alternativas)

El protocolo ACME es la ruta de emisión más común. Cert-Manager implementa el cliente ACME completo según RFC 8555, compatible con endpoints de staging y producción.

Desafío HTTP-01: Cert-Manager sirve temporalmente un token en http://<domain>/.well-known/acme-challenge/<token>. Esto requiere que el dominio resuelva a una IP públicamente accesible en el puerto 80. Funciona para certificados de dominio único y SAN, pero no puede emitir certificados wildcard.

Desafío DNS-01: Cert-Manager crea un registro TXT _acme-challenge.<domain> a través de una API de proveedor DNS. Esto funciona detrás de firewalls, admite certificados wildcard (*.example.com) y es necesario para cualquier clúster no expuesto directamente a internet. Los proveedores DNS compatibles incluyen Cloudflare, Route53, Google Cloud DNS, Azure DNS y muchos otros mediante solvers webhook.

HashiCorp Vault

El emisor Vault se integra con el motor de secretos PKI de Vault. Es la opción preferida para:

  • mTLS de microservicios internos donde los certificados deben ser de corta duración (horas, no meses).
  • Entornos con requisitos estrictos de custodia de claves donde las claves privadas nunca deben salir de Vault.
  • Rotación automatizada de certificados vinculada al sistema de renovación de arrendamientos de Vault.

Emisores Self-Signed y CA

El emisor SelfSigned genera certificados firmados por la propia clave privada del certificado — útil para inicializar una CA raíz dentro del clúster. El emisor CA utiliza un Secret de Kubernetes que contiene un par de claves CA para firmar certificados, lo que lo hace adecuado para entornos de desarrollo interno y PKI de service mesh.

Venafi

La integración con Venafi está orientada a entornos empresariales con aplicación centralizada de políticas de certificados, auditoría de cumplimiento e integración con módulos de seguridad de hardware (HSMs).

Cert-Manager vs. Enfoques Alternativos de Automatización TLS

EnfoqueSoporte WildcardNativo de KubernetesMulti-CARenovación AutomáticaComplejidad
Cert-ManagerSí (DNS-01)Sí (CRDs)Media
Certbot ManualNo (solo HTTP-01)NoLimitadoCon scriptsBaja–Media
Terminación TLS en LB de NubeVariableNoNoBaja
Istio / CA de Service MeshSolo internoNoAlta
HashiCorp Vault (independiente)NoManualAlta

Para equipos que ejecutan Kubernetes en un Servidor Dedicado o VPS, Cert-Manager es el único enfoque que es simultáneamente nativo de Kubernetes, admite todas las CAs principales y no requiere ninguna intervención manual continua.

Instalación de Cert-Manager: Configuración Lista para Producción

Requisitos Previos

  • Kubernetes 1.22+ (se recomienda 1.26+ para plena estabilidad de CRD)
  • kubectl configurado con privilegios de cluster-admin
  • Helm 3.x instalado
  • Un dominio registrado con acceso a la gestión DNS (para DNS-01) o una IP de ingress públicamente accesible (para HTTP-01)

Si gestiona su propio dominio, se recomienda encarecidamente el Registro de Dominios a través de un proveedor que exponga una API — permite resolver completamente los desafíos DNS-01 de forma automatizada sin intervención manual.

Paso 1: Instalar CRDs y el Controlador Cert-Manager

El método de instalación en producción recomendado utiliza Helm con CRDs gestionados por separado para evitar conflictos en las actualizaciones de Helm:

# Add the Jetstack Helm repository
helm repo add jetstack https://charts.jetstack.io
helm repo update

# Install Cert-Manager with CRDs included
helm install cert-manager jetstack/cert-manager 
  --namespace cert-manager 
  --create-namespace 
  --version v1.14.5 
  --set installCRDs=true 
  --set global.leaderElection.namespace=cert-manager

Verifique que los tres pods principales estén en ejecución antes de continuar:

kubectl get pods --namespace cert-manager

Salida esperada:

NAME                                       READY   STATUS    RESTARTS   AGE
cert-manager-xxxxxxxxx-xxxxx              1/1     Running   0          60s
cert-manager-cainjector-xxxxxxxxx-xxxxx   1/1     Running   0          60s
cert-manager-webhook-xxxxxxxxx-xxxxx      1/1     Running   0          60s

El cainjector inyecta datos del bundle CA en las configuraciones de webhook. El webhook valida y muta los objetos CRD de Cert-Manager — si no está en ejecución, todas las operaciones kubectl apply sobre recursos de Cert-Manager fallarán.

Paso 2: Configurar un ClusterIssuer para Let’s Encrypt

Comience siempre con el entorno de staging de Let’s Encrypt para evitar alcanzar los límites de tasa de producción (50 certificados por dominio registrado por semana):

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: ops@example.com
    privateKeySecretRef:
      name: letsencrypt-staging-account-key
    solvers:
      - http01:
          ingress:
            class: nginx

Una vez que los certificados de staging se emitan correctamente, cree el emisor de producción:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: ops@example.com
    privateKeySecretRef:
      name: letsencrypt-prod-account-key
    solvers:
      - http01:
          ingress:
            class: nginx

Aplique ambos manifiestos:

kubectl apply -f clusterissuer-staging.yaml
kubectl apply -f clusterissuer-prod.yaml

Verifique la disponibilidad del emisor:

kubectl describe clusterissuer letsencrypt-prod

El campo Status.Conditions debe mostrar Ready: True. Si muestra False, el registro de la cuenta ACME falló — verifique la dirección de correo electrónico y la conectividad de red desde el pod de cert-manager.

Paso 3: Solicitar un Certificado Explícitamente

Puede solicitar certificados ya sea creando un recurso Certificate directamente o anotando un recurso Ingress. El enfoque explícito con Certificate le brinda más control:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: example-com-tls
  namespace: production
spec:
  secretName: example-com-tls-secret
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  commonName: example.com
  dnsNames:
    - example.com
    - www.example.com
  duration: 2160h    # 90 days (Let's Encrypt default)
  renewBefore: 720h  # Renew 30 days before expiry

Aplique y monitoree la emisión:

kubectl apply -f certificate.yaml
kubectl describe certificate example-com-tls -n production

Observe los objetos CertificateRequest y Order para obtener el estado detallado:

kubectl get certificaterequest -n production
kubectl describe order -n production

Paso 4: Método de Anotación en Ingress (Simplificado)

Para equipos que usan NGINX Ingress Controller, Cert-Manager puede activarse automáticamente mediante una anotación — no se requiere un manifiesto Certificate separado:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: production
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - example.com
        - www.example.com
      secretName: example-com-tls-secret
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: example-service
                port:
                  number: 80

Cert-Manager detecta la anotación y crea automáticamente el recurso Certificate correspondiente. Este es el patrón más común en flujos de trabajo GitOps.

Patrones de Configuración Avanzada

Certificados Wildcard con DNS-01 (Ejemplo con Cloudflare)

Los certificados wildcard requieren validación DNS-01. Primero, cree un Secret que contenga su token API de Cloudflare:

kubectl create secret generic cloudflare-api-token 
  --from-literal=api-token=<YOUR_CLOUDFLARE_API_TOKEN> 
  --namespace cert-manager

Configure el ClusterIssuer con un solver DNS-01:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod-dns
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: ops@example.com
    privateKeySecretRef:
      name: letsencrypt-prod-dns-account-key
    solvers:
      - dns01:
          cloudflare:
            apiTokenSecretRef:
              name: cloudflare-api-token
              key: api-token

Solicite el certificado wildcard:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: wildcard-example-com
  namespace: production
spec:
  secretName: wildcard-example-com-tls
  issuerRef:
    name: letsencrypt-prod-dns
    kind: ClusterIssuer
  dnsNames:
    - "*.example.com"
    - example.com

Problema crítico: El Secret que contiene las credenciales del proveedor DNS debe residir en el namespace cert-manager cuando es referenciado por un ClusterIssuer. Si lo coloca en otro namespace, el controlador no podrá leerlo y la emisión fallará silenciosamente. Verifique los logs del controlador de cert-manager con kubectl logs -n cert-manager deploy/cert-manager si los desafíos se detienen.

PKI Interna con un Emisor CA

Para mTLS entre servicios dentro de un clúster, un emisor CA respaldado por una raíz autofirmada es más apropiado que ACME:

# Step 1: Create a self-signed root CA certificate
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: selfsigned-root
spec:
  selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: internal-root-ca
  namespace: cert-manager
spec:
  isCA: true
  commonName: internal-root-ca
  secretName: internal-root-ca-secret
  issuerRef:
    name: selfsigned-root
    kind: ClusterIssuer
---
# Step 2: Create a CA issuer backed by the root certificate
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: internal-ca-issuer
spec:
  ca:
    secretName: internal-root-ca-secret

Los servicios ahora pueden solicitar certificados de corta duración a internal-ca-issuer para mTLS sin ninguna dependencia de CA externa.

Configuración de renewBefore para Entornos de Alta Seguridad

El renewBefore predeterminado de 30 días es apropiado para los certificados de 90 días de Let’s Encrypt. Para certificados internos de corta duración (p. ej., validez de 24 horas), establezca renewBefore como una fracción de la duración total:

spec:
  duration: 24h
  renewBefore: 8h

Cert-Manager comenzará la renovación 8 horas antes del vencimiento, dando al controlador tres ventanas de renovación dentro de un ciclo de vida de certificado de 24 horas — un margen de seguridad crítico si el clúster experimenta indisponibilidad transitoria del servidor API.

Depuración de Fallos Comunes de Cert-Manager

Certificado Atascado en Estado “Issuing”

# Check the Certificate status
kubectl describe certificate <name> -n <namespace>

# Check the associated CertificateRequest
kubectl describe certificaterequest -n <namespace>

# Check the ACME Order
kubectl describe order -n <namespace>

# Check the Challenge
kubectl describe challenge -n <namespace>

# Check controller logs
kubectl logs -n cert-manager deploy/cert-manager --tail=100

Causas raíz comunes:

  • Fallo HTTP-01: El controlador Ingress no está enrutando correctamente el tráfico /.well-known/acme-challenge/. Verifique que el objeto Ingress del desafío fue creado y que el puerto 80 es accesible desde internet. Los firewalls en el host deben permitir TCP/80 entrante.
  • Fallo DNS-01: El token API del proveedor DNS tiene permisos insuficientes, o la propagación DNS no se ha completado. Los servidores de validación de Let’s Encrypt pueden consultar resolvers diferentes a su DNS local — los retrasos de propagación de 60–120 segundos son normales.
  • Límite de tasa excedido: Let’s Encrypt aplica 5 intentos de validación fallidos por dominio por hora. Tras alcanzar este límite, debe esperar antes de reintentar. Pruebe siempre con el endpoint de staging primero.
  • Webhook no disponible: Si el pod del webhook de cert-manager no está en ejecución, todas las operaciones CRD fallarán con un error de conexión rechazada. Asegúrese de que el servicio webhook tenga un endpoint válido.

Verificación de un Certificado Desplegado

# Check the Secret contents
kubectl get secret example-com-tls-secret -n production -o jsonpath='{.data.tls.crt}' | base64 -d | openssl x509 -noout -text

# Check expiry date specifically
kubectl get secret example-com-tls-secret -n production -o jsonpath='{.data.tls.crt}' | base64 -d | openssl x509 -noout -enddate

Lista de Verificación para Hardening en Producción

Desplegar Cert-Manager en un entorno de producción requiere más que una instalación predeterminada con Helm. Aplique estas medidas de hardening antes de pasar a producción:

  • Límites de recursos: Establezca requests y limits de CPU y memoria en los tres pods de Cert-Manager para prevenir la contención de recursos en nodos compartidos.
  • Auditoría RBAC: Cert-Manager requiere amplios permisos RBAC. Revise los objetos ClusterRole instalados y restrínjalos al mínimo necesario para sus tipos de emisores.
  • Namespace separado: Despliegue siempre Cert-Manager en su propio namespace cert-manager, aislado de las cargas de trabajo de las aplicaciones.
  • Monitoreo: Exponga el endpoint de métricas Prometheus de Cert-Manager (--metrics-listen-address) y configure alertas sobre certmanager_certificate_expiration_timestamp_seconds para detectar fallos de renovación antes de que afecten a los servicios.
  • Respaldo del estado CRD: Incluya los objetos Certificate, ClusterIssuer y Issuer en su estrategia de respaldo del clúster. Perder estos manifiestos tras un evento de recuperación ante desastres significa recrear manualmente todas las configuraciones de certificados.
  • Validación en staging: Nunca emita su primer certificado contra un endpoint ACME de producción. Las violaciones de límites de tasa pueden bloquear su dominio hasta por una semana.

Si ejecuta múltiples clústeres Kubernetes — por ejemplo, separando las cargas de trabajo de staging y producción — los Paneles de Control VPS pueden simplificar la gestión del ciclo de vida del clúster y brindarle una interfaz unificada para aprovisionar la infraestructura subyacente en la que se ejecuta cada clúster.

Para cargas de trabajo que requieren inferencia acelerada por GPU o servicio de ML detrás de endpoints con terminación TLS, los mismos patrones de Cert-Manager se aplican en infraestructura de GPU Hosting, donde la gestión automatizada de certificados es igualmente crítica para proteger los endpoints de API de modelos.

Matriz de Decisión Práctica: Elegir el Emisor Correcto

EscenarioEmisor RecomendadoTipo de DesafíoWildcard
Aplicación web pública, dominio único`letsencrypt-prod`HTTP-01No
Aplicación web pública, múltiples subdominios`letsencrypt-prod`DNS-01
Clúster air-gapped / privado`CA` o `Vault`N/A (interno)
Empresa con requisitos de cumplimiento`Venafi`N/A
mTLS de service mesh (certificados de corta duración)`Vault` o `CA`N/A (interno)
Desarrollo / clúster local`SelfSigned` o `CA`N/A

Conclusiones Clave

  • Instale Cert-Manager usando Helm con installCRDs=true y valide siempre contra el endpoint ACME de staging antes de cambiar a producción.
  • Use ClusterIssuer para clústeres multi-namespace; use Issuer con alcance de namespace solo cuando necesite aislamiento de CA por equipo.
  • DNS-01 es estrictamente necesario para certificados wildcard y para clústeres no directamente accesibles desde internet en el puerto 80.
  • El campo renewBefore no es opcional en producción — establézcalo en al menos un tercio del duration total del certificado.
  • Cuando la emisión se detiene, la ruta de depuración es siempre: CertificateCertificateRequestOrderChallenge → logs del controlador.
  • Las credenciales de la API del proveedor DNS referenciadas por un ClusterIssuer deben residir en el namespace cert-manager, no en los namespaces de las aplicaciones.
  • Monitoree certmanager_certificate_expiration_timestamp_seconds en Prometheus y configure alertas — los fallos silenciosos de renovación son el modo de fallo más peligroso.
  • Respalde sus manifiestos Certificate y ClusterIssuer como parte de su plan de recuperación ante desastres.

Preguntas Frecuentes

¿Cuál es la diferencia entre un Issuer y un ClusterIssuer en Cert-Manager?

Un Issuer tiene alcance de namespace y solo puede emitir certificados dentro del namespace donde está definido. Un ClusterIssuer tiene alcance de clúster y puede ser referenciado por recursos Certificate en cualquier namespace. Para la mayoría de los clústeres en producción, ClusterIssuer es la opción correcta a menos que necesite un estricto aislamiento de CA a nivel de namespace.

¿Por qué mi certificado de Cert-Manager está atascado en el estado “Issuing”?

Inspeccione los objetos Order y Challenge en el mismo namespace usando kubectl describe. Las causas más comunes son: puerto 80 bloqueado por un firewall (HTTP-01), credenciales API de DNS incorrectas o retraso de propagación (DNS-01), límites de tasa de Let’s Encrypt excedidos, o el pod del webhook de cert-manager no está en ejecución. Verifique siempre los logs del controlador con kubectl logs -n cert-manager deploy/cert-manager.

¿Puede Cert-Manager emitir certificados wildcard desde Let’s Encrypt?

Sí, pero solo usando el tipo de desafío DNS-01. HTTP-01 no puede validar dominios wildcard. Debe configurar una integración con un proveedor DNS (Cloudflare, Route53, etc.) en la configuración del solver ClusterIssuer y asegurarse de que las credenciales API tengan permiso para crear registros TXT en el dominio de destino.

¿Cómo gestiona Cert-Manager la renovación automática de certificados?

El controlador de Cert-Manager compara continuamente el vencimiento de cada objeto Certificate con la hora actual. Cuando la validez restante cae por debajo del umbral renewBefore (por defecto: 30 días), el controlador crea un nuevo CertificateRequest, completa el desafío ACME y reemplaza atómicamente el contenido del Secret de destino — todo sin reiniciar los pods que consumen el certificado. Los pods que montan el Secret como volumen verán el certificado actualizado en el próximo ciclo de sincronización del kubelet.

¿Es Cert-Manager adecuado para proteger la comunicación interna entre servicios, no solo HTTPS público?

Sí. Usando el emisor CA o el emisor HashiCorp Vault, Cert-Manager puede emitir certificados de corta duración para mTLS interno entre microservicios. Este es un patrón común en despliegues de service mesh donde cada carga de trabajo necesita un certificado de identidad único. Los campos duration y renewBefore permiten que los certificados tengan una duración tan corta como minutos, con rotación completamente automatizada.

15%

Ahorra 15%<\/span> en todos los servicios de hosting

Pon a prueba tus habilidades y obtén Descuento<\/span> en cualquier plan de hosting

Usa el código:

Skills
Comenzar