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ầuK8s thuầnService Mesh
Retry / timeout giữa servicePhải code trong appProxy tự xử lý
mTLS service-to-servicePhải tự cấu hình certMesh cấp cert tự động
Circuit breakerPhải dùng lib (Hystrix, Resilience4j)Proxy tự xử lý
Traffic split (canary)Ingress routing đơn giảnFine-grained policy
Observability east-westTự instrumentTự độ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ăngTrạng thái
L4 mTLS (ztunnel)Stable
L7 policy (waypoint)Stable
Multi-clusterBeta
Egress gateway ambientAlpha

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ốngGợi ý
Team nhỏ, cần mTLS + observability cơ bảnLinkerd
Đã dùng Cilium CNICilium Service Mesh
Cần nhiều policy L7 phức tạp, multi-clusterIstio ambient
Chỉ cần mTLS giữa một vài serviceSPIFFE/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:

  1. Upgrade Istio lên 1.24+ và bật ambient profile.
  2. Namespace-by-namespace: gán label istio.io/dataplane-mode=ambient cho namespace test trước.
  3. Xóa sidecar injection label (istio-injection=enabled) → pod mới không có sidecar, ztunnel xử lý mTLS.
  4. Triển khai waypoint nếu namespace cần L7 policy (đa số chỉ cần L4 mTLS).
  5. Theo dõi metric: so sánh latency, error rate trước/sau. Ambient thường giảm p99 latency nhờ bỏ proxy hop.
  6. 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.