Skip to main content

Automating TLS Certificate Management in Kubernetes with cert-manager

When exposing services on Kubernetes, TLS certificate management is an unavoidable challenge. Manual certificate issuance and renewal increase operational burden and create outage risks from expiration. cert-manager, a CNCF Graduated project, fully automates the TLS certificate lifecycle and solves this problem at its root. On K3s-based Kubernetes platforms like Kubo, cert-manager enables zero-touch certificate management.

cert-manager Fundamentals and Architecture

cert-manager is an add-on that automates TLS certificate issuance and renewal on Kubernetes and OpenShift clusters. Actively developed on GitHub, it has become the de facto standard for certificate management in cloud-native environments.

Core Components

cert-manager consists of:

  • Controller: Monitors Certificate resource state and executes issuance and renewal
  • Webhook: Handles CRD validation and Admission Control
  • CA Injector: Automatically injects CA bundles into webhooks and custom resources
  • ACME Solver: Manages challenge processing with ACME providers like Let's Encrypt

Supported Issuers

According to the cert-manager documentation, the following certificate authorities are supported:

  • Let's Encrypt (ACME protocol): Free, automated TLS certificates
  • HashiCorp Vault: Enterprise PKI integration
  • CyberArk Certificate Manager: Enterprise certificate management
  • Private PKI: Certificates from your own CA
  • Self-signed: For test environments

Captain.AI monitors the security posture of your entire Kubernetes environment with AI, proactively detecting certificate expiration risks.

Installation and Initial Configuration

Installing with Helm

bash
# Add the cert-manager Helm repository
helm repo add jetstack https://charts.jetstack.io
helm repo update

# Install with CRDs included
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.18.1 \
  --set crds.enabled=true

Verifying Installation

bash
# Check pod status
kubectl get pods -n cert-manager

# Expected output:
# cert-manager-5c6866597-zw7kh          1/1     Running   0
# cert-manager-cainjector-577f6d9fd7-b   1/1     Running   0
# cert-manager-webhook-56f8b4f8d-hsqvg   1/1     Running   0

Creating a ClusterIssuer

Following the practical guide from Funky Si's Blog, configure a ClusterIssuer for Let's Encrypt:

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

It is recommended to also prepare a staging issuer for testing:

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

On Kubo, you can also integrate with the Traefik Ingress Controller that ships with K3s.

How ACME Challenges Work

Let's Encrypt uses the ACME (Automatic Certificate Management Environment) protocol to verify domain ownership. As explained by KodeKloud, cert-manager supports two primary challenge types.

HTTP-01 Challenge

yaml
solvers:
- http01:
    ingress:
      class: nginx
  • let's encrypt accesses the -.well-known-acme-challenge- endpoint to validate
  • Pros: Simple configuration, no additional DNS permissions needed
  • Cons: Port 80 must be externally accessible, wildcard certificates not supported

DNS-01 Challenge

yaml
solvers:
- dns01:
    cloudflare:
      email: admin@example.com
      apiTokenSecretRef:
        name: cloudflare-api-token
        key: api-token
  • Validation via DNS TXT records
  • Pros: Supports wildcard certificates, port 80 not required
  • Cons: Requires DNS provider API credentials

As The Dougie Chronicles details, the Cloudflare DNS-01 challenge is the most common choice when wildcard certificates are needed.

Supported DNS providers include:

Ingress Integration and Automatic Certificate Issuance

One of cert-manager's most powerful features is its automatic integration with Ingress resources.

Annotation-Based Auto-Issuance

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

Simply adding the cert-manager.io/cluster-issuer annotation causes cert-manager to automatically create a Certificate resource, obtain a certificate from Let's Encrypt, and store it in a Kubernetes Secret.

Gateway API Integration

cert-manager also works with the Kubernetes Gateway API:

yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: my-app-route
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  parentRefs:
  - name: my-gateway
  hostnames:
  - "app.example.com"
  rules:
  - backendRefs:
    - name: my-app
      port: 80

Automatic Renewal

As explained in this detailed Medium article, cert-manager continuously monitors certificate expiration and automatically triggers renewal before the renewBefore period. Let's Encrypt certificates are valid for 90 days, and by default renewal starts 30 days before expiration.

yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: app-tls
spec:
  secretName: app-tls-secret
  duration: 2160h    # 90 days
  renewBefore: 720h  # Renew 30 days before expiry
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
  - app.example.com
  - www.app.example.com

By integrating with Captain.AI, you can build workflows where AI detects certificate renewal failures and automatically suggests remediation.

Troubleshooting and Best Practices

Common Issues and Solutions

Drawing from the oneuptime guide and F5 best practices:

bash
# Check Certificate status
kubectl describe certificate app-tls -n default

# Check CertificateRequest
kubectl get certificaterequest -n default

# Check Order (for ACME)
kubectl get order -n default

# Check Challenge
kubectl get challenge -n default

# View cert-manager logs
kubectl logs -n cert-manager -l app=cert-manager

Common Errors and Fixes

ErrorCauseFix
Waiting for HTTP-01 challengePort 80 blockedCheck firewall settings
DNS record not yet propagatedDNS propagation delaySet --dns01-recursive-nameservers
rate limitedLet's Encrypt rate limitsTest with staging environment first
account is not registeredACME registration failureVerify the email field

Security Best Practices

  • Test with staging Issuer before switching to production
  • Restrict access to Certificate resources with RBAC
  • As Apurv's tech notes recommend, manage API tokens securely in Kubernetes Secrets
  • Set up monitoring alerts for certificates (Prometheus metric certmanager_certificate_expiration_timestamp_seconds)

Conclusion

cert-manager dramatically reduces the effort of TLS certificate management in Kubernetes. The key takeaways are:

  1. cert-manager fully automates certificate issuance, renewal, and management
  2. Let's Encrypt integration provides free TLS certificates automatically
  3. HTTP-01 / DNS-01 challenges adapt to various environment requirements
  4. Ingress annotations enable adoption with minimal changes to existing workloads
  5. Automatic renewal eliminates the risk of certificate expiration

Kubo is built on K3s with strong affinity for the CNCF ecosystem, and cert-manager deployment enables secure service exposure with ease. If you are looking to strengthen Kubernetes security, explore Kubo.

For AI-powered Kubernetes operations automation, see Captain.AI for details. For consultations, reach out through our contact page.

← Back to all posts