TLS encryption
Enable server-side TLS encryption for the xDS gRPC server in the kgateway control plane. For more information about the server, see the Architecture docs.
TLS encryption is disabled by default. When enabled, the control plane mounts a kgateway-xds-cert
TLS secret that you create and propogates the CA bundle to any kgateway and agentgateway data plane proxies to establish a secure connection. You might integrate your secret with a provider such as cert-manager to automate certificate management and rotation.
Before you begin
-
Follow the Get started guide to install kgateway.
-
Follow the Sample app guide to create a 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
Step 1: Set up cert-manager
cert-manager is a Kubernetes controller that helps you automate the process of obtaining and renewing certificates from various PKI providers, such as AWS Private CA, Google Cloud CA, or Vault. In this example, you set up cert-manager to provide self-signed certificates for the kgateway control plane.
-
Add the Jetstack Helm repository.
helm repo add jetstack https://charts.jetstack.io --force-update
-
Install cert-manager in your cluster. Note: cert-manager versions 1.18 and later have stricter validation rules. Certificate durations must be at least 1 hour, and renewal windows must be at least 5 minutes.
helm upgrade --install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace \ --set "extraArgs={--feature-gates=ExperimentalGatewayAPISupport=true}" --set installCRDs=true
ℹ️To allow cert-manager to use the Kubernetes Gateway API, you must set--feature-gates=ExperimentalGatewayAPISupport=true
in the cert-manager Helm installation. -
Create a self-signed Certificate Authority (CA) that acts as the root of trust for the xDS gRPC server certificates. For production environments, replace the self-signed root issuer with your organization’s CA issuer, such as Vault or a cloud CA service. For more information, see the cert-manager CA issuer docs.
kubectl apply -f - <<EOF apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: kgateway-xds-root-issuer namespace: kgateway-system spec: selfSigned: {} --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: kgateway-xds-ca namespace: kgateway-system spec: secretName: kgateway-xds-ca-secret issuerRef: name: kgateway-xds-root-issuer kind: Issuer isCA: true commonName: kgateway-xds-ca duration: 1h renewBefore: 5m privateKey: algorithm: RSA size: 2048 EOF
-
Use the CA to sign a TLS certificate for the xDS gRPC server. This two-tiered approach keeps the root CA separate from the server certificate, and lets the server certificate be rotated independently of the CA. cert-manager automatically creates a Kubernetes secret with the required name
kgateway-xds-cert
, typekubernetes.io/tls
, and the server certificate and private key in thetls.crt
andtls.key
keys.ℹ️The DNS names in the server certificate must match the service endpoints of the control plane. If you install the control plane in a different namespace, you must update the DNS names to match the actual service endpoints.kubectl apply -f - <<EOF apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: kgateway-xds-ca-issuer namespace: kgateway-system spec: ca: secretName: kgateway-xds-ca-secret --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: kgateway-xds-cert namespace: kgateway-system spec: secretName: kgateway-xds-cert issuerRef: name: kgateway-xds-ca-issuer kind: Issuer isCA: false dnsNames: - kgateway - kgateway.kgateway-system - kgateway.kgateway-system.svc - kgateway.kgateway-system.svc.cluster.local duration: 1h renewBefore: 5m privateKey: algorithm: RSA size: 2048 EOF
Step 2: Update the control plane to use TLS
Upgrade kgateway with TLS enabled for the controller. For complete steps, review the Upgrade guide.
-
Set your version of kgateway in an environment variable, such as the latest patch version (
2.0.4
).export NEW_VERSION=2.0.4
-
Get the Helm values file for your current version.
helm get values kgateway -n kgateway-system -o yaml > values.yaml open values.yaml
-
Add the following values to the Helm values file to enable TLS for the xDS gRPC server.
controller: xds: tls: enabled: true
-
Upgrade your Helm installation.
helm upgrade -i -n kgateway-system kgateway oci://cr.kgateway.dev/kgateway-dev/charts/kgateway \ -f values.yaml \ --version v$NEW_VERSION
-
Confirm that the kgateway control plane is up and running.
kubectl get pods -n kgateway-system
Step 3: Verify the TLS connection
Now that the control plane is up and running, verify the TLS connection.
-
Port-forward the control plane service on port 9977.
kubectl port-forward -n kgateway-system svc/kgateway 9977
-
Send a request to the control plane in plaintext without TLS authentication. You get back an
authentication failed
error.grpcurl -plaintext localhost:9977 list
Example output:
Failed to list services: rpc error: code = Unknown desc = authentication failed: [Authenticator KubeJWTAuthenticator: target JWT extraction error: no HTTP authorization header exists]
-
Port-forward the control plane deployment on port 9092.
kubectl port-forward -n kgateway-system deploy/kgateway 9092
-
Send a request to the metrics endpoint to check for
xds_auth
metrics.curl localhost:9092/metrics | grep xds_auth
Example output:
# HELP kgateway_xds_auth_rq_failure_total Total number of failed xDS auth requests # TYPE kgateway_xds_auth_rq_failure_total counter kgateway_xds_auth_rq_failure_total 2 # HELP kgateway_xds_auth_rq_success_total Total number of successful xDS auth requests # TYPE kgateway_xds_auth_rq_success_total counter kgateway_xds_auth_rq_success_total 1 # HELP kgateway_xds_auth_rq_total Total number of xDS auth requests # TYPE kgateway_xds_auth_rq_total counter kgateway_xds_auth_rq_total 3