Istio服務網格:為忙碌人士而生
我最近為Istio做出了一個小貢獻,Istio 是一個開源服務網格項目。我的貢獻包括為 Istio CLI 的一個命令添加了一些測試。如果你想查看詳細信息,可以在此處找到 pull 請求。這不是一個巨大的改變,但它是一個很棒的學習體驗。在 Istio 上工作幫助我更深入地理解了服務網格。我很高興能做出更多貢獻。在這篇文章中,我將解釋什么是 Istio,它為什么有用以及它是如何工作的。
譯自The Istio Service Mesh for People Who Have Stuff to Do | Blog,作者 Luca Cavallin。
從本質上講,Istio 是一個服務網格。服務網格管理微服務之間的通信,負責處理諸如路由流量、保護通信和提供可觀測性等事項。隨著微服務數量的增長,管理這些交互會變得很復雜。Istio 自動執行許多這些任務,因此你可以專注于構建應用程序,而不是管理服務之間的通信。
為什么要使用 Istio?
隨著架構變得越來越復雜,你將面臨新的挑戰。服務需要以可靠、安全和高效的方式進行通信。Istio 幫助你在三個關鍵領域做到這一點:
- 管理流量: Istio 使你能夠控制流量在服務之間如何流動。你可以將流量拆分到服務的不同版本之間,在部署期間重新路由請求,或者設置重試和超時策略。保護通信: Istio 使啟用
- 雙向 TLS (mTLS)變得容易。這確保了服務之間所有通信都是加密和經過身份驗證的,從而阻止未經授權的服務。
- 可觀測性: Istio 自動收集指標、日志和跟蹤,使你能夠實時了解你的服務。這有助于監控、故障排除和性能調整。
這三個領域——流量管理、安全性和可觀測性——是運行健康微服務架構的關鍵,Istio 可以輕松地處理它們。
使用 Istio 管理流量
Istio 的主要功能之一是管理服務之間的流量。在微服務設置中,你可能有多個版本的同一個服務同時運行。例如,你可能正在測試支付服務的最新版本,并希望將大部分流量發送到版本 1,但將一些流量路由到版本 2。
以下是如何使用 Istio 將流量拆分到服務的兩個版本之間的示例:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: payments
spec:
hosts:
- payments.myapp.com
http:
- route:
- destination:
host: payments
subset: v1
weight: 90
- destination:
host: payments
subset: v2
weight: 10
在這個例子中:
- 90% 的流量被發送到payments服務的版本 1,而10%被發送到版本 2。
- hosts字段指定虛擬服務適用的域——在本例中為payments.myapp.com。
- route塊定義了流量如何在服務的兩個子集中進行拆分:v1(版本 1)和v2(版本 2)。weight字段控制流量分配。
這對于金絲雀部署非常有用,在金絲雀部署中,你可以使用一小部分用戶測試新功能,然后再完全推出。
Envoy 代理和 Sidecar 容器
Istio 的數據平面依賴于Envoy 代理,Envoy 代理是一個第 7 層代理,它管理服務之間所有流量。網格中的每個服務都有自己的Sidecar 代理,它位于服務旁邊,并管理其所有入站和出站流量。
Envoy 允許你應用流量策略,例如重試、超時和斷路器,所有這些都無需更改應用程序代碼。它還收集有關流量流的詳細指標,有助于監控和調試。
由于 Envoy 作為Sidecar 容器運行,因此它可以在不干擾應用程序邏輯的情況下執行這些規則并收集數據。簡而言之,Envoy 充當服務網格中所有通信的“交通警察”。
可觀測性:了解系統中發生的事情
運行一個包含許多微服務的系統可能會讓你難以了解正在發生的事情。Istio 的內置可觀測性功能可以幫助你跟蹤服務之間所有通信的指標、日志和跟蹤。這對于監控系統的運行狀況、發現性能問題和修復錯誤至關重要。
Istio 的可觀測性工具可以讓你清楚地了解系統的工作方式。你可以及早發現問題,并使你的服務運行得更加順暢。
安全:啟用 mTLS 和訪問控制
安全是管理微服務時的一大問題。Istio 使實施雙向 TLS (mTLS)變得容易,雙向 TLS (mTLS) 會加密服務之間的所有通信,并確保服務在交換數據之前相互驗證身份。
Istio 還允許您設置訪問控制策略,以指定哪些服務可以進行通信。這有助于限制哪些服務可以交互,從而減少系統的攻擊面。
以下是一個 Istio 策略示例,該策略僅允許billing服務與payments服務通信:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: payments-to-billing
spec:
selector:
matchLabels:
app: payments
rules:
- from:
- source:
principals: ["billing.myapp.com"]
在此策略中:
- selector指定此規則適用于payments服務,使用標簽app: payments。
- rules塊僅允許billing服務(由主體"billing.myapp.com"標識)與payments服務通信。任何其他服務都不允許向payments服務發送流量。
此策略限制除billing服務之外的所有服務訪問payments服務,從而加強了微服務的安全性。
什么是 SPIFFE?
Istio 使用SPIFFE(安全生產身份框架,面向所有人)來管理服務身份。SPIFFE 提供了一種為服務分配安全、可驗證身份的方法。網格中的每個服務都會獲得一個SPIFFE 可驗證身份文檔 (SVID),該文檔與 mTLS 一起使用以確保安全通信。此身份系統是 Istio 安全模型的基礎。
Istio 中的網絡
微服務中的網絡可能很困難,尤其是在控制網格內部和外部的流量時。Istio 提供了幾種管理網絡流量的工具:
- 服務條目: 允許外部服務與網格內部的服務進行通信,反之亦然。
- 虛擬服務: 定義流量如何在網格內部路由。
- 目標規則: 將流量策略(如負載均衡或 mTLS)應用于服務。
- 網關: 管理進出網格的流量。
配置示例:網關、服務條目、虛擬服務和目標規則
假設您在網格中有一個 API 服務器,它通過負載均衡器接收來自互聯網的流量。以下是如何配置網關、服務條目、虛擬服務和目標規則來處理此流量。
網關配置
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: api-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "api.myapp.com"
這里發生了什么?網關在端口 80上監聽來自域api.myapp.com的 HTTP 流量。selector字段將此網關連接到Istio 入口網關,該網關處理進入網格的流量。
服務條目配置
假設您的 API 服務器需要調用外部身份驗證服務。以下是如何配置服務條目:
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: auth-service-entry
spec:
hosts:
- "auth.external-service.com"
location: MESH_EXTERNAL
ports:
- number: 443
name: https
protocol: HTTPS
resolution: DNS
endpoints:
- address: 203.0.113.1
這里發生了什么?服務條目告訴 Istio 如何將流量路由到外部服務 (auth.external-service.com),該服務在端口 443(HTTPS)上運行。location: MESH_EXTERNAL指示此服務存在于 Istio 服務網格之外。endpoints字段包含外部服務的 IP 地址,允許網格內的 API 服務器發送請求。
虛擬服務配置
以下是如何在網格內路由流量:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: api-virtualservice
spec:
hosts:
- "api.myapp.com"
gateways:
- api-gateway
http:
- match:
- uri:
prefix: "/v1"
route:
- destination:
host: api-service
subset: stable
這里發生了什么?虛擬服務定義了流量路由規則。在這種情況下,通過api-gateway到達api.myapp.com/v1的流量將路由到網格中的api-service。subset: stable指的是api-service的特定版本(您可以擁有同一服務的多個版本)。
目標規則配置
最后,以下是一個目標規則,用于應用負載均衡和 mTLS:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: api-destination-rule
spec:
host: api-service
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
tls:
mode: ISTIO_MUTUAL
這里發生了什么?目標規則將策略應用于路由到api-service的流量。它使用輪詢負載均衡將請求均勻地分布到實例中。mTLS通過tls.mode: ISTIO_MUTUAL啟用,確保服務之間加密通信。
彈性:使用重試、超時和斷路器處理故障
在分布式系統中,故障是不可避免的。服務可能會宕機,網絡可能會變慢,或者用戶可能會遇到延遲。Istio 可以幫助您使用重試、超時和斷路器來處理這些問題。
- 重試: 自動重試失敗的請求,以處理臨時故障,而不會影響用戶體驗。
- 超時: 定義服務在放棄并繼續執行之前應等待響應的時間。
- 斷路器: 如果服務出現故障,Istio 可以停止向其發送流量,從而防止可能導致系統其他部分崩潰的級聯故障。
以下是如何在 Istio 中配置重試和超時的示例:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-service
spec:
hosts:
- my-service
http:
- route:
- destination:
host: my-service
retries:
attempts: 3
perTryTimeout: 2s
timeout: 5s
這里發生了什么?如果對my-service的請求失敗,Istio 將最多重試該請求3 次。每次重試嘗試都有2 秒的限制。請求的總允許時間為5 秒。在此之后,Istio 將停止等待響應。
對于斷路,您可以使用類似這樣的目標規則:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: my-service
spec:
host: my-service
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
http1MaxPendingRequests: 50
outlierDetection:
consecutive5xxErrors: 2
interval: 10s
baseEjectionTime: 30s
maxEjectionPercent: 50
這里發生了什么?如果my-service在10 秒內返回兩個連續的 5xx 錯誤,Istio 將停止向其發送流量。該服務將從負載均衡池中剔除30 秒,然后重新考慮。
總結
Istio 是一個強大的工具,它簡化了微服務的流量管理、安全性和可觀測性。為 Istio 做貢獻讓我了解了它如何幫助解決運行分布式系統時遇到的一些復雜挑戰。
如果您正在運行微服務架構或計劃進行擴展,Istio 可以幫助您使系統更具彈性和更易于管理。如果您有任何問題或想了解更多關于 Istio 的信息,請隨時聯系我,我很樂意分享我的經驗。