Ingress là API; controller mới xử lý traffic
Ingress mô tả desired L7 routing, nhưng bản thân object không tạo reverse proxy. Ingress Controller watch Kubernetes API, reconcile rule thành cấu hình data plane và cập nhật status. Với thiết kế mới, Kubernetes khuyến nghị Gateway API; Ingress vẫn GA nhưng API đã frozen.
Request path đầy đủ
Client / DNS
→ cloud Load Balancer hoặc NodePort
→ Ingress Controller data plane (Nginx, Traefik, HAProxy, Envoy...)
→ host/path rule match
→ Service ClusterIP / EndpointSlice
→ ready Pod IP : targetPort
→ application container
Controller có thể chạy dưới dạng Deployment hoặc DaemonSet và được expose bằng Service type LoadBalancer, NodePort hoặc integration riêng của platform. Một thay đổi Ingress/Gateway trước hết đi qua reconciliation; chỉ sau khi data plane nhận config mới thì traffic mới thực sự thay đổi.
Ingress resource tối thiểu
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: banking-web
spec:
ingressClassName: nginx
tls:
- hosts: [bank.example.com]
secretName: bank-tls
rules:
- host: bank.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: banking-api
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: banking-web
port:
number: 80
backend.service.port là Service port, không nhất thiết là container port. Service tiếp tục map port → targetPort. Ingress chuẩn route tới Service trong cùng namespace; nhu cầu cross-namespace nên dùng cơ chế có permission rõ, ví dụ Gateway API với ReferenceGrant, thay vì giả định mọi controller có cùng extension.
IngressClass và controller ownership
ingressClassName xác định controller/class chịu trách nhiệm. Một cluster có thể có public và internal controllers; ownership phải rõ để tránh hai controller cùng reconcile một route hoặc không controller nào nhận route.
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
spec:
controller: k8s.io/ingress-nginx
spec.controller, annotations và feature support phụ thuộc implementation. Annotation của NGINX Ingress không mặc nhiên dùng được cho AWS ALB, Traefik hoặc controller khác. Khi thay controller, hãy coi annotation/config-specific behavior là migration surface cần test.
pathType: Exact, Prefix, ImplementationSpecific
| Type | Ý nghĩa | Cảnh báo |
|---|---|---|
| Exact | Match URL path chính xác, case-sensitive. | /api không tự match /api/orders. |
| Prefix | Match theo path elements; /api match /api/orders. | Phải hiểu boundary segment và test trailing slash. |
| ImplementationSpecific | Controller quyết định semantics. | Regex/rewrite có portability thấp và thường cần extension/annotation. |
Rule precedence, regex, merge và conflict giữa nhiều Ingress objects có thể controller-specific. Với host/path quan trọng, thêm probe cho positive case, negative case, trailing slash và path gần giống để phát hiện route shadowing.
TLS termination và certificate lifecycle
- TLS Secret kiểu
kubernetes.io/tlschứa certificate/key; base64 không phải encryption. - Certificate SAN/SNI,
tls.hostsvà rule host phải nhất quán. - Controller thường terminate TLS rồi proxy HTTP, hoặc re-encrypt tới backend theo config.
- cert-manager có thể tự động issuance/renewal, nhưng issuer, challenge routing, DNS và Secret ownership vẫn phải monitor.
- Rotation cần reload mà không drop traffic; alert trước expiry và khi renewal/reload thất bại.
Headers và client identity
Controller thường thêm Forwarded hoặc X-Forwarded-For/Proto/Host. Application chỉ nên tin các header này khi request đến từ trusted proxy chain; edge phải strip/overwrite header do client tự gửi nếu dùng chúng cho authorization, redirect, audit hoặc rate-limit.
externalTrafficPolicy, proxy protocol và cloud LB behavior có thể thay đổi client IP nhìn thấy ở proxy/app. Sai trust configuration có thể gây redirect loop, insecure cookie, forged audit IP hoặc bypass policy dựa trên source address.
Timeout, buffering, body size và retry
Phần lớn timeout, buffering, body/header limit và retry là controller-specific chứ không phải portable Ingress API. Deadline của proxy phải nằm trong end-to-end latency budget và tương thích với upstream/downstream timeouts.
- Buffering ảnh hưởng streaming, upload latency, memory/disk pressure và backpressure.
- Body/header limit vừa là capacity control vừa là security boundary.
- Timeout quá thấp tạo 504 giả; quá cao giữ connection/resource quá lâu khi backend suy giảm.
- Retry storm có thể khuếch đại incident; giới hạn attempts và tổng retry budget.
Rewrite và SPA routing
Rewrite thay URL trước khi gửi backend; strip prefix sai thường tạo 404 hoặc route nhầm. Với SPA, fallback /index.html nên thuộc static/frontend routing boundary; không rewrite mọi API/asset 404 thành HTML 200 vì sẽ che lỗi thật. Giữ original URI trong access log/tracing để điều tra được request trước và sau rewrite.
Ingress khác Service LoadBalancer thế nào?
| Service LoadBalancer | Ingress | |
|---|---|---|
| Layer | Thường L4 TCP/UDP, tùy provider | L7 HTTP/HTTPS routing |
| Exposure | Mỗi Service có thể cần LB riêng | Một controller/LB có thể route nhiều Services |
| Routing | Port tới một Service | Host/path tới nhiều Services |
| Implementation | Cloud/controller integration | Cần Ingress Controller |
Hai mô hình thường phối hợp: Ingress Controller chính nó có thể được expose bằng một Service LoadBalancer. Vì vậy câu hỏi không phải luôn là “chọn một trong hai”, mà là layer nào chịu trách nhiệm L4 exposure và layer nào chịu trách nhiệm L7 routing.
Gateway API: successor có role model rõ hơn
Kubernetes hiện khuyến nghị Gateway thay vì mở rộng thêm Ingress. Gateway API tách ownership infrastructure và application routing rõ hơn:
GatewayClass → implementation/controller của platform
Gateway → listener, address, TLS; platform team quản
HTTPRoute → host/path/header/backend; app team quản
ReferenceGrant → cho phép cross-namespace reference có chủ đích
HTTPRoute và ReferenceGrant thuộc Standard Channel/GA. Gateway API có typed routes, richer matching, explicit attachment/status và permission model tốt hơn cho cross-namespace references. Tuy vậy, feature support thực tế vẫn phụ thuộc controller/conformance profile, nên phải kiểm tra implementation trước khi migration.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: banking-api
spec:
parentRefs:
- name: public-gateway
hostnames: [bank.example.com]
rules:
- matches:
- path: { type: PathPrefix, value: /api }
backendRefs:
- name: banking-api
port: 8080
weight: 90
- name: banking-api-canary
port: 8080
weight: 10
Debug từ ngoài vào trong
- DNS có resolve đúng LB address? TLS handshake, SNI, certificate và HTTP status là gì?
- Ingress/Gateway đã accepted/programmed chưa? Kiểm tra class, status/conditions, events và controller logs.
- Host/path/pathType có match request thực tế?
- Backend Service tồn tại và Service port name/number đúng?
- EndpointSlice có ready Pod IP và targetPort đúng?
- Pod có listen
0.0.0.0, readiness true và NetworkPolicy cho phép? - Proxy upstream log báo connect timeout, reset, 502, 503 hay 504?
- Application trace/log có nhận request và forwarded headers đúng?
| Symptom | Nghi ngờ đầu tiên | Signal cần xem |
|---|---|---|
| 404 từ controller | Host/path/class/rule hoặc default backend | Matched route, access log, config dump/status |
| 502 | Endpoint/listener/targetPort/protocol/reset | Upstream connect/reset, EndpointSlice |
| 503 | No ready endpoints hoặc upstream unavailable | Ready endpoints, readiness, controller health |
| 504 | Backend chậm hoặc timeout budget sai | Upstream latency, saturation, deadline |
| Redirect loop | Forwarded proto/trust/TLS termination | X-Forwarded-Proto, app redirect log |
| Certificate sai | DNS/SNI/Secret/host/default certificate | Presented cert, secret revision, reload event |
Capacity, security và recovery checklist
- Theo dõi request rate, concurrent connections, p95/p99 latency, 4xx/5xx, upstream connect errors, reload failures và controller CPU/memory.
- Giữ headroom khi một controller replica/node/AZ mất; test pod disruption và LB health-check behavior.
- Giới hạn admin/config endpoints, dùng RBAC least privilege, bảo vệ TLS Secrets và review annotation/extension có khả năng inject config.
- Khi rollout gây lỗi: freeze config changes, rollback route/controller release, restore known-good certificate/config, rồi verify DNS → edge → Service → Pod theo thứ tự.
Câu hỏi phỏng vấn
Tạo Ingress nhưng không truy cập được, vì sao?
IngressClass, controller được expose, status/address sẵn sàng, DNS trỏ đúng, rules match, Service/EndpointSlice/Pods healthy và policy cho phép.