CKA — TLS Termination
CKA Exam Domain
Services & Networking — 20%
TLS termination at the Ingress layer is a common CKA exam task. You’ll be asked to create a TLS Secret, configure an Ingress to use it, and verify HTTPS is working. Know the commands and YAML by heart.
Creating TLS Secrets
Before configuring TLS on an Ingress, you need a Kubernetes Secret of type kubernetes.io/tls containing the certificate and private key.
Generate a Self-Signed Certificate
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt -subj "/CN=app.example.com"
This creates:
tls.key— the private keytls.crt— the self-signed certificate valid for 365 days
Create the Secret
kubectl create secret tls app-tls --cert=tls.crt --key=tls.key
Verify:
kubectl get secret app-tls
kubectl describe secret app-tls
The Secret will have two data keys: tls.crt and tls.key.
Secret YAML (for reference)
apiVersion: v1
kind: Secret
metadata:
name: app-tls
type: kubernetes.io/tls
data:
tls.crt: <base64-encoded-cert>
tls.key: <base64-encoded-key>
Exam tip: Use the kubectl create secret tls command — it’s faster and less error-prone than writing YAML with base64-encoded values.
Configuring TLS in Ingress
Add the tls section to your Ingress spec to enable HTTPS:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com # Must match a host in rules
secretName: app-tls # The TLS Secret we created
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-svc
port:
number: 80
Key points:
- The
tls[].hostsmust match thehostin therulessection secretNamereferences the TLS Secret- The certificate’s CN (Common Name) should match the hostname
- You can have multiple
tlsentries for different hosts
Multiple Hosts with TLS
spec:
tls:
- hosts:
- app.example.com
secretName: app-tls
- hosts:
- api.example.com
secretName: api-tls
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-svc
port:
number: 80
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-svc
port:
number: 8080
TLS Flow
Understanding the traffic flow is important for both the exam and troubleshooting:
Client (HTTPS) → Ingress Controller → TLS Terminates Here → Service (HTTP) → Pod
- Client sends an HTTPS request to the Ingress Controller’s external IP
- Ingress Controller receives the encrypted traffic, uses the certificate from the TLS Secret to decrypt it
- TLS terminates at the controller — from here, traffic is plain HTTP
- Controller forwards the unencrypted request to the backend Service
- Service routes to the Pod
This means your backend applications don’t need to handle TLS themselves — the Ingress Controller takes care of it.
Certificate Management
For the CKA exam, you’ll use self-signed certificates or certificates provided in the question. In production, you’d typically use cert-manager for automated certificate management:
- Automatically provisions certificates from Let’s Encrypt or other CAs
- Handles certificate renewal before expiry
- Integrates with Ingress via annotations
# Production example (not needed for CKA, but good to know)
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
For the exam: Stick to openssl + kubectl create secret tls. That’s all you need.
Redirect HTTP to HTTPS
By default, the NGINX Ingress Controller redirects HTTP to HTTPS when TLS is configured. You can control this behavior with annotations:
# Force HTTPS redirect (default when TLS is configured)
nginx.ingress.kubernetes.io/ssl-redirect: "true"
# Disable HTTPS redirect (serve both HTTP and HTTPS)
nginx.ingress.kubernetes.io/ssl-redirect: "false"
# Force SSL using a 308 redirect
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
Exam tip: If the question says “configure HTTPS” but doesn’t mention redirects, adding ssl-redirect: "true" is a safe default.
Verifying TLS
After configuring TLS, verify it’s working:
# Test HTTPS connection (-v for verbose, -k to skip cert verification for self-signed)
curl -vk https://app.example.com
# Check Ingress TLS configuration
kubectl describe ingress app-ingress | grep -i tls
# Verify the Secret exists and has the right type
kubectl get secret app-tls -o yaml
# Check certificate details
openssl x509 -in tls.crt -text -noout | head -20
# Test from inside the cluster
kubectl run curl-test --image=curlimages/curl --rm -it -- \
curl -vk https://app.example.com
Expected output from kubectl describe ingress:
TLS:
app-tls terminates app.example.com
If you see TLS: <none>, the TLS configuration isn’t applied correctly — check the Secret name and host matching.
Practice Questions
Q1. Create a TLS Secret named web-tls from certificate file web.crt and key file web.key.
Show Answer
kubectl create secret tls web-tls --cert=web.crt --key=web.key
Verify: kubectl get secret web-tls — it should show type kubernetes.io/tls.
Q2. Write an Ingress resource that terminates TLS for shop.example.com using Secret shop-tls, routing all traffic to shop-svc on port 80.
Show Answer
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: shop-ingress
spec:
ingressClassName: nginx
tls:
- hosts:
- shop.example.com
secretName: shop-tls
rules:
- host: shop.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: shop-svc
port:
number: 80
Q3. Where does TLS terminate in a standard Ingress setup?
Show Answer
TLS terminates at the Ingress Controller. The controller decrypts the HTTPS traffic using the certificate from the TLS Secret, then forwards plain HTTP to the backend Service. This means backend Pods receive unencrypted traffic.
Q4. How do you generate a self-signed certificate for api.example.com and create the corresponding Secret?
Show Answer
# Generate the certificate and key
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt -subj "/CN=api.example.com"
# Create the Kubernetes Secret
kubectl create secret tls api-tls --cert=tls.crt --key=tls.key
Q5. An Ingress has TLS configured but kubectl describe ingress shows TLS: <none>. What could be wrong?
Show Answer
Common causes:
- Secret doesn’t exist — check
kubectl get secret <secret-name>in the same namespace - Secret name mismatch — the
secretNamein the Ingress doesn’t match the actual Secret - Wrong namespace — the Secret must be in the same namespace as the Ingress
- Secret type is wrong — must be
kubernetes.io/tls, notOpaque - Host mismatch — the
hostsundertlsdoesn’t match anyhostinrules