服務Mesh和流量策略
1)為什麼需要Service Mesh
Service Mesh是用於東西方流量(服務間通信)的基礎架構層,可在不重寫代碼的情況下提供統一的功能:- 默認安全性:mTLS,自動簽發/輪換證書,服務標識。
- 流量策略:L7路由,金絲雀/AV測試,退化和可持續性。
- 可觀察性:度量,邏輯,跟蹤,每個呼叫中的黃金信號。
- 操作:所有語言/框架的統一策略。
與API網關的區別:網關是南北外圍;mesh是集群/組織內的東西方。經常一起工作。
2)體系結構: 平面和模式
Data Plane: sidecar代理(Envoy/Linkerd-proxy/haproxy),攔截poda/VM流量。
控制平面:分配配置(路由、策略、證書)、存儲狀態、發布服務折扣。
身份:通常是SPIFFE ID和自動X.509證書(SPIRE/嵌入式 CA)。
入口/出口點:ingress/egress-gateway用於邊界流控制。
實施模式:每個下方的sidecar;新實現中的節點/環境模式。
3)安全政策與零信任
1.mTLS by default:加密和相互驗證servis↔servis。
2.AuthN/AuthZ:
AuthN:我們只信任CA mesh'a(SPIFFE)簽發的身份。
AuthZ:聲明規則「誰可以成為誰」(RBAC/ABAC)。
3.隔離和egress控制:
允許的域/子網;通過egress-gateway強制退出。
阻止pod的直接結果。
4.秘密輪換:短壽命證書,自動代理重新配置。
Istio(示例:全局mTLS嚴格):yaml apiVersion: security. istio. io/v1beta1 kind: PeerAuthentication metadata: { name: default, namespace: istio-system }
spec:
mtls: { mode: STRICT }
Istio(示例:僅允許gRPC上的inventory→billing):
yaml apiVersion: security. istio. io/v1beta1 kind: AuthorizationPolicy metadata: { name: billing-allow, namespace: prod }
spec:
selector: { matchLabels: { app: billing } }
rules:
- from:
- source: { principals: ["spiffe://corp. local/ns/prod/sa/inventory"] }
to:
- operation: { ports: ["8080"], methods: ["POST"], paths: ["/proto. Billing/"] }
4)流量策略: 可持續性和路由
4.1 Taymauts和retrai
Timeouts:一定要調用(connect/read/overall)。
Retries:僅用於等效操作;backoff+jitter;超時限制。
Istio (VirtualService):
yaml apiVersion: networking. istio. io/v1beta1 kind: VirtualService metadata: { name: orders }
spec:
hosts: ["orders"]
http:
- route:
- destination: { host: orders, subset: v1, port: { number: 8080 } }
timeout: 5s retries:
attempts: 2 perTryTimeout: 2s retryOn: "5xx,connect-failure,reset"
4.2 Circuit Breaker и outlier detection
CB:通過保護apstrims來限制同時查詢/連接。
Outlier:推翻錯誤/潛伏的「壞」實例。
Istio (DestinationRule):
yaml apiVersion: networking. istio. io/v1beta1 kind: DestinationRule metadata: { name: orders }
spec:
host: orders trafficPolicy:
connectionPool:
http: { http1MaxPendingRequests: 1024, maxRequestsPerConnection: 100 }
outlierDetection:
consecutive5xxErrors: 5 interval: 5s baseEjectionTime: 30s maxEjectionPercent: 50
4.3金絲雀和按條件
重量:按權重v1/v2劃分流量。
基於頭部:標誌/cookie/tenant →滾動到新版本。
Session affinity:按鍵哈希(整齊縮放)。
yaml http:
- match: [{ headers: { "x-experiment": { exact: "new" } } }]
route: [{ destination: { host: orders, subset: v2 } }]
- route:
- destination: { host: orders, subset: v1, weight: 90 }
- destination: { host: orders, subset: v2, weight: 10 }
4.4 Fault Injection和退化
為穩定性測試和SLO註入延遲/錯誤。
yaml fault:
delay: { fixedDelay: 300ms, percentage: { value: 10 } }
abort: { httpStatus: 503, percentage: { value: 1 } }
5)網絡邊界: ingress/egress和外部服務
Ingress-gateway:mesh中外部客戶的唯一切入點;與WAF/OIDC/ratelimits集成。
Egress-gateway:帶有允許主機列表的中央出口,TLS檢查,遙測記錄。
ServiceEntry:將外部SNI/主機聲明為 mesh的一部分(策略和mTLS起源適用)。
yaml apiVersion: networking. istio. io/v1beta1 kind: ServiceEntry metadata: { name: payments-external }
spec:
hosts: ["api. payments. com"]
ports: [{ number: 443, name: https, protocol: TLS }]
resolution: DNS location: MESH_EXTERNAL
6)多群集,多網絡和混合體
通用PKI/托管域:群集之間的單個SPIFFE身份。
端點發現:區域之間的服務球;本地優先級和failover。
區域隔離:區域政策、限制和優先事項。
Mesh中的VM:將傳統/靜態系統連接到代理和相同的策略。
7)可觀察性,SLO和操作
Метрики: `requests_total`, `request_duration_ms{p50,p95,p99}`, `5xx_rate`, `retry_attempts`, `cb_state`, `mTLS_authz_denied`.
訪問日誌:結構性,帶有「traceparent」、「user/tenant」、「response_flags」。
Tracing:自動標頭註入(W3C Trace Context), sampling,在hop級別上演唱。
SLO:p99目標/路線錯誤(service→service)。
Alerts: 「5xx」激增、「reset」增長、「outlier_ejections」、mTLS降解(handshake failures)。
8)生產力和成本
Sidecar添加開銷(CPU/RAM/latency)。我們優化:- 顆粒性:在需要的地方納入政策;不包括任何地方的重型過濾器。
- 池:將路徑(臨界/背景)分為不同的路線和限制。
- 剖析:「冷」路線上的p99,遙測量(rate-limit log/trays)。
- 如果支持並且符合要求,請考慮環境/無障礙模式。
9)安全和合規性
最起碼的訪問:明確允許方向和方法。
Neimspace/tenant策略:網絡/授權邊界。
鑰匙輪換/SA:計劃和緊急情況;TTL證書短。
PII/秘密:在日誌/預告片中掩蓋;電線/靜止加密。
審計:誰改變了政策,何時改變了政策;兩步的啟示。
10)與K8S級集成
Mesh策略是對NetworkPolicy的補充而不是替代。
在ingress/egress-gateway中,可以將PodSecurity/PSA掛在下面的級別。
NRA/自動滑行:考慮回程/SV-它們改變負載。
發布計劃:通過VirtualService+自動升級到SLO的金絲雀權重。
11)實施支票
- 已定義信任邊界並啟用STRICT mTLS。
- 包括AuthZ策略:誰在誰,在哪個端口/方法上。
- 定制timeouts/retries和outlier檢測,定義了偶數路徑。
- 規定了金絲雀路線和滾回計劃;fault injection-僅在非程序中。
- 通過egress-gateway和ServiceEntry進行外部依賴。
- 設置指標,標誌,路線;dashbords和alertes在p99/5xx/CB。
- 規定了per-tenant/namespace配額/限額。
- 準備運行手冊:證書泄漏,CA故障,apstrim降解,質量503/RESET。
- 多類計劃(通用PKI,本地優先級,DR腳本)。
- 測試日(遊戲日):控制平面下降,中途停止,網絡破裂,「有毒」消失。
12)反模式
Mesh「無處不在」,沒有路線清單,SLO →昂貴的復雜性。
默認情況下,retrai用於→效果和流量雪崩。
斷開連接的mTLS「暫時」→永遠存在。
沒有網關的Egress →數據泄漏/未報告的依賴關系。
所有服務的一個全球政策→假安全和假陽性。
零觀察力:打開了mesh,但我們沒有收集指標/步伐-我們失去了意義。
13)快速食譜
Linkerd: 啟用mTLS和跨服務器的策略
yaml apiVersion: policy. linkerd. io/v1beta1 kind: Server metadata: { name: billing, namespace: prod }
spec:
podSelector: { matchLabels: { app: billing } }
port: 8080 apiVersion: policy. linkerd. io/v1beta1 kind: ServerAuthorization metadata: { name: billing-allow-inventory, namespace: prod }
spec:
server: { name: billing }
client:
meshTLS:
identities: ["inventory. prod. serviceaccount. identity. linkerd. cluster. local"]
Consul (L7 intent + splitter)
hcl
Kind = "service-router"
Name = "orders"
Routes = [{
Match { HTTP { PathPrefix = "/v1" } }
Destination { Service = "orders" }
}]
Kind = "service-splitter"
Name = "orders"
Splits = [
{ Weight = 90, ServiceSubset = "v1" },
{ Weight = 10, ServiceSubset = "v2" }
]
14) FAQ
需要一個小團隊嗎?
如果3-5服務-更常見的是沒有。從良好的ingress和可持續性庫開始。當需要默認的mTLS、單一策略和跟蹤時,無需更改代碼,即可連接mesh。
如何控制成本?
在關鍵路徑上測量開銷(CPU/RAM/latency),禁用多余的過濾器,減少登錄量/跟蹤量,在安全的情況下使用無側面模式。
mesh和手動配置的代理是否可能受到幹擾?
是的,但避免雙重路由/重復轉發。一個地方是真實的-控制飛機。
更重要的是: 安全性或性能?
默認情況下為安全性(mTLS、AuthZ)。通過調整連接池,outlier檢測和目標路由來實現性能。
15)結果
Service Mesh將服務之間的網絡轉換為具有統一策略的可編程層:加密和身份,精細路由和可持續性,遙測和配額。從關鍵路徑開始,包括STRICT mTLS和顯式AuthZ,設置計時器/retrai/SV,控制egress,測量p99和5xx,進行遊戲日。然後,mesh將成為可靠性和發行速度的放大器,而不是意外的來源。