TLS termination¶
By default, NGINX Ingress Controller generates default TLS certificates for TLS termination. You can, though, generate and configure your own TLS certificates for TLS termination purposes.
Note
Prior to setting up TLS termination, verify that you have correctly configured kubectl.
Generate a self-signed certificate and a private key for the TLS connection.
Note
The Common Name (CN) in the certificate must match the host name of the server.
mkdir -p example_certs openssl req \ -new \ -newkey rsa:2048 \ -x509 \ -sha256 \ -days 365 \ -nodes \ -subj "/O=echo/CN=echo.example.com" \ -keyout example_certs/echo.example.com.key \ -out example_certs/echo.example.com.crt
Create a Kubernetes Secret that contains the generated certificate:
kubectl create secret tls echo-tls-secret --key example_certs/echo.example.com.key --cert example_certs/echo.example.com.crt
Deploy a sample application:
cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: echo-svc spec: replicas: 1 selector: matchLabels: app: echo-svc template: metadata: labels: app: echo-svc spec: containers: - name: echo-svc image: registry.k8s.io/e2e-test-images/echoserver:2.3 ports: - containerPort: 8080 env: - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP --- apiVersion: v1 kind: Service metadata: name: echo-svc labels: app: echo-svc spec: ports: - port: 80 targetPort: 8080 protocol: TCP name: http selector: app: echo-svc EOF
Deploy the Ingress.
Create an
Ingress
for the sample application, inserting the Kubernets Secret you created in thetls
section as the host for which the TLS connection will terminate:cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: echo-test spec: tls: - hosts: - echo.example.com secretName: echo-tls-secret ingressClassName: nginx-default rules: - host: echo.example.com http: paths: - path: / pathType: Prefix backend: service: name: echo-svc port: number: 80 EOF
Test the TLS termination by connecting to the application using HTTPS.
export MKE_HOST=<mke host> export NODE_PORT=33001 curl -k -v --resolve "echo.example.com:$NODE_PORT:$MKE_HOST" "https://echo.example.com:$NODE_PORT" Example output: * Added echo.example.com:33001:54.218.145.62 to DNS cache * Hostname echo.example.com was found in DNS cache * Trying 54.218.145.62:33001... * Connected to echo.example.com (54.218.145.62) port 33001 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/cert.pem * CApath: none * (304) (OUT), TLS handshake, Client hello (1): * (304) (IN), TLS handshake, Server hello (2): * (304) (IN), TLS handshake, Unknown (8): * (304) (IN), TLS handshake, Certificate (11): * (304) (IN), TLS handshake, CERT verify (15): * (304) (IN), TLS handshake, Finished (20): * (304) (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / AEAD-AES256-GCM-SHA384 * ALPN, server accepted to use h2 * Server certificate: * subject: O=echo; CN=echo.example.com * start date: Nov 29 19:58:22 2022 GMT * expire date: Nov 29 19:58:22 2023 GMT * issuer: O=echo; CN=echo.example.com * SSL certificate verify result: self signed certificate (18), continuing anyway. ...
The output shows that the TLS connection is being negotiated using the provided certficate.
Clean up Kubernetes resources that are no longer needed:
kubectl delete ingress echo-test kubectl delete service echo-svc kubectl delete deployment echo-svc kubectl delete secret echo-tls-secret