
Series of blog posts show progress of updating/adding to EKS Cluster, this post covers adding Gateway API. See part 1 below:
Gateway API:
- Kubernetes positions Gateway API as the next generation of service networking for L4/L7 routing.
Flow & Steps Forward:
- We’ll use the stable Envoy Gateway
v1.9.2Helm chart.- Its chart supplies compatible Gateway API and Envoy CRDs.
- No ALB/NLB hourly charges.
- No new Terraform, IAM, or Pod Identity initially.
- Managed completely through Argo CD.
- Teaches the portable Gateway API objects.
- Test locally through
kubectl port-forward. - Later, repeat the exercise with AWS Load Balancer Controller to create real ALBs/NLBs.
Implementation Phases:
- Start with Envoy Gateway using an internal
ClusterIP: - Install Envoy Gateway and Gateway API CRDs.
- Update the lab-platform and workload AppProjects.
- Deploy a small ARM64-compatible demonstration application.
- Add GatewayClass, Gateway, and HTTPRoute.
- Port-forward Envoy and test routing with curl.
- Test path matching, redirects, header matching, and traffic splitting.
- Optionally add AWS Load Balancer Controller for public ALB/NLB routing.
| Phase | Purpose | Resources |
|---|---|---|
| Phase 1 | Install the controller and CRDs | Envoy Gateway Helm chart |
| Phase 2A | Prepare platform ownership | AppProject, Application, Namespace |
| Phase 2B | Select and configure Envoy | GatewayClass, EnvoyProxy |
| Phase 2C | Create the listener | Gateway |
| Phase 3A | Deploy the test application | Deployment, Service |
| Phase 3B | Connect traffic to the application | HTTPRoute |
| Phase 4 | Test routing | Port-forward, curl, status checks |
Planned Gitops Structure:
applications/lab/├── platform/│ ├── envoy-gateway.yaml│ └── envoy-gateway-config.yaml└── workloads/ └── gateway-demo.yamlapps/├── envoy-gateway/│ └── values.yaml├── envoy-gateway-config/│ ├── namespace.yaml│ ├── gatewayclass.yaml│ ├── envoy-proxy.yaml│ └── gateway.yaml└── gateway-demo/ ├── deployment.yaml ├── service.yaml └── httproute.yaml
| Resource | Responsibility |
|---|---|
GatewayClass | Selects Envoy Gateway as the implementation |
EnvoyProxy | Forces the generated Envoy service to ClusterIP |
Gateway | Defines the HTTP listener |
HTTPRoute | Routes requests to the application |
Service | Provides the route backend |
Deployment | Runs the demonstration application |
Phase 3a: Deploy the test application for Deployment, Service
- Deploys the workload independently of Gateway routing. This checkpoint proves:
===========Deployment → Pod → Service===========
===========applications/lab/workloads/└── gateway-demo.yamlapps/gateway-demo/├── deployment.yaml└── service.yaml===========
lab-platform.yaml:
=========== - namespace: gateway-demo server: https://kubernetes.default.svc===========
applications/lab/workloads/gateway-demo.yaml
- Create the workload Argo CD Application
- Sources:
apps/gateway-demo/deployment.yaml
- Create the demonstration deployment
- The image has an ARM64 build, matching the architecture of your EKS nodes.
- Sources:
apps/gateway-demo/service.yaml
- Create backend service
- Later, the Gateway will receive traffic on port 80 and the
HTTPRoutewill forward it to Service port 8080.
- Later, the Gateway will receive traffic on port 80 and the
Service port 8080
↓
container port 8080
↓
whoami process
Phase 3b: Connect traffic to the application for HTTP-Route
- Phase 3B adds the final connection:
- Client
- Gateway listener
- HTTPRoute
- gateway-demo Service
- whoami Pod
- Client
lab-platform.yaml:
- This permission allows the workload Application to manage its route, but it still cannot modify:
GatewayClassEnvoyProxyGateway
- That preserves the platform/workload ownership boundary.
=========== # Application teams may attach HTTP routes to permitted Gateways. - group: gateway.networking.k8s.io kind: HTTPRoute===========
apps/gateway-demo/httproute.yaml
- Sources:
- The route attaches the route to the
httplistener created in Phase 2C.
===========parentRefs: - name: gateway-demo sectionName: http===========
- This section means the request must use
gateway-demo.localas its HTTP hostname.
===========hostnames: - gateway-demo.local===========
- And sends the request too:
===========Service/gateway-demo:8080===========
applications/lab/projects/lab-workloads.yaml
===========spec: destinations: - namespace: gateway-demo server: https://kubernetes.default.svc clusterResourceWhitelist: - group: "" kind: Namespace namespaceResourceWhitelist: - group: "" kind: Service - group: gateway.networking.k8s.io kind: HTTPRoute===========
Phase 4: Test Routing for Port-Forward, curl, status checks
- End-to-End verification
Envoy Gateway controller↓GatewayClass↓Gateway + internal Envoy proxy↓HTTPRoute↓Service↓whoami Pod
- Proves all layers work
Applications Synced/HealthyGatewayClass Accepted TrueGateway Programmed TrueAttached routes 1HTTPRoute Accepted TrueHTTPRoute ResolvedRefs TrueBackend EndpointSlice ready trueEnvoy Service ClusterIPCorrect hostname HTTP 200Wrong hostname HTTP 404
Commands to try/test:
- After your git commands & terraform apply commands – the following commands can be attempted

===========kubectl patch application envoy-gateway \ -n argocd \ --type merge \ -p '{"operation":null}'===========kubectl annotate application monitoring-root \ -n argocd \ argocd.argoproj.io/refresh=hard \ --overwritekubectl annotate application envoy-gateway \ -n argocd \ argocd.argoproj.io/refresh=hard \ --overwrite===========
Can check k9s or here our a few commands to also try

===========kubectl get deployment,pods,service \ -n gateway-demo \ -o wide===========



Confirm endpoints can demonstrate a workload

Test traffic through Envoy
===========kubectl get services \ -n envoy-gateway-system \ -l gateway.envoyproxy.io/owning-gateway-name=gateway-demo===========ENVOY_SERVICE="$( kubectl get services \ -n envoy-gateway-system \ -l gateway.envoyproxy.io/owning-gateway-name=gateway-demo \ -o jsonpath='{.items[0].metadata.name}')"echo "$ENVOY_SERVICE"===========kubectl -n envoy-gateway-system port-forward svc/envoy-gateway-demo-gateway-demo-c72b0946 8080:80===========curl --include \ --resolve gateway-demo.local:8080:127.0.0.1 \ http://gateway-demo.local:8080/===========
- You should see
- HTTP/1.1 200 OK
===========curl → local port-forward → Envoy ClusterIP Service → Gateway listener → HTTPRoute → gateway-demo Service → gateway-demo pod===========

One thought on “EKS Cluster: Part 13 – Gateway API (Part 2)”