How to Set Up cert-manager in Kubernetes
In this tutorial, you'll learn about How to Set Up cert. We cover key concepts, practical examples, and best practices.
The Problem
Your cert-manager Certificate resource stays in Ready: False status, the Issuer is not found, or the TLS secret is never created. Ingress resources that reference the secret show TLS handshake error because the certificate does not exist.
Quick Fix
Fix 1: Certificate Not Ready
kubectl get certificate
# NAME READY SECRET AGE
# example-tls False example-tls 5m
kubectl describe certificate example-tls
# Status:
# Conditions:
# Reason: IssuerNotReady
# Message: Issuer letsencrypt-prod is not ready
RIGHT β check the Issuer:
kubectl describe issuer letsencrypt-prod
# Status:
# Conditions:
# Reason: ACMEAccountRegistrationFailed
# Message: Failed to register ACME account: 429 Too Many Requests
Wait and retry, or check the issuer configuration.
Fix 2: ACME Issuer Configuration
WRONG β ClusterIssuer without proper ACME settings:
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-account-key
# missing solvers
RIGHT β complete ClusterIssuer with solvers:
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-account-key
solvers:
- http01:
ingress:
class: nginx
Fix 3: Certificate DNS Names Mismatch
WRONG β certificate name does not match the Ingress host:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-tls
spec:
secretName: example-tls
dnsNames:
- app.example.com # certificate is for app.example.com
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
tls:
- hosts:
- www.example.com # ingress uses www.example.com
secretName: example-tls
RIGHT β match DNS names:
spec:
dnsNames:
- www.example.com # must match the ingress host
- app.example.com # additional names as needed
Fix 4: Ingress Not Annotated for cert-manager
WRONG β creating a Certificate manually without Ingress annotation:
# Ingress missing cert-manager annotation:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
# no annotation β cert-manager does not auto-create certs
RIGHT β add the annotation for auto-certificate:
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- example.com
secretName: example-tls
Fix 5: DNS-01 Challenge Fails
kubectl describe certificate example-tls
# Reason: ACMEChallenge
# Message: Failed to complete ACME dns-01 challenge:
# DNS problem: NXDOMAIN looking up TXT for _acme-challenge.example.com
RIGHT β verify DNS delegation for the _acme-challenge subdomain:
spec:
solvers:
- dns01:
cloudflare:
email: admin@example.com
apiTokenSecretRef:
name: cloudflare-token
key: api-token
Fix 6: Secret Not Created
kubectl get secret example-tls
# Error: secret "example-tls" not found
RIGHT β describe the certificate and check the error:
kubectl describe certificate example-tls
# If the issuer is ready and DNS is configured, the secret is created after
# the certificate is issued. Check cert-manager logs:
kubectl logs -n cert-manager deployment/cert-manager
Use DodaTech's Certificate Dashboard to monitor cert-manager issuers, certificate expiry, and auto-remediate failed ACME challenges.
Prevention
- Verify DNS records before creating certificates.
- Use ClusterIssuer for cluster-wide certificate issuance.
- Annotate Ingress resources for automatic certificate management.
- Monitor certificate expiry and set renewal notifications.
- Keep cert-manager updated to the latest version.
Common Mistakes with cert manager
- Using
headandtailinstead of pattern matching, causing runtime errors on empty lists - Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks
- Using
returnto exit a function early instead of wrapping a pure value in the monad
These mistakes appear frequently in real-world K8S code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro