Ingress with TLS
Terminate HTTPS and force redirect at the edge.
An Ingress is the cluster’s HTTP front door: a controller (ingress-nginx, Traefik, and so on) watches Ingress objects and programs one reverse proxy that routes by host and path to backend Services. Terminating TLS there means a single place holds the certificate and speaks HTTPS to the world, then forwards to Services inside the cluster — instead of every backend pod owning a cert. For a security specialist the Ingress is where public exposure meets your internal Services, so it is where TLS and redirect policy get enforced.
The certificate and private key live in a TLS-type Secret (keys tls.crt and tls.key), which the Ingress references by name. Create the Secret first, then point the tls block at it and match the host.
# a TLS secret is just the cert + key under fixed keys$ kubectl create secret tls payments-tls \--cert=tls.crt --key=tls.key -n payments$ kubectl -n payments get secret payments-tls -o jsonpath='{.type}'kubernetes.io/tls
apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: paymentsnamespace: paymentsspec:ingressClassName: nginxtls:- hosts: [pay.acme.internal]secretName: payments-tls # cert served for this hostrules:- host: pay.acme.internalhttp:paths:- path: /pathType: Prefixbackend:service: { name: payments-api, port: { number: 8080 } }
Force HTTPS and refuse weak TLS
Terminating TLS is pointless if the door still answers plaintext HTTP on :80. Turn on an SSL redirect so every HTTP request is 308-upgraded to HTTPS, and constrain the protocol versions and ciphers the controller will negotiate so you are not completing a TLS 1.0 handshake with whoever asks. In ingress-nginx these are annotations on the object plus controller-wide config; the exact keys differ per controller, which is why the docs tab matters.
metadata:annotations:nginx.ingress.kubernetes.io/ssl-redirect: "true" # http -> httpsnginx.ingress.kubernetes.io/force-ssl-redirect: "true" # even without default backendnginx.ingress.kubernetes.io/ssl-protocols: "TLSv1.3 TLSv1.2"
Verify from outside the cluster: an HTTP request should return a redirect to HTTPS, and the served certificate should be the one from your Secret with the right subject. curl -v shows the handshake, the negotiated protocol version, and the certificate chain in one shot.
$ curl -sI http://pay.acme.internal/ # should redirect, not serveHTTP/1.1 308 Permanent RedirectLocation: https://pay.acme.internal/$ curl -v https://pay.acme.internal/ 2>&1 | grep -E "SSL connection|subject:"* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384* subject: CN=pay.acme.internal