Belajar Kubernetes - Episode 19.1 - Ingress dengan Gateway API

Belajar Kubernetes - Episode 19.1 - Ingress dengan Gateway API

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.

Arman Dwi Pangestu
Arman Dwi PangestuMarch 23, 2026
0 views
10 min read

Pendahuluan

Catatan

Untuk kalian yang ingin membaca episode sebelumnya, bisa click thumbnail episode 19 di bawah ini

Episode 19Episode 19

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.

Apa Itu Gateway API?

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:

  • Role-oriented - Separate concern antara infrastructure dan application team
  • Expressive - Lebih banyak routing capability daripada Ingress
  • Extensible - Custom resource dan filter
  • Portable - Work across different implementation
  • Type-safe - Strongly typed API dengan validation
  • Multi-protocol - HTTP, HTTPS, TCP, UDP, gRPC
  • Advanced routing - Header-based, query param-based routing
  • Traffic splitting - Weighted routing untuk canary deployment

Gateway API vs Traditional Ingress

Mari kita pahami perbedaan kunci nya:

AspekGateway APITraditional Ingress
DesignRole-oriented (3 persona)Single resource
ExpressivenessHighly expressiveLimited
ProtocolHTTP, HTTPS, TCP, UDP, gRPCHTTP, HTTPS saja
RoutingHeader, query, method-basedHost dan path saja
Traffic ManagementBuilt-in traffic splittingRequire annotation
ExtensibilityCustom filter dan resourceAnnotation-based
PortabilityStandardized across providerProvider-specific
MaturityGA (2023)GA (2019)

Arsitektur Gateway API

Gateway API introduce tiga main resource yang represent different persona:

1. GatewayClass

Define class dari Gateway (seperti IngressClass). Di manage oleh infrastructure provider.

Kubernetesyml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
    name: example-gateway-class
spec:
    controllerName: example.com/gateway-controller

2. Gateway

Define bagaimana traffic di translate ke Service. Di manage oleh cluster operator.

Kubernetesyml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
    name: example-gateway
spec:
    gatewayClassName: example-gateway-class
    listeners:
        - name: http
          protocol: HTTP
          port: 80

3. HTTPRoute

Define HTTP routing rule. Di manage oleh application developer.

Kubernetesyml
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: 8080

Install Gateway API

Step 1: Install Gateway API CRD

Kubernetesbash
sudo kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml

Verify installation:

Kubernetesbash
sudo kubectl get crd | grep gateway

Output:

Kubernetesbash
gatewayclasses.gateway.networking.k8s.io
gateways.gateway.networking.k8s.io
httproutes.gateway.networking.k8s.io
referencegrants.gateway.networking.k8s.io

Step 2: Install Gateway Controller

Untuk contoh ini, kita akan gunakan NGINX Gateway Fabric:

Kubernetesbash
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.yaml

Verify controller:

Kubernetesbash
sudo kubectl get pods -n nginx-gateway

Membuat Gateway Pertama

Step 1: Buat GatewayClass

Kubernetesgateway-class.yml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
    name: nginx
spec:
    controllerName: gateway.nginx.org/nginx-gateway-controller

Apply:

Kubernetesbash
sudo kubectl apply -f gateway-class.yml

Step 2: Buat Gateway

Kubernetesgateway.yml
apiVersion: 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: Same

Apply:

Kubernetesbash
sudo kubectl apply -f gateway.yml

Verify:

Kubernetesbash
sudo kubectl get gateway

Output:

Kubernetesbash
NAME              CLASS   ADDRESS         READY   AGE
example-gateway   nginx   203.0.113.10    True    30s

Step 3: Buat Application dan Service

Kubernetesapp.yml
apiVersion: 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: 80

Apply:

Kubernetesbash
sudo kubectl apply -f app.yml

Step 4: Buat HTTPRoute

Kuberneteshttp-route.yml
apiVersion: 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: 80

Apply:

Kubernetesbash
sudo kubectl apply -f http-route.yml

Verify:

Kubernetesbash
sudo kubectl get httproute

Sekarang 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

  1. Disable traefik bawaan (karena jika langsung ubah dari config nya akan terkena override terus ketika ingin enable fitur Gateway API)
sudo nvim /etc/rancher/k3s/config.yaml
  1. Restart K3s
bash
sudo systemctl restart k3s
  1. Setup kubeconfig agar tidak pakai sudo
Kubernetesbash
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER:$USER ~/.kube/config
  1. Install traefik via Helm
helm repo add traefik https://traefik.github.io/charts
helm repo update
  1. Buat Gateway
Kubernetesgateway.yml
apiVersion: 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-tls
  1. Deploy aplikasi menggunakan Deployment, Service, dan HTTPRoute
Kubernetesapp.yml
# ================================
# 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: 80

Testing connection

Linuxbash
curl -k --resolve web.example.com:443:10.10.10.4 https://web.example.com -v

Advanced Routing dengan Gateway API

Header-Based Routing

Route berdasarkan HTTP header:

Kubernetesheader-route.yml
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: 8080

Query Parameter Routing

Route berdasarkan query parameter:

Kubernetesquery-route.yml
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: 8080

HTTP Method Routing

Route berdasarkan HTTP method:

Kubernetesmethod-route.yml
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: 8080

Traffic Splitting dan Canary Deployment

Gateway API membuat traffic splitting jadi simple:

Weighted Traffic Distribution

Kubernetescanary-route.yml
# ================================
# Alpha Service
# ================================
apiVersion: apps/v1
kind: Deployment
metadata:
  name: alpha-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: alpha-service
  template:
    metadata:
      labels:
        app: alpha-service
    spec:
      containers:
        - name: alpha-service
          image: ghcr.io/armandwipangestu/alpha-service:1.0.1
          ports:
            - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: alpha-service
spec:
  selector:
    app: alpha-service
  ports:
    - port: 80
      targetPort: 3000
---
# ================================
# Beta Service
# ================================
apiVersion: apps/v1
kind: Deployment
metadata:
  name: beta-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: beta-service
  template:
    metadata:
      labels:
        app: beta-service
    spec:
      containers:
        - name: beta-service
          image: ghcr.io/armandwipangestu/beta-service:1.0.1
          ports:
            - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: beta-service
spec:
  selector:
    app: beta-service
  ports:
    - port: 80
      targetPort: 3000
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: canary-gateway
spec:
  gatewayClassName: traefik
  listeners:
    - name: http
      protocol: HTTP
      port: 8000
      hostname: "*.example.com"
 
    - name: https
      protocol: HTTPS
      port: 8443
      hostname: "*.example.com"
      tls:
        mode: Terminate
        certificateRefs:
          - name: example-tls
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: canary-route
spec:
  parentRefs:
    - name: canary-gateway
      sectionName: https
    - name: canary-gateway
      sectionName: http
  hostnames:
    - "canary.example.com"
  rules:
    - backendRefs:
        - name: alpha-service
          port: 80
          weight: 90
        - name: beta-service
          port: 80
          weight: 10

Ini send 90% traffic ke alpha version dan 10% ke beta version.

Progressive Canary Rollout

Kubernetesprogressive-canary.yml
# 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: 5

Update weight secara progressive: 5% → 25% → 50% → 100%

Konfigurasi TLS

Configure HTTPS dengan Gateway API:

Step 1: Buat TLS Secret

Kubernetesbash
sudo kubectl create secret tls example-tls \
    --cert=path/to/tls.crt \
    --key=path/to/tls.key

Step 2: Configure Gateway dengan TLS

Kubernetestls-gateway.yml
apiVersion: 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: Same

Step 3: Buat HTTPRoute untuk HTTPS

Kuberneteshttps-route.yml
apiVersion: 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: 80

Cross-Namespace Routing

Gateway API support routing across namespace dengan ReferenceGrant:

Step 1: Buat ReferenceGrant

Kubernetesreference-grant.yml
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: Service

Step 2: Buat Cross-Namespace Route

Kubernetescross-ns-route.yml
apiVersion: 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: 8080

Request/Response Modification

Modify request dan response:

Request Header Modification

Kubernetesheader-modification.yml
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: 8080

URL Rewrite

Kubernetesurl-rewrite.yml
apiVersion: 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: 8080

Request Mirroring

Mirror traffic ke service lain untuk testing:

Kubernetesmirror-route.yml
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: 8080

Traffic pergi ke production-service, tapi juga di mirror ke test-service.

Konfigurasi Timeout

Configure request timeout:

Kubernetestimeout-route.yml
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: 8080

Contoh Praktis: Complete Microservices Setup

Kubernetesmicroservices-gateway.yml
apiVersion: 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: 3000

Monitoring dan Observability

Check Gateway Status

Kubernetesbash
sudo kubectl get gateway example-gateway -o yaml

Look for status condition:

Kubernetesyml
status:
    conditions:
        - type: Accepted
          status: "True"
        - type: Programmed
          status: "True"
    addresses:
        - value: 203.0.113.10

Check HTTPRoute Status

Kubernetesbash
sudo kubectl get httproute web-route -o yaml

View Gateway Event

Kubernetesbash
sudo kubectl describe gateway example-gateway

Migrasi dari Ingress ke Gateway API

Before (Ingress)

Kubernetesyml
apiVersion: 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: 80

After (Gateway API)

Kubernetesyml
apiVersion: 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: 80

Best Practice

Gunakan Role-Based Resource

Separate concern by persona:

Kubernetesyml
# Infrastructure team manage GatewayClass
# Cluster operator manage Gateway
# Developer manage HTTPRoute

Leverage Traffic Splitting

Gunakan untuk canary deployment:

Kubernetesyml
backendRefs:
    - name: stable
      weight: 95
    - name: canary
      weight: 5

Configure Timeout

Selalu set appropriate timeout:

Kubernetesyml
timeouts:
    request: 30s
    backendRequest: 25s

Gunakan ReferenceGrant untuk Security

Control cross-namespace access:

Kubernetesyml
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant

Monitor Gateway Health

Check status secara regular:

Kubernetesbash
sudo kubectl get gateway -o wide
sudo kubectl get httproute -o wide

Gunakan Descriptive Name

Pilih clear resource name:

Kubernetesyml
# Bagus
name: api-gateway
name: user-service-route
 
# Hindari
name: gw1
name: route

Troubleshooting

Gateway Not Ready

Check controller log:

Kubernetesbash
sudo kubectl logs -n nginx-gateway -l app=nginx-gateway

HTTPRoute Not Working

Verify parent reference:

Kubernetesbash
sudo kubectl get httproute <route-name> -o yaml

Check status condition.

Cross-Namespace Issue

Verify ReferenceGrant:

Kubernetesbash
sudo kubectl get referencegrant -A

TLS Certificate Issue

Check secret exist:

Kubernetesbash
sudo kubectl get secret <tls-secret-name>

Penutup

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 adalah evolution dari Kubernetes Ingress
  • Role-oriented design separate infrastructure, cluster, dan app concern
  • More expressive routing dengan header, query param, method
  • Traffic splitting built-in untuk canary deployment
  • Multi-protocol support (HTTP, HTTPS, TCP, UDP, gRPC)
  • Extensible dengan custom filter dan resource
  • Portable across different implementation
  • Tiga main resource: GatewayClass, Gateway, HTTPRoute
  • Advanced feature: request mirroring, URL rewrite, timeout
  • ReferenceGrant untuk secure cross-namespace routing
  • Graduated ke GA di 2023 untuk core feature
  • Coexist dengan traditional Ingress (bukan replacement)

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

Episode 20Episode 20

Related Posts