Traefik is an open-source Kubernetes Ingress controller that pairs with cert-manager to automatically provision and renew TLS certificates for services exposed from your cluster. This guide installs Traefik and cert-manager, then deploys a sample app behind an Ingress with a Let's Encrypt certificate.
Prerequisites: a Kubernetes cluster,
kubectland Helm configured against it, a domain (this guide usesexample.com).
Install Traefik
$ kubectl create namespace traefik-namespace
$ helm repo add traefik https://helm.traefik.io/traefik
$ helm repo update
$ helm install --namespace=traefik-namespace traefik traefik/traefik
$ kubectl get services -n traefik-namespace
The traefik Service's EXTERNAL-IP may show <pending> briefly while your cloud provider provisions the LoadBalancer — wait and re-check.
Point a domain A record at that external IP with your DNS provider.
Install cert-manager
$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.17.2/cert-manager.yaml
$ kubectl get pods --namespace cert-manager
Check the cert-manager releases page for the current version.
Create a ClusterIssuer
$ nano cluster-issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: hello@example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:
- http01:
ingress:
class: traefik
Use a real email address — Let's Encrypt rejects example.com addresses.
$ kubectl apply -f cluster-issuer.yaml
$ kubectl get clusterissuer
READY: True confirms it's ready to issue certs.
Deploy a Sample App
$ kubectl create namespace example-app-namespace
$ nano example-app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: example-app-namespace
name: example-app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: example-app
template:
metadata:
labels:
app: example-app
spec:
containers:
- name: web-app
image: nginx
ports:
- containerPort: 80
$ kubectl apply -f example-app-deployment.yaml
$ kubectl get pods -n example-app-namespace
Create an Ingress
1. Service:
$ nano example-app-service.yaml
apiVersion: v1
kind: Service
metadata:
namespace: example-app-namespace
name: example-app-service
spec:
selector:
app: example-app
ports:
- protocol: TCP
port: 80
targetPort: 80
$ kubectl apply -f example-app-service.yaml
$ kubectl get services -n example-app-namespace
2. Ingress — replace example.com:
$ nano example-app-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app-ingress
namespace: example-app-namespace
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: example-app-service
port:
number: 80
tls:
- secretName: web-app-cert
hosts:
- example.com
The Traefik-specific annotations route HTTPS traffic through the websecure entrypoint; the cert-manager.io/cluster-issuer annotation ties the Ingress to the ClusterIssuer. secretName doesn't need to exist beforehand — cert-manager creates it.
$ kubectl apply -f example-app-ingress.yaml
$ kubectl get ingress -n example-app-namespace
ADDRESS populates a few seconds later with Traefik's external IP.
3. Confirm the certificate:
$ kubectl get certificates -n example-app-namespace
READY: True means it's issued. Check auto-renewal is scheduled:
$ kubectl describe -n example-app-namespace certificate web-app-cert
Look for a Renewal Time a month or so out.
4. Visit https://example.com — you should see the default Nginx welcome page over a valid cert.
Troubleshooting
Certificate stuck False — confirm DNS points at Traefik's LoadBalancer IP, then check logs:
$ kubectl logs deployment/cert-manager -n cert-manager --tail=15 -f
Traefik routing issues — check its logs and resource status:
$ kubectl logs -n <namespace> <traefik-pod>
$ kubectl get pods -n traefik-namespace
Ingress not routing — verify the manifest has the right Traefik/cert-manager annotations:
$ kubectl get ingress
Next Steps
Traefik is routing traffic with automatic Let's Encrypt certificates via cert-manager. From here:
- Add more Ingress resources for additional apps, reusing the same ClusterIssuer
- Explore Traefik middlewares for rate limiting, auth, or redirects
- Switch to DNS-01 challenges in the ClusterIssuer if you need wildcard certificates
For the full guide, visit the original article on Vultr Docs.
Top comments (1)
Was looking for Traefik setup this way. great article