Di episode ini kita akan coba explore update terbaru Kubernetes Ingress menggunakan Gateway API. Pelajari cara leverage Gateway API yang baru untuk routing lebih advanced, traffic management, dan modern ingress pattern.

Catatan
Untuk kalian yang ingin membaca episode sebelumnya, bisa click thumbnail episode 19 di bawah ini
Di episode sebelumnya kita sudah belajar tentang traditional Kubernetes Ingress untuk HTTP/HTTPS routing. Sekarang di episode 19.1 ini, kita akan explore Gateway API - next generation dari Ingress yang menyediakan API yang lebih expressive, extensible, dan role-oriented untuk manage ingress traffic.
Catatan: Disini saya akan menggunakan Kubernetes Cluster yang di install melalui K3s.
Gateway API bukan replacement untuk Ingress, tapi lebih ke evolution yang address limitation dan provide capability yang lebih advanced. Dia di design untuk lebih expressive, extensible, dan portable across different implementation.
Gateway API adalah collection dari Kubernetes resource yang model service networking di Kubernetes. Dia adalah successor dari Ingress API, offering improved expressiveness, extensibility, dan role-oriented design.
Gateway API di develop oleh Kubernetes SIG Network community dan graduated ke Beta di 2022, dengan GA (General Availability) untuk core feature di 2023. Dia provide cara yang lebih powerful dan flexible untuk manage ingress traffic dibanding traditional Ingress.
Karakteristik kunci Gateway API:
Mari kita pahami perbedaan kunci nya:
| Aspek | Gateway API | Traditional Ingress |
|---|---|---|
| Design | Role-oriented (3 persona) | Single resource |
| Expressiveness | Highly expressive | Limited |
| Protocol | HTTP, HTTPS, TCP, UDP, gRPC | HTTP, HTTPS saja |
| Routing | Header, query, method-based | Host dan path saja |
| Traffic Management | Built-in traffic splitting | Require annotation |
| Extensibility | Custom filter dan resource | Annotation-based |
| Portability | Standardized across provider | Provider-specific |
| Maturity | GA (2023) | GA (2019) |
Gateway API introduce tiga main resource yang represent different persona:
Gateway API ConceptsDefine class dari Gateway (seperti IngressClass). Di manage oleh infrastructure provider.
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: example-gateway-class
spec:
controllerName: example.com/gateway-controllerDefine bagaimana traffic di translate ke Service. Di manage oleh cluster operator.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: example-gateway
spec:
gatewayClassName: example-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80Define HTTP routing rule. Di manage oleh application developer.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: example-route
spec:
parentRefs:
- name: example-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-service
port: 8080sudo kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yamlVerify installation:
sudo kubectl get crd | grep gatewayOutput:
gatewayclasses.gateway.networking.k8s.io
gateways.gateway.networking.k8s.io
httproutes.gateway.networking.k8s.io
referencegrants.gateway.networking.k8s.ioUntuk contoh ini, kita akan gunakan NGINX Gateway Fabric:
sudo kubectl apply -f https://github.com/nginxinc/nginx-gateway-fabric/releases/download/v1.1.0/crds.yaml
sudo kubectl apply -f https://github.com/nginxinc/nginx-gateway-fabric/releases/download/v1.1.0/nginx-gateway.yamlVerify controller:
sudo kubectl get pods -n nginx-gatewayapiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: nginx
spec:
controllerName: gateway.nginx.org/nginx-gateway-controllerApply:
sudo kubectl apply -f gateway-class.ymlapiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: example-gateway
namespace: default
spec:
gatewayClassName: nginx
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: SameApply:
sudo kubectl apply -f gateway.ymlVerify:
sudo kubectl get gatewayOutput:
NAME CLASS ADDRESS READY AGE
example-gateway nginx 203.0.113.10 True 30sapiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80Apply:
sudo kubectl apply -f app.ymlapiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: web-route
spec:
parentRefs:
- name: example-gateway
hostnames:
- "web.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: web-service
port: 80Apply:
sudo kubectl apply -f http-route.ymlVerify:
sudo kubectl get httprouteSekarang traffic ke web.example.com route melalui Gateway ke web-service.
Tip
Jika kalian menggunakan K3s yang dimana menggunakan Traefik sebagai default Ingress Controller nya dan ingin mencoba menjalankan Gateway API, kalian bisa ikuti langkah berikut ini
sudo nvim /etc/rancher/k3s/config.yamlsudo systemctl restart k3skubeconfig agar tidak pakai sudomkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER:$USER ~/.kube/confighelm repo add traefik https://traefik.github.io/charts
helm repo updateapiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: web-gateway
spec:
gatewayClassName: traefik
listeners:
- name: http
protocol: HTTP
port: 8000
hostname: "*.example.com"
- name: https
protocol: HTTPS
port: 8443
hostname: web.example.com
tls:
mode: Terminate
certificateRefs:
- name: example-tlsDeployment, Service, dan HTTPRoute# ================================
# Web Service
# ================================
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-service
spec:
replicas: 3
selector:
matchLabels:
app: web-service
template:
metadata:
labels:
app: web-service
spec:
containers:
- name: web-service
image: ghcr.io/armandwipangestu/web-service:1.0.1
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web-service
ports:
- port: 80
targetPort: 3000
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: web-service
spec:
parentRefs:
- name: web-gateway
sectionName: https
- name: web-gateway
sectionName: http
hostnames:
- "web.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: web-service
port: 80Testing connection
curl -k --resolve web.example.com:443:10.10.10.4 https://web.example.com -vRoute berdasarkan HTTP header:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: header-route
spec:
parentRefs:
- name: example-gateway
rules:
- matches:
- headers:
- name: X-API-Version
value: v2
backendRefs:
- name: api-v2-service
port: 8080
- matches:
- headers:
- name: X-API-Version
value: v1
backendRefs:
- name: api-v1-service
port: 8080Route berdasarkan query parameter:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: query-route
spec:
parentRefs:
- name: example-gateway
rules:
- matches:
- queryParams:
- name: version
value: beta
backendRefs:
- name: beta-service
port: 8080
- matches:
- queryParams:
- name: version
value: stable
backendRefs:
- name: stable-service
port: 8080Route berdasarkan HTTP method:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: method-route
spec:
parentRefs:
- name: example-gateway
rules:
- matches:
- method: POST
path:
type: PathPrefix
value: /api
backendRefs:
- name: write-service
port: 8080
- matches:
- method: GET
path:
type: PathPrefix
value: /api
backendRefs:
- name: read-service
port: 8080Gateway API membuat traffic splitting jadi simple:
Ini send 90% traffic ke alpha version dan 10% ke beta version.
# Phase 1: 5% canary
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app-route
spec:
parentRefs:
- name: example-gateway
rules:
- backendRefs:
- name: stable-service
port: 80
weight: 95
- name: canary-service
port: 80
weight: 5Update weight secara progressive: 5% → 25% → 50% → 100%
Configure HTTPS dengan Gateway API:
sudo kubectl create secret tls example-tls \
--cert=path/to/tls.crt \
--key=path/to/tls.keyapiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: tls-gateway
spec:
gatewayClassName: nginx
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: example-tls
allowedRoutes:
namespaces:
from: SameapiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: https-route
spec:
parentRefs:
- name: tls-gateway
hostnames:
- "secure.example.com"
rules:
- backendRefs:
- name: web-service
port: 80Gateway API support routing across namespace dengan ReferenceGrant:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-gateway-routes
namespace: app-namespace
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: default
to:
- group: ""
kind: ServiceapiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: cross-ns-route
namespace: default
spec:
parentRefs:
- name: example-gateway
rules:
- backendRefs:
- name: app-service
namespace: app-namespace
port: 8080Modify request dan response:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: header-mod-route
spec:
parentRefs:
- name: example-gateway
rules:
- filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Custom-Header
value: custom-value
set:
- name: X-Forwarded-Proto
value: https
remove:
- X-Internal-Header
backendRefs:
- name: api-service
port: 8080apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: rewrite-route
spec:
parentRefs:
- name: example-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /old-api
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /new-api
backendRefs:
- name: api-service
port: 8080Mirror traffic ke service lain untuk testing:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: mirror-route
spec:
parentRefs:
- name: example-gateway
rules:
- filters:
- type: RequestMirror
requestMirror:
backendRef:
name: test-service
port: 8080
backendRefs:
- name: production-service
port: 8080Traffic pergi ke production-service, tapi juga di mirror ke test-service.
Configure request timeout:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: timeout-route
spec:
parentRefs:
- name: example-gateway
rules:
- timeouts:
request: 30s
backendRequest: 25s
backendRefs:
- name: slow-service
port: 8080apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: microservices-gateway
spec:
gatewayClassName: nginx
listeners:
- name: https
protocol: HTTPS
port: 443
hostname: "*.example.com"
tls:
mode: Terminate
certificateRefs:
- name: wildcard-tls
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-routes
spec:
parentRefs:
- name: microservices-gateway
hostnames:
- "api.example.com"
rules:
# User service dengan canary
- matches:
- path:
type: PathPrefix
value: /users
backendRefs:
- name: user-service-stable
port: 8080
weight: 90
- name: user-service-canary
port: 8080
weight: 10
# Order service dengan header routing
- matches:
- path:
type: PathPrefix
value: /orders
headers:
- name: X-API-Version
value: v2
backendRefs:
- name: order-service-v2
port: 8080
- matches:
- path:
type: PathPrefix
value: /orders
backendRefs:
- name: order-service-v1
port: 8080
# Product service dengan timeout
- matches:
- path:
type: PathPrefix
value: /products
timeouts:
request: 10s
backendRefs:
- name: product-service
port: 8080
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: web-routes
spec:
parentRefs:
- name: microservices-gateway
hostnames:
- "web.example.com"
rules:
- backendRefs:
- name: frontend-service
port: 3000sudo kubectl get gateway example-gateway -o yamlLook for status condition:
status:
conditions:
- type: Accepted
status: "True"
- type: Programmed
status: "True"
addresses:
- value: 203.0.113.10sudo kubectl get httproute web-route -o yamlsudo kubectl describe gateway example-gatewayapiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app-route
spec:
parentRefs:
- name: example-gateway
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: app-service
port: 80Separate concern by persona:
# Infrastructure team manage GatewayClass
# Cluster operator manage Gateway
# Developer manage HTTPRouteGunakan untuk canary deployment:
backendRefs:
- name: stable
weight: 95
- name: canary
weight: 5Selalu set appropriate timeout:
timeouts:
request: 30s
backendRequest: 25sControl cross-namespace access:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrantCheck status secara regular:
sudo kubectl get gateway -o wide
sudo kubectl get httproute -o widePilih clear resource name:
# Bagus
name: api-gateway
name: user-service-route
# Hindari
name: gw1
name: routeCheck controller log:
sudo kubectl logs -n nginx-gateway -l app=nginx-gatewayVerify parent reference:
sudo kubectl get httproute <route-name> -o yamlCheck status condition.
Verify ReferenceGrant:
sudo kubectl get referencegrant -ACheck secret exist:
sudo kubectl get secret <tls-secret-name>Pada episode 19.1 ini, kita telah explore Gateway API - next generation dari Kubernetes ingress. Kita sudah belajar bagaimana dia improve traditional Ingress dengan routing yang lebih expressive, extensibility yang lebih baik, dan role-oriented design.
Key takeaway:
Gateway API represent future dari ingress di Kubernetes. Sementara traditional Ingress tetap supported, Gateway API provide capability yang lebih powerful untuk modern cloud-native application. Consider adopt Gateway API untuk project baru untuk leverage advanced feature nya.
Bagaimana, siap modernize Kubernetes ingress kalian? Jadi, pastikan tetap semangat belajar dan nantikan episode selanjutnya!
Catatan
Untuk kalian yang ingin melanjutkan ke episode selanjutnya, bisa click thumbnail episode 20 di bawah ini