Vấn đề mesh giải quyết
Sau khi có Kubernetes Service và Ingress (bài 10), traffic bắc-nam (north-south: vào/ra cluster) đã có LB và TLS. Nhưng traffic đông-tây (east-west: giữa service trong cluster) vẫn thiếu:
| Nhu cầu | K8s thuần | Service Mesh |
|---|---|---|
| Retry / timeout giữa service | Phải code trong app | Proxy tự xử lý |
| mTLS service-to-service | Phải tự cấu hình cert | Mesh cấp cert tự động |
| Circuit breaker | Phải dùng lib (Hystrix, Resilience4j) | Proxy tự xử lý |
| Traffic split (canary) | Ingress routing đơn giản | Fine-grained policy |
| Observability east-west | Tự instrument | Tự động từ proxy |
Kiến trúc: sidecar + control plane
container proxy (Envoy / Linkerd-proxy) - sidecar
│ (nhận cert, cấu hình route, auth policy)
▼
Control Plane (istiod / Linkerd control plane)Data plane: sidecar proxy trên từng Pod, xử lý gói tin thực sự.
Control plane: phát policy và chứng chỉ, nếu down, traffic vẫn chạy theo config hiện tại, nhưng policy mới không được đẩy xuống.
mTLS, xác thực lẫn nhau
Mặc định HTTP giữa Pod không mã hóa. Mesh phát SVID (SPIFFE identity, thường là cert ngắn hạn) cho mỗi workload và enforce mTLS:
Service A (cert: spiffe://cluster/ns/default/sa/api)
│ (TLS mutual authentication (mTLS))
▼
Service B (cert: spiffe://cluster/ns/default/sa/db)Kết quả: chỉ workload được chứng nhận mới nói chuyện được, giảm blast radius nếu Pod bị compromise.
Bật mTLS strict và giới hạn truy cập bằng AuthorizationPolicy trong Istio
# Bắt buộc mTLS trong namespace
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: production
spec:
mtls:
mode: STRICT
---
# Cho phép service A gọi service B
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-api-to-db
namespace: production
spec:
selector:
matchLabels:
app: db
rules:
- from:
- source:
principals: ["cluster.local/ns/production/sa/api"]
Retry, timeout và circuit breaker (không cần code trong app)
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-api
spec:
http:
- retries:
attempts: 3
perTryTimeout: 2s
retryOn: "5xx,reset,connect-failure"
timeout: 10s
route:
- destination:
host: my-api
Cảnh báo: retry + timeout không đúng có thể gây retry storm, khi downstream đã quá tải, upstream retry tiếp thêm áp lực.
Thế hệ mesh 2025, không chỉ còn sidecar
Trước đây sidecar (Istio, Linkerd) là mô hình mặc định, nhưng chi phí RAM/CPU và phức tạp vận hành khiến cộng đồng tìm phương án nhẹ hơn. Ba trường phái chính hiện nay:
Istio ambient mesh (GA, Istio 1.24, 11/2024)
Istio giới thiệu ambient mode, bỏ sidecar, dùng hai lớp:
- ztunnel (DaemonSet trên mỗi node): xử lý mTLS L4 cho mọi Pod.
- Waypoint proxy (Deployment per-namespace hoặc per-service): xử lý L7 (retry, AuthorizationPolicy trên header) khi cần.
Pod A (không sidecar)
│ (plain TCP tới ztunnel cục bộ)
▼
ztunnel (node A)
│ (đường hầm HBONE: HTTP CONNECT qua mTLS)
▼
ztunnel (node B)
│
▼
Pod B (không sidecar)Ưu: app không cần inject, RAM tiết kiệm đáng kể, upgrade data plane không restart Pod. Nhược: L7 policy phải triển khai waypoint riêng (đồng nghĩa thêm Deployment + resource planning); multi-cluster ambient vẫn đang hoàn thiện.
Trạng thái tính năng (Istio 1.24, 04/2026):
| Tính năng | Trạng thái |
|---|---|
| L4 mTLS (ztunnel) | Stable |
| L7 policy (waypoint) | Stable |
| Multi-cluster | Beta |
| Egress gateway ambient | Alpha |
Ghi chú phiên bản: kiểm tra Istio release notes cho trạng thái mới nhất. Ambient GA từ 1.24 nhưng các sub-feature có maturity khác nhau.
Linkerd, nhẹ, đơn giản
Linkerd giữ mô hình sidecar nhưng viết proxy bằng Rust (không dùng Envoy) → RAM ~10–20MB/sidecar thay vì ~50–100MB của Envoy. Triết lý “less is more”: không có custom CRD phức tạp, ít tính năng hơn Istio nhưng dễ vận hành; phù hợp team nhỏ.
Cilium Service Mesh (sidecar-less bằng eBPF)
Cilium dùng eBPF làm data plane mesh ngay trong kernel, không sidecar, không DaemonSet proxy cho L4 mTLS (WireGuard hoặc IPsec); tuỳ chọn Envoy DaemonSet per-node khi cần L7. Ưu: hiệu năng cao, tận dụng CNI đã có; nhược: tính năng L7 còn giới hạn so với Istio full-feature.
Chọn mesh nào (2025–2026):
| Tình huống | Gợi ý |
|---|---|
| Team nhỏ, cần mTLS + observability cơ bản | Linkerd |
| Đã dùng Cilium CNI | Cilium Service Mesh |
| Cần nhiều policy L7 phức tạp, multi-cluster | Istio ambient |
| Chỉ cần mTLS giữa một vài service | SPIFFE/SPIRE + cert-manager (không mesh) |
Gateway API và GAMMA, mesh + ingress hội tụ
GAMMA (Gateway API for Mesh Management and Administration) mở rộng Gateway API (đã GA từ v1.1, 2024) để cấu hình cả traffic east-west (mesh), không chỉ north-south (ingress):
# HTTPRoute cho east-west traffic (GAMMA)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-retry
spec:
parentRefs:
- kind: Service # Không cần Gateway resource
name: my-api
rules:
- matches:
- path: { type: PathPrefix, value: / }
backendRefs:
- name: my-api
port: 8080
timeouts:
request: 10s
# retry và traffic split cũng dùng HTTPRoute
Ý nghĩa: thay vì học CRD riêng của Istio (VirtualService, DestinationRule), có thể dùng một API chuẩn cho cả ingress và mesh. Istio 1.24+, Linkerd 2.15+, Cilium 1.16+ đã hỗ trợ GAMMA.
Migration: sidecar → ambient
Với cluster đang chạy Istio sidecar, chuyển sang ambient từng bước:
- Upgrade Istio lên 1.24+ và bật ambient profile.
- Namespace-by-namespace: gán label
istio.io/dataplane-mode=ambientcho namespace test trước. - Xóa sidecar injection label (
istio-injection=enabled) → pod mới không có sidecar, ztunnel xử lý mTLS. - Triển khai waypoint nếu namespace cần L7 policy (đa số chỉ cần L4 mTLS).
- Theo dõi metric: so sánh latency, error rate trước/sau. Ambient thường giảm p99 latency nhờ bỏ proxy hop.
- Rollback dễ: xóa label ambient, thêm lại sidecar injection → restart pod.
Chi phí waypoint: mỗi waypoint là Envoy Deployment (CPU/memory riêng). Namespace ít L7 policy → không cần waypoint → tiết kiệm đáng kể so với sidecar-per-pod.
Khi nào KHÔNG cần service mesh
Mesh thêm độ phức tạp vận hành đáng kể:
- Mỗi Pod thêm ~50–100MB RAM cho sidecar (Istio sidecar classic, Envoy); Linkerd ~10–20MB; ambient/Cilium gần như không có overhead per-Pod.
- Debug khó hơn: thêm proxy hop, trace phức tạp hơn.
- Upgrade mesh = rủi ro outage (đặc biệt upgrade CRD và data plane cùng lúc).
- Control plane là điểm tập trung quan trọng, cần HA, monitor riêng.
Không nên dùng mesh khi:
- Số service < 10–20 và team nhỏ.
- Không có yêu cầu zero-trust security (mTLS).
- Đã đủ resilience bằng library trong app (retry, timeout).
Nên cân nhắc mesh khi:
- Nhiều service, nhiều team, cần policy east-west thống nhất.
- Compliance yêu cầu encryption in-transit giữa service.
- Canary/traffic split phức tạp (A/B test bằng header, weight).
Tóm tắt
- Mesh giải quyết east-west traffic: mTLS, retry, circuit breaker, observability, không cần code trong app.
- Sidecar model: mọi traffic in/out của Pod đi qua proxy.
- mTLS chứng thực workload identity, khác với TLS user-facing.
- Cân nhắc kỹ trade-off trước khi adopt: mesh tốt cho hệ thống lớn, overkill cho team nhỏ.
- GAMMA (Gateway API for mesh), API chuẩn thay CRD riêng; Istio, Linkerd, Cilium đã hỗ trợ.
- Migration sidecar → ambient: từng namespace, theo dõi metric, rollback dễ.
Câu hỏi hay gặp
Istio control plane (istiod) down, traffic đang chạy có chết không?
Trả lời: Data plane (Envoy) thường vẫn forward với config đã nhận; mất cập nhật policy/cert mới. Ngắt hoàn toàn tùy cấu hình và phiên bản, không coi CP down là “an toàn để deploy”.
STRICT mTLS, Pod C không có sidecar gọi Pod B, được không?
Trả lời: Thường không, B mong đợi TLS/mTLS từ mesh, C không đáp ứng. Cần inject sidecar, exception policy, hoặc plaintext port riêng (ít khuyến khích).
Retry 3×2s khi downstream đang quá tải, rủi ro gì?
Trả lời: Retry storm: nhân đôi số request lên service đang gục, làm sập nhanh hơn. Cần retry budget, circuit breaker, jitter.
Quay lại Giai đoạn IV: VPC và mạng trên cloud, từ trong cluster nhìn ra cloud provider.