Canary Deployment
Gateway API provides native support for weighted traffic splitting, enabling canary deployments without additional tools or service mesh infrastructure. In this section, we'll deploy a new version of the UI application and progressively shift traffic from the original version to the new one using HTTPRoute weights.
With traditional Kubernetes Ingress, weighted traffic splitting is not natively supported — you would need a service mesh like Istio or App Mesh to achieve this. Gateway API makes it a first-class feature through the backendRefs weight field.
Deploy the new UI version
First, we'll deploy a second version of the UI application (ui-v2) that uses an orange theme to make it visually distinguishable from the original blue theme:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ui-v2
namespace: ui
labels:
app.kubernetes.io/name: ui
app.kubernetes.io/version: v2
app.kubernetes.io/component: service
app.kubernetes.io/created-by: eks-workshop
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ui
app.kubernetes.io/version: v2
template:
metadata:
labels:
app.kubernetes.io/name: ui
app.kubernetes.io/version: v2
spec:
containers:
- name: ui
image: public.ecr.aws/aws-containers/retail-store-sample-ui:1.2.1
ports:
- containerPort: 8080
protocol: TCP
env:
- name: RETAIL_UI_THEME
value: "orange"
The key difference is the RETAIL_UI_THEME=orange environment variable, which produces a visually distinct orange-themed UI.
We also need a Service to route traffic to the new pods:
apiVersion: v1
kind: Service
metadata:
name: ui-v2
namespace: ui
labels:
app.kubernetes.io/name: ui
app.kubernetes.io/version: v2
app.kubernetes.io/created-by: eks-workshop
spec:
selector:
app.kubernetes.io/name: ui
app.kubernetes.io/version: v2
ports:
- port: 8080
targetPort: 8080
protocol: TCP
Apply both resources:
Wait for the new pods to be ready:
Apply the 90/10 canary route
Now we'll replace the existing ui-route HTTPRoute with a weighted version that sends 90% of traffic to the original UI and 10% to ui-v2:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: ui-route
namespace: ui
spec:
parentRefs:
- name: retail-store-gateway
namespace: ui
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: ui
port: 80
weight: 90
- name: ui-v2
port: 8080
weight: 10
Notice how the backendRefs field now contains two entries with explicit weight values. The Gateway controller distributes traffic proportionally based on these weights.
Apply the canary HTTPRoute:
Test the traffic split
Send multiple requests to the Gateway and observe the distribution. Approximately 10% of responses should come from the orange-themed ui-v2:
href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-orange.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-orange.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-orange.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-orange.css"theme: {You should see that most responses return theme-default while roughly 1-2 out of 20 requests return theme-orange, confirming the 90/10 traffic split is working.
Increase traffic to 50/50
Once you're confident the new version is working correctly, increase the canary weight to 50%:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: ui-route
namespace: ui
spec:
parentRefs:
- name: retail-store-gateway
namespace: ui
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: ui
port: 80
weight: 50
- name: ui-v2
port: 8080
weight: 50
Test again to see the even split:
You should now see roughly half of the responses returning the orange theme.
Complete the rollout
When you're satisfied with the new version, shift all traffic to ui-v2 by setting the weights to 0/100:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: ui-route
namespace: ui
spec:
parentRefs:
- name: retail-store-gateway
namespace: ui
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: ui
port: 80
weight: 0
- name: ui-v2
port: 8080
weight: 100
Verify that all traffic now goes to the new version:
All responses should now return the orange theme, confirming the full cutover to ui-v2.

Summary
In this section we performed a progressive canary deployment using Gateway API's native weighted traffic splitting:
- Deployed a new version of the UI with a distinct visual theme
- Started with a 90/10 split to test with minimal risk
- Increased to 50/50 after validating the new version
- Completed the rollout with a 0/100 split
Gateway API vs Ingress comparison
| Capability | Gateway API | Kubernetes Ingress |
|---|---|---|
| Weighted traffic splitting | Native via backendRefs weights | Not supported natively |
| Canary deployments | Built-in, no extra tools needed | Requires service mesh or annotations |
| Cross-namespace routing | Native via parentRefs | Requires IngressGroup or similar workarounds |
| Role-oriented model | GatewayClass → Gateway → HTTPRoute | Single Ingress resource |
| Multiple backends per route | Native with weights and filters | Limited to single backend per path |
| Progressive rollouts | Declarative weight updates | Requires external controllers |
Gateway API's native traffic splitting makes canary deployments straightforward and declarative, eliminating the need for additional service mesh infrastructure or custom annotations that traditional Ingress requires.