Backend TLS
Configure TLS to terminate for a specific backend workload.
When you configure an HTTPS listener, the Gateway terminates the TLS connection and decrypts the traffic. The Gateway then routes the decrypted traffic to the backend service.
However, you might have a specific backend workload that uses its own TLS certificate. In this case, you can configure the Gateway to originate a TLS connection that terminates at the backend service by using the Kubernetes Gateway API BackendTLSPolicy. For more information, see the Kubernetes Gateway API docs.
Before you begin
-
Follow the Get started guide to install kgateway.
-
Follow the Sample app guide to create an API gateway proxy with an HTTP listener and deploy the httpbin sample app.
-
Get the external address of the gateway and save it in an environment variable.
export INGRESS_GW_ADDRESS=$(kubectl get svc -n kgateway-system http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") echo $INGRESS_GW_ADDRESS
kubectl port-forward deployment/http -n kgateway-system 8080:8080
Create a backend workload with a TLS certificate
The following example uses an NGINX server with a self-signed TLS certificate. For the configuration, see the test directory in the kgateway GitHub repository.
-
Deploy the NGINX server with a self-signed TLS certificate.
kubectl apply -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/v2.0.x/test/kubernetes/e2e/features/backendtls/inputs/nginx.yaml
-
Verify that the NGINX server is running.
kubectl get pods -l app.kubernetes.io/name=nginx
Example output:
NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 9s
Create a BackendTLSPolicy
Create the BackendTLSPolicy for the NGINX workload. For more information, see the Kubernetes Gateway API docs.
-
Install the experimental channel of the Kubernetes Gateway API so that you can use BackendTLSPolicy.
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/experimental-install.yaml
-
Create a Kubernetes ConfigMap that has the public CA certificate for the NGINX server.
kubectl apply -f- <<EOF # public cert of self-signed cert loaded into nginx, see nginx.yaml # separate file so it can be deleted independently apiVersion: v1 data: ca.crt: | -----BEGIN CERTIFICATE----- MIICszCCAZsCFD9dhyrM7bqtwYLORIn7QTULAmRaMA0GCSqGSIb3DQEBCwUAMBYx FDASBgNVBAMMC2V4YW1wbGUuY29tMB4XDTI1MDQxMDIyMjYxNVoXDTI2MDQxMDIy MjYxNVowFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA A4IBDwAwggEKAoIBAQC46DSkpngZavNVgByw/h7rbKyvgzp2wGDW/fPGL0/rkLcK IsIiNgHH6vA0UPTSI3YsHeu+CnQCEhZWk9KhQ2q8etSynUoizIrj2iuxKTEsL3SJ 7cI03cpHiQoMuUqp4L4lA6/YXsLkXjHWtnTLKjsvsrjBFiu96ueoje6B2sfcSlYR FI1WgMgZQP+LALy9tVtMManIqKVr63BG0884AghF3sPo5ryOEP/1Oc9F6Ivf67Jf NjMhuBHahT500hYyuxzjgUPoMWyX1FQ7NL/OWUJ5EXuSnxpDb7edVDVCz+z199S7 6wpAKEe0hoJG5Ahw1vWNRRBO8gnsSjLAHEw0nXpvAgMBAAEwDQYJKoZIhvcNAQEL BQADggEBAGtLZTITtlEMJc8u7qrN8psA2Eiycgv6Cqi48NeF6lldfg7hVfm9CLB1 xKBHZnbLoBl6WbfRarFT/FtT8bzLrwQLl3SnmHuRvQgHSBBIBP3gUggog7GUdo2e /h3p7bot/53gyFUfEfCZ+hw1n20VpAJzkJ+6VAQg8yvMzqC6wSVPNGTniS7KIRtH ON2ulncyLxR65lOiqLrGOw6oXUF1RpTqiJnOGDqJV5RV4+uBHIQZG4BwNXbUNira V2wU4MHa1JLXAaOVJsyY5GcXlTXfus4cGOFyFHPvBAXu42OF7wbAx3bPJzOlBx2Y l339oYIY57gPn8irKcZGJ0idvMc8b7Y= -----END CERTIFICATE----- kind: ConfigMap metadata: name: ca EOF
-
Create the BackendTLSPolicy.
kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1alpha3 kind: BackendTLSPolicy metadata: name: nginx-tls-policy labels: app: nginx spec: targetRefs: - group: "" kind: Service name: nginx validation: hostname: "example.com" caCertificateRefs: - group: "" kind: ConfigMap name: ca EOF
Setting Description targetRefs
The service that you want the Gateway to originate a TLS connection to, such as the NGINX server. validation.hostname
The hostname that matches the NGINX server certificate. validation.caCertificateRefs
The ConfigMap that has the public CA certificate for the NGINX server. -
Create an HTTPRoute that routes traffic to the NGINX server on the
example.com
hostname and HTTPS port 8443. Note that the parent Gateway is the samplehttp
Gateway resource that you created before you began.kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: nginx-route labels: app: nginx spec: parentRefs: - name: http namespace: kgateway-system hostnames: - "example.com" rules: - backendRefs: - name: nginx port: 8443 EOF
Verify the TLS connection
Now that your TLS backend and routing resources are configured, verify the TLS connection.
-
Get the external address of the gateway and save it in an environment variable. Note that it might take a few seconds for the gateway address to become available.
export INGRESS_GW_ADDRESS=$(kubectl get svc -n kgateway-system http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") echo $INGRESS_GW_ADDRESS
kubectl port-forward svc/http -n kgateway-system 8080:8080
-
Send a request to the NGINX server and verify that you get back a 200 HTTP response code.
curl -vi http://$INGRESS_GW_ADDRESS:8080/ -H "host: example.com:8080"
curl -vi http://localhost:8080/ -H "host: example.com:8080"
Example output:
* Host localhost:8080 was resolved. * IPv6: ::1 * IPv4: 127.0.0.1 * Trying [::1]:8080... * Connected to localhost (::1) port 8080 > GET / HTTP/1.1 > Host: example.com:8080 > User-Agent: curl/8.7.1 > Accept: */* > * Request completely sent off < HTTP/1.1 200 OK HTTP/1.1 200 OK
-
Enable port-forwarding on the Gateway.
kubectl port-forward deploy/http -n kgateway-system 19000
-
In your browser, open the Envoy stats page at http://127.0.0.1:19000/stats.
-
Search for the following stats that indicate the TLS connection is working. The count increases each time that the Gateway sends a request to the NGINX server.
cluster.kube_default_nginx_8443.ssl.versions.TLSv1.2
: The number of TLSv1.2 connections from the Envoy gateway proxy to the NGINX server.cluster.kube_default_nginx_8443.ssl.handshake
: The number of successful TLS handshakes between the Envoy gateway proxy and the NGINX server.
Cleanup
You can remove the resources that you created in this guide.-
Delete the NGINX server.
kubectl delete -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/v2.0.x/test/kubernetes/e2e/features/backendtls/inputs/nginx.yaml
-
Delete the routing resources that your created for the NGINX server.
kubectl delete backendtlspolicy,configmap,httproute -A -l app=nginx
-
If you want to re-create a BackendTLSPolicy after deleting one, restart the control plane.
HTTP/1.1 400 Bad Request
error after creating the new BackendTLSPolicy.
kubectl rollout restart -n kgateway-system deployment/kgateway