Serve an App over HTTPS with Ingress TLS
Create an Ingress resource named web in the prod namespace and configure it as follows: Route traffic for host web.k8s.local and all paths to the existing Service web.
Live lab access
This task description is public. Live practice requires full access unless this is the selected free weekly task. AI Lab Coach is available in single-task labs, including the free weekly task. See this week's free task.
Create an account to continue →
On a phone? Read the task and create your account here, then sign in on a desktop or laptop for the terminal lab. Nothing starts until you choose Start.
The task
Context
You must expose a web application using HTTPS routes. A default Cilium IngressClass is configured in the cluster.
Task
Create an Ingress resource named web in the prod namespace and configure it as follows:
- Route traffic for host
web.k8s.localand all paths to the existing Serviceweb. - Enable TLS termination using the existing Secret
web-cert. - Redirect HTTP requests to HTTPS.
> You can test your Ingress configuration with the following command: >
> curl -L http://web.k8s.local
>
Original Prepium guide · Written for Kubernetes v1.35 and checked against the official documentation on 6 October 2026. Use a disposable practice cluster. You need an Ingress controller and an IngressClass; behaviour that the Ingress API leaves open is noted per controller below.
Terminate TLS on an Ingress and prove it from the command line
An Ingress can terminate HTTPS for you: the controller loads a certificate and key from a Secret, serves them on port 443 for the hosts you list, and forwards plain HTTP to your Service. The Kubernetes API defines what to secure (the tls section); details such as redirecting port 80 to 443 are decided by the controller, which is where many attempts go wrong.
client ──HTTPS :443 (SNI shop.prepium.test)──→ Ingress controller ──HTTP──→ Service storefront ──→ Pods
certificate + key from Secret type kubernetes.io/tls
1. Create a TLS Secret of the right type
openssl req -x509 -noenc -newkey rsa:2048 -days 30 \
-keyout shop.key -out shop.crt \
-subj "/CN=shop.prepium.test" -addext "subjectAltName=DNS:shop.prepium.test"
kubectl create namespace prepium-tutorial
kubectl -n prepium-tutorial create secret tls storefront-tls --cert=shop.crt --key=shop.key
kubectl -n prepium-tutorial get secret storefront-tls -o jsonpath='{.type}'
The type must be kubernetes.io/tls, with data keys tls.crt and tls.key; the API server checks that both keys exist but not that the certificate is valid. secretName is a bare name with no namespace field, so keep the Secret in the Ingress's own namespace.
2. Add the tls section
kubectl -n prepium-tutorial create deployment storefront --image=nginx:1.27-alpine --port=80
kubectl -n prepium-tutorial expose deployment storefront --port=80
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: storefront
namespace: prepium-tutorial
spec:
tls:
- hosts: ["shop.prepium.test"]
secretName: storefront-tls
rules:
- host: shop.prepium.test
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: storefront
port:
number: 80
Each tls entry pairs a list of hosts with one Secret. The hosts must match the host values in rules exactly, because TLS cannot apply to a host-less default rule. Without ingressClassName, the cluster's default IngressClass (annotation ingressclass.kubernetes.io/is-default-class: "true") is used.
3. Know who decides about redirects
The Ingress spec has no redirect field. ingress-nginx, for example, documents a 308 redirect to HTTPS by default once TLS is enabled for an Ingress, switchable with its ssl-redirect setting. Cilium's Ingress controller documents its own per-Ingress annotation and a cluster-wide setting for forcing HTTPS. Always read the docs for the controller behind your IngressClass instead of copying another controller's annotation, which simply has no effect.
4. Verify without touching DNS
IP=$(kubectl -n prepium-tutorial get ingress storefront -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -kv --resolve shop.prepium.test:443:$IP https://shop.prepium.test/
curl -sv -o /dev/null --resolve shop.prepium.test:80:$IP http://shop.prepium.test/
--resolve pins the host name to the controller's address for that port, so SNI and the Host header are correct. -k skips verification (your certificate is self-signed) and -v shows the handshake, where the server certificate's subject should name shop.prepium.test. The plain HTTP call shows whether a 3xx with a Location: https://... header comes back; add -L to follow it.
Common mistakes
- Secret in another namespace or of type
Opaquewith other key names: the controller cannot use it, and many controllers then present a built-in default certificate, visible incurl -v. - A
tls.hostsentry that does not match the rule's host: HTTPS serves the wrong certificate. - Testing by IP without
--resolve: no SNI is sent, so the result says nothing about your host. - Using an annotation from a different controller for the redirect.
| Example check | Evidence |
|---|---|
| Secret usable | Type kubernetes.io/tls, same namespace as the Ingress |
| TLS wired | spec.tls[].secretName set, hosts equal rule hosts |
| Certificate served | curl -kv shows your subject, not the controller default |
| Redirect behaviour | HTTP request returns 3xx with an https:// Location |
Cleanup: kubectl delete namespace prepium-tutorial and remove the local key files. References: Ingress TLS, TLS Secrets, ingress-nginx HTTPS redirect, Cilium Ingress. Next, try TLS Secrets or Ingress routing.
What this tests
Restrict RBAC and service accounts, tighten API server flags, and keep the cluster patched. On the CKS exam, Cluster Hardening tasks are graded purely on what you build in the cluster - not multiple choice - so the only way to get faster is to do them on a real cluster against a clock.
Practice it for real
The public description lets you study the task before signing up. Full access includes this live lab; the selected Task of the Week is free with an account. You solve the task in a real terminal, hit validate, and a programmatic checker scores exactly what you got right and wrong (with partial credit). You can open the solution while practising, then retry and use the failed checks to improve your score.