How to Deploy Gateway API with TLS Encryption on Kubernetes

The Kubernetes Gateway API is a standard interface for managing service networking within Kubernetes clusters. It succeeds the Ingress API by offering a more expressive and extensible resource model (comprising GatewayClass, Gateway, and HTTPRoute) to handle advanced traffic routing, role-oriented management, and cross-namespace connectivity natively.
This article outlines the process of exposing a web application securely using the Gateway API. It covers the installation of Envoy Gateway as the controller and configuration of cert-manager for automated TLS certificate provisioning from Let's Encrypt.
Prerequisites
Before you begin, you need to:
- Have a Kubernetes cluster.
- Install and Configure Kubectl on your workstation to access your Kubernetes cluster.
- Install Helm on your workstation.
- Have a domain name, such as
app.example.com.
Install Envoy Gateway
The Gateway API requires an implementation controller to function. Envoy Gateway translates Gateway API resources into configuration for the Envoy Proxy data plane.
Install the Gateway API CRDs and the Envoy Gateway controller using the OCI Helm registry.
console$ helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.6.1 -n envoy-gateway-system --create-namespace
Wait for the controller to report as available.
console$ kubectl wait --timeout=5m -n envoy-gateway-system deployment/envoy-gateway --for=condition=Available
Create the GatewayClass resource to register the Envoy Gateway controller.
console$ kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: eg spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller EOF
Install cert-manager
Deploy the cert-manager operator with the Gateway API feature gate enabled. This configuration ensures the certificate controller can communicate with the Gateway API to route Let's Encrypt validation traffic correctly.
Install the cert-manager Helm chart with Gateway API support enabled.
console$ helm upgrade --install cert-manager oci://quay.io/jetstack/charts/cert-manager \ --namespace cert-manager \ --create-namespace \ --version v1.19.2 \ --set config.apiVersion=controller.config.cert-manager.io/v1alpha1 \ --set config.kind=ControllerConfiguration \ --set config.enableGatewayAPI=true \ --set crds.enabled=true
Verify that the cert-manager pods enter the Running state.
console$ kubectl wait --for=condition=Ready pods --all -n cert-manager
Configure the ClusterIssuer
A ClusterIssuer represents a certificate authority capable of issuing TLS certificates cluster-wide. Register the cluster with Let's Encrypt to automate certificate management. This ClusterIssuer configuration enables the ACME HTTP-01 solver, which allows cert-manager to prove domain ownership.
Create a ClusterIssuer manifest.
console$ nano cluster-issuer.yaml
Add the following configuration. Replace
admin@example.comwith your valid email address.yamlapiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: admin@example.com privateKeySecretRef: name: letsencrypt-prod solvers: - http01: gatewayHTTPRoute: parentRefs: - name: web-gateway kind: Gateway
Save and close the file.
Apply the ClusterIssuer manifest.
console$ kubectl apply -f cluster-issuer.yaml
Deploy a Sample Web Application
To verify traffic routing, deploy a simple web application using the nginxdemos/hello image.
Create a deployment for the web application.
console$ kubectl create deployment web-app --image=nginxdemos/hello --replicas=2
Expose the deployment internally as a Service.
console$ kubectl expose deployment web-app --port=80 --target-port=80
Initialize the Gateway
Deploy the Gateway resource to provision a cloud LoadBalancer and assign a public IP address. This resource defines how the cluster handles traffic for your domain.
Create the Gateway manifest file.
console$ nano gateway.yaml
Add the following configuration. Replace
app.example.comwith your actual domain name.yamlapiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: web-gateway annotations: cert-manager.io/cluster-issuer: letsencrypt-prod spec: gatewayClassName: eg listeners: - name: http protocol: HTTP port: 80 hostname: "app.example.com" allowedRoutes: namespaces: from: Same - name: https protocol: HTTPS port: 443 hostname: "app.example.com" tls: mode: Terminate certificateRefs: - kind: Secret name: web-app-tls-secret allowedRoutes: namespaces: from: Same
Save and close the file.
Apply the Gateway manifest.
console$ kubectl apply -f gateway.yaml
Retrieve the Gateway external IP address.
console$ kubectl get gateway web-gateway
Update your domain’s DNS A record to point to the assigned IP address.
Verify the TLS certificate status.
console$ kubectl get certificate
The certificate may take a few minutes to update to
True.
Configure Secure Application Routing
Define the routing rules to direct traffic from the Gateway to your backend service. Attach this route exclusively to the HTTPS listener to enforce encryption and prevent insecure access.
Create the HTTPRoute manifest file.
console$ nano http-route.yaml
Add the following configuration:
yamlapiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: web-app-route spec: parentRefs: - name: web-gateway sectionName: https hostnames: - "app.example.com" rules: - backendRefs: - name: web-app port: 80
Save and close the file.
Apply the HTTPRoute manifest.
console$ kubectl apply -f http-route.yaml
Open a web browser and navigate to your domain name
https://app.example.com. Verify that the browser displays a padlock icon next to the URL, indicating a valid certificate, and loads the application successfully.
Conclusion
You have deployed a Gateway API setup with Envoy Gateway and cert-manager. The web application is now secure and accessible via HTTPS using the Gateway API. Envoy Gateway manages the traffic routing, while cert-manager automates the lifecycle of Let's Encrypt certificates. Refer to the official Gateway API documentation for advanced routing and traffic management features.