In this tutorial, you’ll learn how to install Cert-Manager on Kubernetes and obtain an SSL certificate from Let’s Encrypt to secure a Traefik Ingress. We’ll walk through:
Installing Cert-Manager with Helm
Reviewing the sample “whoami” app and existing Ingress
Creating a Let’s Encrypt staging Issuer
Applying the Issuer and validating resources
Updating the Ingress to request TLS
Verifying the ACME challenge and certificate issuance
Creating a Let’s Encrypt production Issuer and switching over
1. Install Cert-Manager
First, ensure you have Helm installed and a Kubernetes context pointing at your control plane.
# Add the Jetstack Helm repository
helm repo add jetstack https://charts.jetstack.io
helm repo update
# Create a namespace for Cert-Manager
kubectl create namespace cert-manager
# Install Cert-Manager and register its CRDs
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--set installCRDs= true
Wait until all pods in the cert-manager namespace are in the Running state:
kubectl get pods -n cert-manager
2. Review the Test App and Ingress
We have a simple “whoami” deployment in the default namespace, fronted by Traefik:
kubectl get all -n default
Example output:
pod/whoami-8c9864b56-6pm4p 1/1 Running
service/whoami ClusterIP 10.98.232.119 80/TCP
deployment.apps/whoami 1/1 Running
Check the existing Ingress:
kubectl get ingress whoami-ingress -n default
NAME CLASS HOSTS ADDRESS PORTS AGE
whoami-ingress traefik * <none> 80 5m
Describe it:
kubectl describe ingress whoami-ingress -n default
3. Create a Let’s Encrypt Staging Issuer
To prevent hitting rate limits, start with the staging environment. Save this as staging-issuer.yaml:
apiVersion : cert-manager.io/v1
kind : Issuer
metadata :
name : letsencrypt-staging
spec :
acme :
server : https://acme-staging-v02.api.letsencrypt.org/directory
email : [email protected]
privateKeySecretRef :
name : letsencrypt-staging
solvers :
- http01 :
ingress :
name : whoami-ingress
Apply and inspect:
kubectl apply -f staging-issuer.yaml
kubectl describe issuer letsencrypt-staging -n default
kubectl get secrets -n default
You should see letsencrypt-staging in the secret list.
4. Update the Ingress for TLS
Modify whoami-ingress.yaml to include the Cert-Manager annotation and a TLS block:
apiVersion : networking.k8s.io/v1
kind : Ingress
metadata :
name : whoami-ingress
namespace : default
annotations :
cert-manager.io/issuer : letsencrypt-staging
spec :
ingressClassName : traefik
tls :
- hosts :
- test-example.com
secretName : web-ssl
rules :
- http :
paths :
- path : /
pathType : Prefix
backend :
service :
name : whoami
port :
name : web
Apply the updated Ingress:
kubectl apply -f whoami-ingress.yaml
Ensure DNS for test-example.com points to your Traefik load balancer before requesting a certificate.
5. Verify the ACME Challenge and Certificate Issuance
Describe the Ingress again to confirm ACME resources:
kubectl describe ingress whoami-ingress -n default
Look for:
A cm-acme-http-solver-… backend under the ACME challenge path
An event CreateCertificate indicating web-ssl was requested
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CreateCertificate 10s cert-manager-ingress-shim Successfully created Certificate "web-ssl"
6. Create a Let’s Encrypt Production Issuer
Once staging is validated, switch to the production environment. Create prod-issuer.yaml:
apiVersion : cert-manager.io/v1
kind : Issuer
metadata :
name : letsencrypt-production
spec :
acme :
server : https://acme-v02.api.letsencrypt.org/directory
email : [email protected]
privateKeySecretRef :
name : letsencrypt-production
solvers :
- http01 :
ingress :
name : whoami-ingress
Apply and verify:
kubectl apply -f prod-issuer.yaml
kubectl describe issuer letsencrypt-production -n default
7. Switch Ingress to Production Issuer
Update the Ingress annotation to use the production Issuer:
kubectl annotate ingress whoami-ingress \
cert-manager.io/issuer=letsencrypt-production \
--overwrite -n default
Describe the Ingress to confirm renewal:
kubectl describe ingress whoami-ingress -n default
In the events, you should see:
Normal RenewCertificate 12s cert-manager-ingress-shim Successfully renewed Certificate "web-ssl"
Your Traefik Ingress is now secured with a Let’s Encrypt production certificate.
Issuer Configuration Summary
Issuer Name Environment ACME Server URL Secret Name letsencrypt-staging Staging https://acme-staging-v02.api.letsencrypt.org/directory letsencrypt-staging letsencrypt-production Production https://acme-v02.api.letsencrypt.org/directory letsencrypt-production
References