Stage 3 · Build
TLS & Certificate Management
TLS in Kubernetes
Ingress TLS, cert-manager, Secrets, and rotating certificates safely.
TLS Secrets
Kubernetes stores TLS certificates in Secrets of type kubernetes.io/tls. These secrets contain two files: tls.crt (the certificate chain) and tls.key (the private key). Ingress resources reference these Secrets to terminate TLS.
# Create TLS Secret from files
kubectl create secret tls my-tls-secret \
--cert=cert.pem \
--key=key.pem
# Or from YAML
apiVersion: v1
kind: Secret
metadata:
name: my-tls-secret
namespace: default
type: kubernetes.io/tls
data:
tls.crt: <base64-encoded-cert>
tls.key: <base64-encoded-key>
# Verify the secret
kubectl get secret my-tls-secret -o yamlThe tls.crt should contain the full certificate chain (your cert + intermediates). The tls.key is the private key. Keep the Secret secure — anyone with access to it can impersonate your service.
Ingress TLS Configuration
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
tls:
- hosts:
- example.com
- www.example.com
secretName: my-tls-secret
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80The tls section maps hostnames to TLS Secrets. When a client connects via HTTPS, the Ingress controller reads the certificate from the Secret and terminates TLS, forwarding plain HTTP to the backend service.
Different Ingress controllers (nginx, traefik, ALB) use different annotations. Check your controller's documentation for TLS-specific settings like protocol versions, cipher suites, and HSTS headers.
cert-manager with Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- example.com
secretName: example-com-tls
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80The cert-manager.io/cluster-issuer annotation tells cert-manager to automatically request a certificate from the specified issuer. cert-manager creates the Secret, performs the ACME challenge, and stores the certificate. No manual certificate management needed.
Certificate Rotation
# Check certificate expiry in a Secret
kubectl get secret my-tls-secret -o jsonpath='{.data.tls\.crt}' | \
base64 -d | openssl x509 -noout -dates
# List all certificates managed by cert-manager
kubectl get certificates -A
# Check cert-manager logs for issues
kubectl -n cert-manager logs -l app=cert-manager --tail=50
# Force re-issue a certificate
kubectl delete secret example-com-tls
# cert-manager will detect the missing secret and re-issuecert-manager handles renewal automatically. It renews certificates when they reach 30 days before expiry. Monitor certificate status with kubectl get certificates and check events for renewal failures.
Debugging TLS in Kubernetes
# 1. Verify the Secret exists and has correct keys
kubectl get secret my-tls-secret -o jsonpath='{.data}' | jq keys
# 2. Check the certificate content
kubectl get secret my-tls-secret -o jsonpath='{.data.tls\.crt}' | \
base64 -d | openssl x509 -text -noout
# 3. Verify the certificate chain
kubectl get secret my-tls-secret -o jsonpath='{.data.tls\.crt}' | \
base64 -d > chain.pem
openssl verify chain.pem
# 4. Check Ingress status
kubectl describe ingress my-ingress
# 5. Test TLS from inside the cluster
kubectl run -it --rm debug --image=busybox --restart=Never -- \
wget -qO- --no-check-certificate https://example.com
# 6. Check cert-manager Certificate status
kubectl get certificate example-com-tls -o yamlThe most common issues are: missing intermediate certificates in tls.crt, wrong key format, certificate hostname mismatch, and cert-manager failing the ACME challenge. Check each step systematically.
Always use kubernetes.io/tls Secrets for certificates, not generic Secrets or ConfigMaps. TLS Secrets have the correct format for Ingress controllers and cert-manager. Using wrong Secret types causes subtle failures.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.