Skip to content

Tổng Quan GKE Load Balancing — Gateway vs Ingress vs LoadBalancer Service

Tại sao cần phân biệt rõ ba cơ chế

GKE cung cấp ba cơ chế chính để expose ứng dụng: Service type: LoadBalancer, Ingress, và Gateway API. Cả ba đều có thể tạo ra một endpoint mà client kết nối vào — nhưng infrastructure GCP phía sau hoàn toàn khác nhau, operating model khác nhau, và constraint khác nhau.

Sai lầm phổ biến nhất là chọn cơ chế theo mức độ quen thuộc hoặc theo mẫu copy từ tutorial, thay vì chọn theo bản chất kỹ thuật của yêu cầu. Kết quả là: Service type: LoadBalancer được dùng cho traffic L7 cần path-based routing (không thể làm được), hoặc Ingress được dùng cho traffic TCP non-HTTP (không được hỗ trợ).

Framework đúng để chọn cơ chế: hỏi "GCP resource nào sẽ được tạo ra?""traffic đi theo đường nào?" — không phải "tôi muốn tính năng gì".

Internal model: Mỗi cơ chế tạo ra GCP resources nào

Service type: LoadBalancer

Khi bạn tạo một Service với type: LoadBalancer trong GKE, controller tạo ra một GCP Passthrough Network Load Balancer (L4). Đây là một load balancer hoạt động ở tầng TCP/UDP, không hiểu HTTP headers, không làm TLS termination, không làm path routing.

yaml
apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  type: LoadBalancer
  selector:
    app: my-app
  ports:
    - port: 80
      targetPort: 8080

GCP resources được tạo ra:

  • Forwarding Rule — external IP + port, forward đến backend
  • Backend Service hoặc Target Pool (tùy cluster config) — nhóm các node instances
  • Firewall Rules — cho phép traffic từ health check probes

Data path (legacy instance group): Client → External IP → Forwarding Rule → Node (NodePort) → kube-proxy DNAT → Pod

Data path (NEG-based, GKE 1.17+): Client → External IP → Forwarding Rule → NEG Endpoint (Pod IP:containerPort) → Pod

Điểm quan trọng: với L4 passthrough LB, externalTrafficPolicy: Local giữ nguyên source IP của client (không SNAT), nhưng chỉ forward đến nodes có Pod đang chạy. externalTrafficPolicy: Cluster phân phối đều hơn nhưng mất source IP do SNAT tại node.

Internal LoadBalancer: Thêm annotation cloud.google.com/load-balancer-type: "Internal" để tạo Internal Passthrough Network LB thay vì external. Traffic chỉ accessible trong VPC.

GKE Ingress

Ingress tạo ra một Application Load Balancer (L7) trong GCP. Đây là sự khác biệt cơ bản với LoadBalancer Service: traffic được terminate và forward ở tầng HTTP/HTTPS, không phải tầng TCP.

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.class: "gce"
spec:
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 8080

GCP resources được tạo ra:

  • Forwarding Rule — IP address, port (80, 443)
  • Target HTTP/HTTPS Proxy — xử lý HTTP protocol, làm TLS termination nếu HTTPS
  • URL Map — routing rules từ host+path → backend service
  • Backend Services — một per Service port được tham chiếu trong Ingress
  • Network Endpoint Groups (NEGs) — thay vì instance groups, chứa Pod IP endpoints

Một Ingress có thể route traffic đến nhiều Services khác nhau dựa trên host và path. Đây là lý do Ingress ra đời: thay vì tạo nhiều LoadBalancer Services (mỗi cái một IP), dùng một IP với một Application LB route theo path.

Gateway API

Gateway API (Kubernetes SIG standard, được GKE implement) cũng tạo ra Application Load Balancer (L7) giống Ingress, nhưng với một mô hình resource tách biệt rõ ràng hơn theo roles:

yaml
# Platform/operator: định nghĩa frontend LB
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: external-gateway
spec:
  gatewayClassName: gke-l7-global-external-managed
  listeners:
    - name: https
      port: 443
      protocol: HTTPS
      tls:
        mode: Terminate
        certificateRefs:
          - name: my-cert
---
# Developer: định nghĩa routing rules
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: my-app-route
spec:
  parentRefs:
    - name: external-gateway
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: api-service
          port: 8080

GCP resources được tạo tương tự Ingress: Forwarding Rule → Target Proxy → URL Map → Backend Services → NEGs. Nhưng cách resources này được compose, quản lý, và mở rộng khác căn bản.

So sánh ba cơ chế theo chiều kỹ thuật

ChiềuLoadBalancer ServiceIngress (Legacy)Gateway API (Recommended)
OSI LayerL4 (TCP/UDP)L7 (HTTP/HTTPS)L7 (HTTP/HTTPS)
GCP LB typePassthrough Network LBApplication LBApplication LB
TLS terminationKhông (passthrough)Có (tại GFE hoặc Envoy)Có (tại GFE hoặc Envoy)
Path routingKhông
Header matchingKhôngKhông
Traffic splittingKhôngKhôngCó (theo weight)
ScopeMột ServiceNhiều ServicesNhiều Services
IP per resourceMột IP per ServiceMột IP cho toàn IngressMột IP per Gateway
StatusActiveMaintenance modeRecommended
Role separationKhôngKhôngCó (operator/developer)

Tại sao ba lớp này tồn tại song song

LoadBalancer Service không thể bị Ingress thay thế hoàn toàn

Ingress và Gateway chỉ hỗ trợ HTTP và HTTPS traffic. Nếu bạn cần expose một dịch vụ TCP thuần (ví dụ: PostgreSQL, gRPC qua TCP thẳng, custom protocol), LoadBalancer Service là lựa chọn duy nhất trong GKE. Gateway API có spec cho TCPRoute nhưng GKE chưa hỗ trợ — theo docs hiện tại, GKE Gateway chỉ hỗ trợ HTTPRoute.

Ingress đang ở maintenance mode

Theo tài liệu chính thức của Google: "GKE Ingress is in maintenance mode. No new functionality will be added except as needed to fix bugs." Điều này có nghĩa Ingress vẫn hoạt động và được support, nhưng mọi tính năng mới sẽ chỉ được thêm vào Gateway API. Cho các hệ thống mới, luôn dùng Gateway API.

Gateway API không phải chỉ là "Ingress v2"

Gateway API có một thiết kế khác về mặt tổ chức: role separation. Với Ingress, một người phải quản lý cả frontend (IP, TLS, ports) lẫn routing rules. Với Gateway API:

  • Cluster operator tạo GatewayClassGateway — quyết định loại LB, IP, TLS
  • Application developer tạo HTTPRoute — quyết định routing rules cho app của mình
  • Hai roles này có thể thuộc hai team/namespace khác nhau và không can thiệp lẫn nhau

Đây là enabler quan trọng cho self-service platform model: operator một lần setup Gateway, developer nhiều teams tự attach HTTPRoutes vào.

Framework quyết định

Câu hỏi 1: Traffic có phải HTTP/HTTPS không?
  └── Không → Service type: LoadBalancer
  └── Có → Câu hỏi 2

Câu hỏi 2: Cần routing theo path/header/weight không?
  └── Không, một service đơn giản → LoadBalancer Service (đơn giản hơn)
  └── Có → Câu hỏi 3

Câu hỏi 3: Hệ thống mới hay cần maintain legacy?
  └── Hệ thống mới → Gateway API
  └── Legacy đang dùng Ingress → Giữ Ingress, migrate dần sang Gateway

Câu hỏi 4 (cho Gateway API): Cần tách role operator/developer không?
  └── Platform model, nhiều teams → Shared Gateway + per-team HTTPRoutes
  └── Single team → Self-managed Gateway

Cơ chế chia sẻ: NEG

Dù chọn Ingress hay Gateway API, GCP infrastructure bên dưới đều sử dụng Network Endpoint Groups (NEGs) để kết nối với Pod endpoints. NEG là khái niệm then chốt giải thích tại sao traffic đi thẳng đến Pod thay vì đi qua node → kube-proxy như mô hình cũ.

Container-native load balancing với NEGs cho phép:

  • Health check trực tiếp tại Pod level (không qua node)
  • Traffic đến thẳng Pod IP, không thêm hop
  • Pod readiness trở thành gate cho traffic routing

Hiểu NEG là điều kiện tiên quyết để hiểu tại sao Ingress hay Gateway hoạt động như vậy. Xem chi tiết tại Chương 05: Container-native LB & NEG Internals.

References