cert-manager is the standard way to get and renew TLS certificates in Kubernetes. It watches your Ingress resources (or explicit Certificate objects), requests certificates from Let’s Encrypt (or other ACME CAs, or your own CA), stores them as Kubernetes Secrets, and renews them automatically before they expire.

Prerequisite: an Ingress controller exposing ports 80/443. See Kubernetes ingress.

Install with Helm

helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager --create-namespace \
  --set crds.enabled=true
kubectl get pods -n cert-manager

See Helm tutorial.

Create ClusterIssuers (staging and production)

Start with Let’s Encrypt staging, which has generous rate limits, while you test:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-staging-key
    solvers:
      - http01:
          ingress:
            ingressClassName: nginx
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-prod-key
    solvers:
      - http01:
          ingress:
            ingressClassName: nginx
kubectl apply -f issuers.yaml
kubectl get clusterissuer

Set ingressClassName to match your controller (for example traefik on k3s).

Get a certificate for an Ingress

Add an annotation and a tls section:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  tls:
    - hosts: [app.example.com]
      secretName: app-example-com-tls
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service: { name: web, port: { number: 80 } }

cert-manager creates a Certificate, solves the challenge, and stores the certificate in the Secret app-example-com-tls, which the Ingress controller then uses.

kubectl get certificate
kubectl describe certificate app-example-com-tls

HTTP-01 vs DNS-01

Challenge How Use when
HTTP-01 Let’s Encrypt fetches a token over port 80 Normal public sites; DNS already points to the cluster
DNS-01 cert-manager creates a TXT record via your DNS provider’s API Wildcards (*.example.com), internal services, port 80 not reachable

DNS-01 example with Cloudflare (API token stored in a Secret):

solvers:
  - dns01:
      cloudflare:
        apiTokenSecretRef:
          name: cloudflare-api-token
          key: api-token

Many DNS providers are supported directly, or via webhooks. Compare: Certbot wildcard certificates.

Renewals

Certificates are renewed automatically, by default 30 days before expiry for 90-day certificates. Nothing to schedule. Monitor them anyway:

kubectl get certificates -A
cmctl status certificate app-example-com-tls     # cert-manager CLI

Troubleshooting

Follow the chain: Certificate → CertificateRequest → Order → Challenge:

kubectl describe certificate app-example-com-tls
kubectl get challenges -A
kubectl describe challenge <name>
kubectl logs -n cert-manager deploy/cert-manager

Common causes:

  • DNS doesn’t point to the cluster yet (HTTP-01 fails).
  • Port 80 is blocked, or redirected in a way that breaks /.well-known/acme-challenge/.
  • Wrong ingressClassName in the issuer.
  • Rate limits from too many production attempts. Test with staging first.

Quick reference

Task Command / field
Install helm install cert-manager jetstack/cert-manager … --set crds.enabled=true
Issuer ClusterIssuer (staging, prod)
Use on Ingress cert-manager.io/cluster-issuer: letsencrypt-prod + tls:
Wildcards DNS-01 solver
Status kubectl get certificate, kubectl get challenges

Related: Let’s Encrypt with Certbot (Nginx) and k3s.

  • Kubernetes
  • SSL
  • DevOps