iT邦幫忙

2025 iThome 鐵人賽

DAY 27
0
DevOps

30 天挑戰 CKAD 認證!菜鳥的 Kubernetes 學習日記系列 第 27

【Day27】Istio:為 Kubernetes 叢集裝上導航系統

  • 分享至 

  • xImage
  •  

前情提要

在前兩天的內容中,我們深入研究了 Kustomize,學會了如何透過 Base 和 Overlays 管理多環境配置,以及如何使用 Transformers、Patches 和 Components 來實現更靈活的配置管理。Kustomize 解決了「如何優雅地維護不同環境的配置差異」這個問題,讓我們不需要複製大量 YAML 檔案,也能輕鬆管理開發、測試、生產等多個環境。

但是,當微服務架構規模越來越大時,另一個挑戰開始浮現:服務與服務之間的通訊管理。在擁有數十個甚至上百個微服務的系統中,流量路由、服務間的加密通訊、故障處理、監控追蹤等問題變得複雜且關鍵。傳統做法是在每個服務的程式碼中實作這些功能,但這會導致大量重複工作,也讓業務邏輯與基礎設施邏輯糾纏在一起。

今天我們要研究的 Istio,就是專門解決微服務通訊問題的服務網格(Service Mesh)解決方案。讓我們能夠在不修改應用程式碼的前提下,統一管理服務間的流量、安全和可觀測性。如果說 Kustomize 是管理「靜態配置」的利器,那 Istio 就是掌控「動態流量」的專家。

Service Mesh:微服務時代的新基礎設施

什麼是 Service Mesh?

根據 CNCF 的定義,Service Mesh 是一個 管理層,用來監控和控制一群微服務。重點是,Service Mesh 是用來 強化 而非 取代 服務本身的控制能力。

我們可以把 Service Mesh 想像成城市的交通管制系統。服務本身就像是各個建築物,像是住宅、商場、辦公大樓,而 Service Mesh 就像是交通號誌、路標、監控攝影機等基礎設施。建築物不需要知道交通規則怎麼運作,交通管制系統會自動處理所有車輛的導引。同樣地,你的微服務不需要知道如何路由流量、如何重試失敗的請求、如何加密通訊,Service Mesh 會在底層自動處理這一切。

Service Mesh 通常使用 Sidecar 模式 來實現,在每個服務的 Pod 中注入一個輔助容器,這個容器負責處理該服務所有的網路進出流量、代理請求、收集監控數據等工作。最棒的是,這一切對原本的服務程式碼來說是 完全透明的,不需要修改任何一行程式碼。

Istio:Service Mesh 的實踐者

Istio 是目前最流行的 Service Mesh 實作之一。之前看過的的 Ingress Controller 處理的是 南北向流量,也就是外部到內部的流量,部署在邊緣網路將傳入的流量路由到對應的內部服務。而 Istio 專注於 東西向流量,也就是服務與服務之間的通訊,在 L7 層提供可觀察性、路由和彈性。這些東西向的網路流量構成了整個應用系統的服務網格,Istio 負責管理這些服務間的 TCP/IP 通訊,包括流量限制、熔斷、gRPC、限速、流量鏡像與金絲雀部署等功能。

Istio 的三大核心特性

1. 流量管理(Traffic Management)

這是 Istio 最強大的功能之一。想像我們正在管理一個複雜的購物網站,有商品服務、訂單服務、支付服務等數十個微服務。傳統做法中,如果想做金絲雀 (Canary) 發布(先讓 10% 的用戶試用新版本),我們需要在程式碼中加入流量分配的邏輯,或者在負載均衡器中配置複雜的規則。而 Istio 讓這一切變得簡單:只需要寫幾行 YAML 配置,就能實現精確的流量控制。

Istio 提供了豐富的流量控制能力,而且 不需要修改任何應用程式碼。它支援服務發現與負載平衡,自動發現服務並智慧分配流量。可以根據 HTTP header、URL、權重等條件進行動態路由。

  • A/B 測試:可以根據用戶屬性將不同的流量導向不同版本。
  • 金絲雀 (Canary) 部署:需要在不影響生產環境的情況下測試新版本,流量鏡像功能可以將生產流量複製到測試環境。
  • 擔心服務過載:熔斷器會在檢測到異常時自動停止請求,保護整個系統。

這些功能在傳統架構中需要大量的程式碼才能完成,而且每個服務都要重複實作。但在 Istio 中,透過簡單的 YAML 配置就能實現這些複雜的流量控制策略。更重要的是,這些配置是聲明式的,只需要描述我們想要的行為,Istio 會負責具體的實現。

2. 安全性(Security)

在微服務架構中,服務間的通訊安全是一個複雜的問題。傳統做法需要每個服務自己實作 TLS、憑證管理、身份驗證等功能,這不僅增加了開發負擔,還容易出錯。Istio 讓安全變得 簡單且一致

Istio 預設使用 mTLS(雙向 TLS)加密所有服務間的通訊。當部署一個新服務時,不需要在程式碼中處理任何加密邏輯,Istio 會自動在 Sidecar 層面處理加密和解密。它還提供統一的認證與授權機制,可以在一個地方定義「哪些服務可以訪問哪些服務」,而不需要在每個服務中重複實作這些邏輯。

在 Kubernetes 環境中,Istio 使用 ServiceAccount 進行身份驗證,並自動管理憑證的生成、輪換和撤銷。最重要的是,這些安全機制對應用程式來說是 透明的。開發者可以專注於業務邏輯,而不需要在程式碼中處理 TLS、憑證等複雜的安全問題。

3. 可觀測性(Observability)

當我們的系統由數十個微服務組成時,了解系統的運作狀況變得極為重要。某個 API 為什麼變慢了?是哪個服務導致的?錯誤率為什麼突然增加?這些問題在傳統架構中很難回答,因為需要在每個服務中加入監控程式碼,然後將這些數據聚合起來分析。

Istio 基於監控的「四個黃金指標」提供全面的可觀測性:延遲(請求響應時間)流量(請求數量和頻率)錯誤(錯誤率)飽和度(資源使用情況)。這些指標不需要在程式碼中加入任何監控邏輯,Istio 會自動從 Sidecar 中收集這些數據。

Istio 提供三種類型的遙測數據。首先是指標(Metrics),整合 Prometheus 和 Grafana,提供豐富的視覺化儀表板,可以即時看到每個服務的 RPS、延遲、錯誤率等關鍵指標。其次是分布式追蹤(Distributed Tracing),整合 Jaeger,可以追蹤單個請求在微服務間的完整路徑,清楚看到請求在每個服務中花了多少時間,哪個服務成為了瓶頸。最後是訪問日誌(Access Logs),記錄每個請求的完整資訊,包括來源、目標、HTTP 方法、狀態碼等。

這些數據讓維運人員能夠深入了解服務網格的運作狀況,快速定位問題,優化效能。更重要的是,這一切都是自動的,不需要修改任何應用程式碼。

Istio 架構解析

Istio 的架構可以分為兩大部分:數據平面(Data Plane)控制平面(Control Plane)。這種分離的設計讓 Istio 既能提供強大的功能,又能保持良好的效能和可擴展性。

數據平面(Data Plane)

數據平面是(Data Plane)實際處理流量的地方,由一組 Envoy Proxy 組成,以 Sidecar 的方式部署在每個服務 Pod 中。Envoy 是一個用 C++ 開發的高效能代理工具,它負責攔截所有進出該服務的流量,並根據 Istio 的配置對這些流量進行處理。

Envoy 的功能非常強大。它能動態發現新的服務實例,自動更新服務註冊表。它支援多種負載均衡算法,可以根據實際情況智慧分配流量。它能處理 TLS 的終止和卸載,讓服務不需要自己處理加密通訊。它原生支援 HTTP/2 和 gRPC 這些現代通訊協定,讓微服務間的通訊更加高效。它內建熔斷器功能,可以在檢測到後端服務異常時立即停止發送請求,避免雪崩效應。它還能進行健康檢查,自動將不健康的實例從負載均衡池中移除。

Sidecar 模式帶來的最大優勢是 無侵入性。不需要修改應用程式碼,不需要重新編譯,甚至不需要重啟應用。只要在 namespace 中啟用 Sidecar 注入,新部署的 Pod 就會自動包含 Envoy 容器。這種設計讓 Istio 能夠管理用任何語言寫成的服務,無論是 Java、Go、Python 還是 Node.js,都能使用相同的流量管理功能。而且可以獨立升級 Istio 而不影響業務服務,一個 Proxy 出問題也不會影響其他服務,實現了很好的故障隔離。

控制平面(Control Plane)

控制平面是 Istio 的「大腦」,負責管理和配置數據平面。在 Istio 1.5 之前,控制平面由多個元件組成,包括負責路由策略的 Pilot、負責憑證管理的 Citadel、負責配置驗證的 Galley、以及負責策略控制的 Mixer。從 1.5 版本開始,這些元件被整合成一個單一的 Istiod 元件,大幅簡化了架構,降低了運維複雜度,也提升了效能。

控制平面的核心職責是配置管理。當我們透過 kubectl 應用一個 VirtualService 或 DestinationRule 時,控制平面會驗證這些配置,然後將它們轉換成 Envoy 能理解的格式,下發到各個 Sidecar Proxy。它還負責服務發現,維護整個網格中所有服務的註冊表,告訴每個 Envoy「現在有哪些服務可用,它們的地址是什麼」。

安全性也是控制平面的重要職責。它會自動為每個服務生成 TLS 憑證,並定期輪換這些憑證,確保通訊安全。在 Kubernetes 環境中,這個過程完全自動化,不需要手動管理任何憑證。控制平面還負責收集和聚合來自各個 Proxy 的遙測數據,將它們發送到 Prometheus、Jaeger 等後端系統,讓我們能夠監控整個服務網格的健康狀況。

Istio 核心資源物件

Istio 透過幾個自定義的 Kubernetes CRD(Custom Resource Definition)來配置流量管理。理解這些資源是使用 Istio 的關鍵。

Gateway(網關)

Gateway 定義了 進入或離開 服務網格的入口點,它有點類似於 Kubernetes 的 Ingress,但功能更強大也更靈活。傳統的 Ingress 只能做 L7 的 HTTP/HTTPS 路由,而 Gateway 支援 L4-L6 的負載均衡配置,可以處理 TCP、UDP 等多種協定。你可以在 Gateway 中配置 TLS 設定,指定使用哪個憑證,是否要求客戶端憑證等。

Gateway 還有一個重要特性是可以定義出口網關(Egress Gateway)。在預設情況下,Istio 只管理入口流量,服務訪問外部系統的流量是不受控的。透過 Egress Gateway,可以強制所有出站流量經過指定的節點,這在需要審計、限制外部訪問、或者需要統一的出口 IP 時非常有用。

需要注意的是,Gateway 只負責定義「這裡有個入口,開放在哪個端口,使用什麼協定」,具體的路由規則(流量進來後要導向哪個服務)由 VirtualService 來定義。這種分離的設計讓配置更加靈活,你可以讓多個 VirtualService 共用同一個 Gateway。

VirtualService(虛擬服務)

VirtualService 是 Istio 流量管理的核心,它定義了 如何路由流量 到實際的服務。可以把 VirtualService 想像成一個非常智慧的路由器,它不僅能根據目標地址路由流量,還能根據各種條件進行精確控制。

在 VirtualService 中,hosts 欄位定義了這個虛擬服務對應的主機名,通常是 Kubernetes Service 的名稱。gateways 欄位指定這個路由規則綁定到哪個 Gateway,如果不指定則只對網格內部的流量生效。httptcptls 欄位定義具體的路由規則,其中 http 是最常用的。

路由規則的強大之處在於 match 條件。你可以根據 URI 匹配(精確匹配、前綴匹配、正則匹配),可以根據 HTTP Header 的內容進行路由,可以根據 Query 參數進行判斷。這讓你能實現非常精細的流量控制,比如「所有包含 user=jason header 的請求路由到 v2 版本」,或者「所有訪問 /api/v2/* 的請求路由到新版本」。

route 欄位定義了符合條件的流量要發送到哪裡,可以指定多個目標並設定權重,實現流量分割。fault 欄位讓我們能注入故障來測試系統韌性,可以模擬延遲或返回錯誤。timeoutretries 欄位讓你能控制超時時間和重試策略,這些都是提高系統可靠性的重要機制。

路由規則有一個重要的特性是 由上到下評估,第一個匹配的規則生效。所以我們需要把更具體的規則放在前面,把通用的規則放在後面。如果所有規則都不匹配,則使用最後定義的預設路由。這種設計讓路由邏輯變得清晰且可預測。

DestinationRule(目標規則)

如果說 VirtualService 決定流量 路由到哪裡,那 DestinationRule 就是定義流量到達後 如何處理。在評估完 VirtualService 的路由規則之後,DestinationRule 會定義流量的真正處理方式。

DestinationRule 中最重要的概念是 subsets(子集)。在微服務世界中,同一個服務通常有多個版本同時運行。比如我們可能正在進行金絲雀發布,v1 和 v2 版本同時存在。DestinationRule 透過 Label Selector 來定義這些版本,給每個版本起個名字(比如 v1、v2、v3),然後 VirtualService 就可以透過這些名字來指定路由目標。

trafficPolicy 欄位定義了到達這個目標後的流量策略。connectionPool 設定連接池的大小和行為,這是實現熔斷器的關鍵。你可以限制最大連接數、最大等待請求數、每個連接的最大請求數等。loadBalancer 設定負載均衡策略,可以選擇輪詢、隨機、最少連接等算法。outlierDetection 設定異常檢測,當某個實例連續失敗時,會自動將它從負載均衡池中移除一段時間,這就是所謂的「自動熔斷」。

VirtualService 和 DestinationRule 的配合使用是 Istio 流量管理的精髓。VirtualService 告訴 Istio「這個請求應該去哪個子集」,DestinationRule 告訴 Istio「這個子集包含哪些實例,以及如何與這些實例通訊」。

ServiceEntry(服務入口)

預設情況下,Istio 只管理網格內的服務。但在實際應用中,我們的服務可能需要訪問外部系統,比如第三方 API、雲服務提供商的服務、或者還沒有遷移到 Kubernetes 的舊有系統。ServiceEntry 讓我們可以將 外部服務 加入到 Istio 的服務註冊表中,這樣就能對外部服務應用 Istio 的流量管理功能。

透過 ServiceEntry,我們可以為外部服務設定超時、重試、熔斷等策略,就像管理內部服務一樣。可以為外部服務定義多個端點,實現負載均衡。甚至可以為訪問外部服務的流量加入監控和追蹤,讓整個調用鏈變得清晰可見。這在構建混合雲、多雲、或者微服務遷移的場景中特別有用。

總結

今天的內容先到這邊,結束 CKAD 的內容之後先刷題準備一下證照,實戰的內容後續會再慢慢補上!


上一篇
【Day26】Kustomize:不用模板也能客製化 Kubernetes 配置 - Part2
下一篇
【Day28】Harbor:企業級的私有映像檔倉庫
系列文
30 天挑戰 CKAD 認證!菜鳥的 Kubernetes 學習日記30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言