Home › CKS › Topics › Practice tasks › Ingress TLS & HTTPS
CKS · Cluster Hardening

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.

Check live lab access → All CKS tasks

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 →

Read this week's free task →

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:

> 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

Example checkEvidence
Secret usableType kubernetes.io/tls, same namespace as the Ingress
TLS wiredspec.tls[].secretName set, hosts equal rule hosts
Certificate servedcurl -kv shows your subject, not the controller default
Redirect behaviourHTTP 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.

Exam
CKS
Domain
Cluster Hardening
Grading
Programmatic · partial credit

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.

Related CKS tasks