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
# 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
# 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:
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:
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
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
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:
- Cloudflare
- AWS Route 53
- Google Cloud DNS
- Azure DNS
- And many more
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
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:
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.
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:
# 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
| Error | Cause | Fix |
|---|---|---|
Waiting for HTTP-01 challenge | Port 80 blocked | Check firewall settings |
DNS record not yet propagated | DNS propagation delay | Set --dns01-recursive-nameservers |
rate limited | Let's Encrypt rate limits | Test with staging environment first |
account is not registered | ACME registration failure | Verify 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:
- cert-manager fully automates certificate issuance, renewal, and management
- Let's Encrypt integration provides free TLS certificates automatically
- HTTP-01 / DNS-01 challenges adapt to various environment requirements
- Ingress annotations enable adoption with minimal changes to existing workloads
- 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.