Skip to main content
โšก Calmops

Cert-Manager Kubernetes TLS Automation: Complete Guide 2026

Introduction

Managing TLS certificates manually in Kubernetes environments is error-prone and unscalable. As organizations deploy hundreds of services requiring secure communication, manual certificate management becomes a significant operational burden and security risk. cert-manager addresses this challenge by automating the entire certificate lifecycleโ€”from issuance through renewal to rotationโ€”integrating seamlessly with Kubernetes-native resources.

In 2026, with zero-trust security architectures becoming standard and regulatory compliance requirements tightening, automated certificate management is no longer optional. This comprehensive guide covers cert-manager architecture, deployment, configuration, and production best practices for Kubernetes environments.

What is cert-manager?

cert-manager is a Kubernetes-native certificate controller that automates certificate issuance and management. It extends Kubernetes with custom resources for certificate management, integrating with various certificate authorities (CAs) including Let’s Encrypt, Venafi, HashiCorp Vault, and internal PKI systems.

Key Capabilities

Automated Issuance: Certificates are automatically requested and issued based on Kubernetes resources.

Automatic Renewal: Certificates are renewed before expiration, eliminating manual processes.

Multiple CA Support: Integration with Let’s Encrypt, Venafi, Vault, self-signed, and custom CAs.

Certificate Rotation: Seamless certificate rotation without service disruption.

DNS Challenge: Domain validation through DNS records for wildcard certificates.

HTTP Challenge: Domain validation through HTTP well-known paths.

Secret Integration: Generated certificates are stored as Kubernetes Secrets.

Architecture

Understanding cert-manager’s architecture is essential for troubleshooting and optimization.

Components

cert-manager consists of several Kubernetes controllers:

Certificate Controller: Watches Certificate resources and manages certificate lifecycle, including requesting new certificates and renewing existing ones.

Issuers/ClusterIssuers: Define certificate authorities and configuration for certificate issuance.

ACME Controller: Handles ACME protocol interactions for Let’s Encrypt and other ACME providers.

Vault PKI Controller: Manages Vault PKI certificate issuance.

Venafi Controller: Integrates with Venafi for enterprise certificate management.

Custom Resources

cert-manager extends Kubernetes with several custom resource definitions:

  • Certificate: Defines desired certificate properties
  • Issuer: Namespaced certificate authority configuration
  • ClusterIssuer: Cluster-wide certificate authority configuration
  • CertificateRequest: Pending certificate requests

Installation

Install cert-manager using Helm:

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

# Install cert-manager
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.16.0 \
  --set installCRDs=true \
  --set prometheus.enabled=true \
  --set 'extraArgs={--dns01-recursive-nameservers-only=true,--dns01-recursive-nameservers=1.1.1.1:53}'

Verify installation:

kubectl get pods -n cert-manager
kubectl get crd | grep cert-manager

Issuer Configuration

Issuers define how cert-manager obtains certificates from certificate authorities.

Let’s Encrypt Issuer (HTTP01)

The most common issuer configuration using HTTP-01 challenge:

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt-http
  namespace: production
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-account-key
    solvers:
    - http01:
        ingress:
          class: traefik

Let’s Encrypt Issuer (DNS01)

For wildcard certificates and environments where HTTP01 isn’t suitable:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-dns
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-dns-key
    solvers:
    - dns01:
        cloudflare:
          email: [email protected]
          apiKeySecretRef:
            name: cloudflare-api-key
            key: api-key

Multiple DNS providers are supported:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: multi-dns-issuer
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-multi-dns-key
    solvers:
    - selector:
        dnsZones:
        - "example.com"
      dns01:
        route53:
          region: us-east-1
          hostedZoneID: ZONE_ID
    - selector:
        dnsZones:
        - "app.example.com"
      dns01:
        cloudflare:
          apiKeySecretRef:
            name: cloudflare-api-key
            key: api-key

Venafi Issuer

For enterprise environments with Venafi:

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: venafi-issuer
  namespace: production
spec:
  venafi:
    url: https://venafi.example.com
    zone: "DevOps\\Kubernetes"
    secretRef:
      name: venafi-credentials
      key: apikey
---
apiVersion: v1
kind: Secret
metadata:
  name: venafi-credentials
  namespace: production
type: Opaque
stringData:
  apikey: VENAFI_API_KEY

HashiCorp Vault PKI

For internal PKI using Vault:

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: vault-issuer
  namespace: production
spec:
  vault:
    server: https://vault.example.com:8200
    path: pki_int
    auth:
      appRole:
        roleId: ROLE_ID
        secretRef:
          name: vault-approle
          key: secretId
---
apiVersion: v1
kind: Secret
metadata:
  name: vault-approle
  namespace: production
type: Opaque
stringData:
  secretId: SECRET_ID

Certificate Management

Certificates define the desired certificate properties and trigger automatic issuance.

Basic Certificate

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: example-com
  namespace: production
spec:
  secretName: example-com-tls
  issuerRef:
    name: letsencrypt-http
    kind: Issuer
    group: cert-manager.io
  dnsNames:
  - example.com
  - www.example.com
  duration: 2160h # 90 days
  renewBefore: 360h # 15 days before expiry
  privateKey:
    algorithm: RSA
    size: 2048
  usages:
  - server auth
  - client auth
  revisionHistoryLimit: 3

Wildcard Certificate

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: wildcard-example-com
  namespace: production
spec:
  secretName: wildcard-example-com-tls
  issuerRef:
    name: letsencrypt-dns
    kind: ClusterIssuer
  dnsNames:
  - "*.example.com"
  - example.com
  duration: 2160h
  renewBefore: 360h
  privateKey:
    algorithm: ECDSA
    size: 256

Multi-Domain Certificate

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: multi-domain
  namespace: production
spec:
  secretName: multi-domain-tls
  issuerRef:
    name: letsencrypt-http
  dnsNames:
  - example.com
  - www.example.com
  - api.example.com
  - app.example.com
  duration: 2160h
  renewBefore: 360h

Ingress Integration

cert-manager integrates with ingress controllers for automatic TLS.

Basic Ingress TLS

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    cert-manager.io/issuer: letsencrypt-http
    kubernetes.io/ingress.class: nginx
spec:
  tls:
  - hosts:
    - myapp.example.com
    secretName: myapp-tls
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp-service
            port:
              number: 80

Ingress with ClusterIssuer

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-dns
    kubernetes.io/ingress.class: traefik
spec:
  tls:
  - hosts:
    - "*.example.com"
    - example.com
    secretName: wildcard-tls
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp-service
            port:
              number: 80

HTTP01 Challenge Configuration

Configure how HTTP01 challenges are solved:

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt-http-custom
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-key
    solvers:
    - http01:
        ingress:
          class: nginx
          podTemplate:
            spec:
              nodeSelector:
                "kubernetes.io/os": linux
              tolerations:
              - key: "node-role.kubernetes.io/control-plane"
                operator: "Exists"
                effect: "NoSchedule"

Advanced Configuration

Certificate Specifications

Configure certificate properties for specific requirements:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: advanced-cert
  namespace: production
spec:
  secretName: advanced-cert-tls
  issuerRef:
    name: venafi-issuer
  dnsNames:
  - app.example.com
  duration: 17520h # 2 years
  renewBefore: 720h # 30 days
  organization:
  - Example Inc
  organizationalUnit:
  - DevOps
  - Engineering
  isCA: false
  privateKey:
    algorithm: ECDSA
    size: 384
    encoding: PKCS8
  usages:
  - digital signature
  - key encipherment
  - server auth
  keyEncoding: PKCS8
  revisionHistoryLimit: 5
  additionalOutputFormats:
  - type: DER
    secretKey: tls.der
  - type: CombinedPEM
    secretKey: tls-ca-bundle.pem

External Account Binding

For CA operators requiring external account binding:

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: zerossl-issuer
spec:
  acme:
    server: https://acme.zerossl.com/v1/DZ26
    email: [email protected]
    externalAccountBinding:
      keyID: ZEROSSL_ACCOUNT_ID
      keySecretRef:
        name: zerossl-eab
        key: secret-key
      keyAlgorithm: HS256
    privateKeySecretRef:
      name: zerossl-key
    solvers:
    - http01:
        ingress:
          class: nginx

Monitoring and Troubleshooting

Certificate Status

Check certificate status:

# Get certificate status
kubectl get certificate -n production

# Describe certificate for details
kubectl describe certificate example-com -n production

# Check certificate secret
kubectl get secret example-com-tls -n production -o yaml

# View certificate details
kubectl get secret example-com-tls -n production -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -text

Troubleshooting Common Issues

Challenge Failure:

# Check challenge status
kubectl get challenges
kubectl describe challenge <challenge-name>

# Common issues:
# - DNS not propagated
# - Firewall blocking port 80
# - Ingress class misconfigured
# - Token not accessible

Rate Limiting:

# Check for rate limiting errors
kubectl get orders
kubectl describe order <order-name>

Certificate Not Issuing:

# Check cert-manager logs
kubectl logs -n cert-manager -l app.kubernetes.io/name=cert-manager

# Verify issuer is ready
kubectl get issuer letsencrypt-http -n production -o yaml

Prometheus Metrics

Enable metrics collection:

# values.yaml
prometheus:
  enabled: true
  servicemonitor:
    enabled: true

Key metrics:

  • certmanager_certificate_expiration_timestamp_seconds: Certificate expiration time
  • certmanager_certificate_ready_status: Certificate ready status
  • certmanager_acme_client_request_count: ACME client requests
  • certmanager_certificates_key_usage: Key usage bits

Security Best Practices

Secure Secret Storage

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: secure-cert
spec:
  secretName: secure-cert-tls
  issuerRef:
    name: vault-issuer
  dnsNames:
  - secure.example.com
  # Use separate secret for CA certificate
  caSecretName: custom-ca-secret

RBAC Configuration

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: cert-manager-role
  namespace: production
rules:
- apiGroups: ["cert-manager.io"]
  resources: ["certificates", "issuers"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "create", "delete"]

Network Policies

Restrict cert-manager network access:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: cert-manager-policy
  namespace: cert-manager
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: cert-manager
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector: {}
    ports:
    - protocol: TCP
      port: 443
  - to:
    - namespaceSelector: {}
    ports:
    - protocol: UDP
      port: 53

High Availability

Deploy cert-manager for high availability.

Multiple Replicas

# values.yaml
replicaCount: 3

podAntiAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
  - labelSelector:
      matchLabels:
        app.kubernetes.io/name: cert-manager
    topologyKey: kubernetes.io/hostname

Pod Disruption Budget

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: cert-manager-pdb
  namespace: cert-manager
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app.kubernetes.io/name: cert-manager

Production Checklist

Before deploying to production:

  • Choose appropriate issuer type (HTTP01 vs DNS01)
  • Configure DNS challenge for wildcards
  • Set up monitoring and alerting
  • Configure appropriate renewal windows
  • Test certificate issuance in staging
  • Plan for CA rate limits
  • Document incident response procedures
  • Configure backup for private keys
  • Set up metrics dashboards
  • Configure appropriate resource limits

Conclusion

cert-manager has become the essential tool for TLS automation in Kubernetes environments. By automating the entire certificate lifecycle, it eliminates manual certificate management overhead while improving security through automatic rotation and renewal. Whether using Let’s Encrypt for public-facing services or integrating with enterprise CAs for internal PKI, cert-manager provides the flexibility and reliability required for modern cloud-native deployments.

As organizations continue their journey toward zero-trust architectures and automated security, cert-manager’s role in providing cryptographic protection will only grow. Understanding its architecture and capabilities enables platform teams to build secure, compliant, and operationally efficient Kubernetes environments.

Resources

Comments