Sau bài này bạn làm được: cấu hình Ingress route HTTP theo host/path; hiểu Gateway API và khi nào chuyển từ Ingress sang; cấu hình TLS với cert-manager.


Vấn đề: expose nhiều service qua 1 IP

LoadBalancer Service tạo 1 LB per service → 10 service = 10 LB = 10 IP = 10× chi phí.

Ingress (và Gateway API) cho phép 1 LB route traffic tới nhiều service dựa trên hostpath.

[Internet]
[Cloud LB] ← 1 IP, 1 LB
[Ingress Controller (nginx/traefik)]
    ├── Host: api.example.com   → Service: my-api
    ├── Host: web.example.com   → Service: my-web
    └── Path: /admin            → Service: admin-panel

Ingress

Ingress resource vs Ingress controller

  • Ingress resource: YAML bạn viết, khai báo routing rules.
  • Ingress controller: pod thực sự xử lý traffic (nginx, traefik, HAProxy, AWS ALB…). Phải cài riêng — Kubernetes không có sẵn.

Ingress spec cơ bản

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx          # Chỉ định controller
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-api
            port:
              number: 80
  - host: web.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-web
            port:
              number: 80

pathType

TypeHành vi
PrefixMatch prefix: /api match /api, /api/users, /api/
ExactMatch chính xác: /api chỉ match /api
ImplementationSpecificTuỳ controller

TLS termination

spec:
  tls:
  - hosts:
    - api.example.com
    secretName: api-tls-cert       # Secret chứa cert + key
  rules:
  - host: api.example.com
    # ...

Cert lưu trong Secret type kubernetes.io/tls:

kubectl create secret tls api-tls-cert \
  --cert=tls.crt --key=tls.key

Tự động với cert-manager: chi tiết → Mạng bài 13 — TLS tự động với cert-manager.

metadata:
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - api.example.com
    secretName: api-tls-cert    # cert-manager tự tạo + renew

Annotations phổ biến (nginx-ingress)

annotations:
  nginx.ingress.kubernetes.io/ssl-redirect: "true"
  nginx.ingress.kubernetes.io/proxy-body-size: "10m"
  nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
  nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com"
  nginx.ingress.kubernetes.io/rate-limit-rps: "10"

Vấn đề: annotations là controller-specific, không portable. Đây là lý do Gateway API ra đời.


Gateway API (GA v1.0+)

Gateway API là tiêu chuẩn mới thay thế Ingress, giải quyết các giới hạn:

  • Annotations không portable → typed config trong spec.
  • Ingress chỉ hỗ trợ HTTP → Gateway API hỗ trợ TCP, UDP, gRPC, TLS passthrough.
  • Không phân quyền rõ → Gateway API tách role: infra admin vs app developer.

Kiến trúc 3 tầng

┌──────────────────────────────────┐
│  GatewayClass (infra provider)   │  ← Ai cung cấp LB (nginx, Cilium, AWS...)
└──────────────────────────────────┘
┌──────────────────────────────────┐
│  Gateway (platform team)         │  ← Listener: port, protocol, hostname, TLS
└──────────────────────────────────┘
┌──────────────────────────────────┐
│  HTTPRoute (app team)            │  ← Path/header routing, backend refs
└──────────────────────────────────┘

GatewayClass

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

Tương tự IngressClass. Thường do infra team hoặc addon cài sẵn.

Gateway

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: main-gateway
  namespace: infra
spec:
  gatewayClassName: nginx
  listeners:
  - name: https
    port: 443
    protocol: HTTPS
    hostname: "*.example.com"
    tls:
      mode: Terminate
      certificateRefs:
      - kind: Secret
        name: wildcard-cert
    allowedRoutes:
      namespaces:
        from: All              # Cho phép HTTPRoute từ mọi namespace

HTTPRoute

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: api-route
  namespace: default           # App team namespace
spec:
  parentRefs:
  - name: main-gateway
    namespace: infra
  hostnames:
  - api.example.com
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /v1
    backendRefs:
    - name: my-api-v1
      port: 80
  - matches:
    - path:
        type: PathPrefix
        value: /v2
    backendRefs:
    - name: my-api-v2
      port: 80

Traffic splitting (canary)

rules:
- backendRefs:
  - name: my-api-v1
    port: 80
    weight: 90                 # 90% traffic
  - name: my-api-v2
    port: 80
    weight: 10                 # 10% canary

Header-based routing

rules:
- matches:
  - headers:
    - name: X-Canary
      value: "true"
  backendRefs:
  - name: my-api-v2
    port: 80

Hai tính năng trên trong Ingress đòi hỏi annotations riêng biệt theo controller — Gateway API có sẵn trong spec.


Ingress vs Gateway API

Khía cạnhIngressGateway API
StatusStable, widely deployedGA v1.0 (2023), adoption tăng
Configannotations (non-portable)Typed spec (portable)
ProtocolHTTP/HTTPS onlyHTTP, TCP, UDP, gRPC, TLS
Role separationKhôngGatewayClass (infra) → Gateway (platform) → Route (app)
Traffic splittingAnnotation-dependentNative weight
Header routingAnnotation-dependentNative matches.headers

Khi nào chọn cái nào

  • Ingress: cluster đã có, team quen, không cần tính năng nâng cao → giữ nguyên.
  • Gateway API: project mới, cần traffic splitting/header routing, multi-team cluster (cần role separation), hoặc non-HTTP protocol.
  • Migration: có thể chạy song song — Ingress và Gateway API trên cùng controller (nginx, Cilium hỗ trợ cả hai).

Debug Ingress/Gateway

# Ingress controller logs
kubectl -n ingress-nginx logs -l app.kubernetes.io/name=ingress-nginx

# Ingress status (address?)
kubectl get ingress my-ingress
# NAME         CLASS   HOSTS             ADDRESS         PORTS   AGE
# my-ingress   nginx   api.example.com   203.0.113.10    80,443  5m

# Nếu ADDRESS trống: controller chưa cài, hoặc LB chưa provision

# Gateway status
kubectl get gateway main-gateway
kubectl describe gateway main-gateway    # Xem conditions

# HTTPRoute status
kubectl describe httproute api-route     # Xem parentRef accepted?

Checklist khi traffic không vào

  1. DNS trỏ tới đúng IP (Ingress ADDRESS hoặc Gateway external IP)?
  2. Ingress controller/Gateway pod đang chạy?
  3. Service backend có endpoints? (kubectl get endpoints)
  4. TLS cert valid? (curl -v https://... kiểm tra cert chain)
  5. Path/host match đúng?
  6. NetworkPolicy có chặn traffic từ controller tới pod không? (bài 10)

Tóm tắt

  • Ingress: 1 LB cho nhiều service, route theo host/path. Cần cài controller riêng.
  • Gateway API: tiêu chuẩn mới, typed config, hỗ trợ traffic splitting/header routing native, phân quyền rõ ràng.
  • TLS: dùng cert-manager tự động renew. Secret type kubernetes.io/tls.
  • Chạy song song Ingress + Gateway API khi migration.

Câu hỏi hay gặp

Ingress controller cài ở đâu? Có sẵn trong K8s không?

Trả lời: Không có sẵn. Bạn phải cài riêng: helm install ingress-nginx ingress-nginx/ingress-nginx hoặc tương đương. Trên managed K8s (EKS, GKE, AKS), cloud thường có addon hoặc controller riêng.

Gateway API có thay thế Ingress hoàn toàn không?

Trả lời: Về lâu dài, . Nhưng hiện tại (2026) Ingress vẫn stable và không bị deprecated. Migration không bắt buộc. Kubernetes SIG Network khuyến khích project mới dùng Gateway API.

Nhiều Ingress resource cùng host có conflict không?

Trả lời: Tuỳ controller. Nginx-ingress merge rules cùng host. Nếu path overlap → rule đầu tiên (theo creation time) thắng. Gateway API xử lý rõ ràng hơn: HTTPRoute có sectionName chỉ định listener cụ thể.


Bài tiếp theo (Giai đoạn III): Network Policy — kiểm soát traffic — ai được nói chuyện với ai trong cluster.