Istio 網關
網絡社群中有一個術語 Ingress,是指入口請求到叢集内服務的流量管理。Ingress 指的是源自本地網絡之外的流量,指向本地叢集網絡中的端點。此流量首先路由到公開的入口點,以便通過執行一些本地網絡的規則和政策來确認哪些流量被允許進入。如果流量未通過這些入口點,則無法與叢集内的任何服務連接配接。如果入口點允許流量進入,則将其代理到本地網絡中的合适節點。Istio 對入口流量的管理是由 Istio 網關進行的。
Istio 網關的工作原理
傳統上,Kubernetes 使用 Ingress 控制器來處理從外部進入叢集的流量。使用 Istio 時,情況不再如此。Istio 網關用新的 Gateway 資源和 VirtualServices 資源來控制入口流量,它們協同工作以将流量路由到網格中。在網格内部不需要 Gateways,因為服務可以通過叢集本地服務名稱互相通路。
那麼 Istio 網關是怎樣工作的?請求如何到達它想要的應用程式?基本步驟如下:
1.用戶端在特定端口上送出請求;
2.負載均衡器在這個端口上進行偵聽,并将請求轉發到叢集中(在相同或新的端口);
3.在叢集内部,請求被路由到 Istio IngressGateway 服務所偵聽的負載均衡器轉發過來的端口上;
4.Istio IngressGateway 服務将請求(在相同或新的端口)轉發到對應的 pod 上;
5.在 IngressGateway pod 上會配置 Gateway 資源和 VirtualService 資源定義。Gateway 會配置端口、協定以及相關安全證書。VirtualService 的路由配置資訊用于找到正确的服務;
6.Istio IngressGateway pod 會根據路由配置資訊将請求路由到對應的應用服務上;
7.應用服務将請求路由到對應的應用 pod 上。

(tio 網關的工作原理)
Istio 網關的負載均衡作用
典型的服務網格具有一個或多個負載均衡器,也稱為網關(Gateway),它們從外部網絡終止 TLS 并允許流量進入網格。然後,流量通過邊車網關(Sidecar gateway)流經内部服務。應用程式使用外部服務的場景也很常見,可以直接調用外部服務,或者在某些部署中強制通過專用出口網關(Egress Gateway)離開網格的所有流量。
Istio 具有入口網關的概念,它扮演網絡入口點的角色,負責保護和控制來自叢集外部的流量對叢集的通路。
(網關在網格中的使用情況)
此外,Istio 的網關還扮演負載均衡和虛拟主機路由的角色。如圖所示,可以看到預設情況下 Istio 使用 Envoy 代理作為入口代理。Envoy 是一個功能強大的服務到服務代理,但它也有負載均衡和路由的功能,可代理的流量包括從服務網格外部到其内部運作的服務,或者從叢集内部服務到外部服務。在前面章節中介紹的 Envoy 的所有功能也可以在入口網關中使用。
(Istio 的入口網關服務)
對于入口流量管理,你可能會問:為什麼不直接使用 Kubernetes Ingress API?
- 第一個原因,Kubernetes Ingress 是一個面向 HTTP 工作負載的非常簡單的規範。有 Kubernetes Ingress 的實作(如 Nginx、Heptio Contour 等),但每個都适用于 HTTP 流量。實際上,Ingress 規範隻将端口 80 和端口 443 視為入口點。這嚴重限制了叢集運維人員可以允許進入服務網格的流量類型。例如,如果你有 Kafka 工作負載,則可能希望向這些消息代理公開直接 TCP 連接配接;
- 第二個原因,Kubernetes Ingress API 無法表達 Istio 的路由需求。Ingress 沒有通用的方法來指定複雜的流量路由規則,如流量拆分或流量鏡像等。這個領域缺乏規範會導緻每個供應商重新設想如何更好地為每種類型的 Ingress 實作(如 HAProxy、Nginx 等)做好配置管理。Ingress 試圖在不同的 HTTP 代理之間取一個公共的交集,是以隻能支援最基本的 HTTP 路由;
- 最後一個原因,由于事前沒有明确規定,大多數供應商的選擇是通過部署上的定制注釋來做配置。供應商之間的注釋各不相同,并且不可移植,如果 Istio 繼續延續這種趨勢,那麼就會有更多的注釋來解釋 Envoy 作為邊緣網關的所有功能。
Istio 網關通過将 L4-L6 配置與 L7 配置分離克服了 Ingress 的這些缺點。Istio 網關隻用于配置 L4-L6 功能(例如,對外公開的端口、TLS 配置),所有主流的 L7 代理均以統一的方式實作了這些功能。然後,通過在 Gateway 上綁定 VirtualService 的方式,可以使用标準的 Istio 規則來控制進入 Gateway 的 HTTP 和 TCP 流量。負載均衡器可以手動配置或通過服務自動配置其類型,例如 type: LoadBalancer。在這種情況下,由于并非所有雲都支援自動配置,假設手動配置負載均衡器以将流量轉發到 IngressGateway Service 正在偵聽的端口。例如如下的負載均衡器正在監聽以下端口:
- HTTP:端口 80,将流量轉發到端口 30080;
- HTTPS:端口 443,将流量轉發到端口 30443;
- MySQL:端口 3306,将流量轉發到端口 30306 確定負載均衡器配置轉發到所有工作節點。這将確定即使某些節點關閉也會轉發流量。
入口網關服務
IngressGateway 服務(入口網關服務)必須監聽上節介紹的所有端口,以便能夠将流量轉發到 IngressGateway pod 上。Kubernetes 服務不是“真正的”服務,該請求将由 Kubernetes 提供的 kube-proxy 轉發到具有運作對應 pod 的節點上。在節點上,IP table 配置将請求轉發到适當的 pod:
ports:
-
name: http2
nodePort: 30000
port: 80
protocol: TCP
-
name: https
nodePort: 30443
port: 443
-
name: mysql
nodePort: 30306
port: 3306
入口網關部署
IngressGateway 部署是一個基于 Envoy 代理的封裝,它的配置方式與服務網格中使用的 Sidecar 配置相同(實際上是同樣的容器鏡像)。當我們建立或更改一個 Gateway 或 VirtualService 時,Istio Pilot 控制器會檢測到這些變更,并将這些變更資訊轉換為 Envoy 配置,然後将 Envoy 配置資訊發送給相關 Envoy 代理,包括内部的 Envoy 和 IngressGateway 中的 Envoy。
注意:這裡不要混淆 IngressGateway 與 Gateway,Gateway 資源是用于配置 IngressGateway 的一種 Kubernetes 的自定義資源。
由于不必在 Kubernetes pod 或部署中聲明容器端口,是以我們不必在 IngressGateway Deployment 中聲明端口。但是,如果檢視部署内部,可以看到聲明的許多端口。另外,在 IngressGateway 部署中需要關注 SSL 證書,為了能夠通路 Gateway 資源内的證書,請確定已正确加載這些證書。
網關資源
網關資源用來配置 Envoy 的端口,前面的示例中已經使用該服務公開了三個端口,是以需要在 Envoy 中處理這些端口。此外,可以通過聲明一個或多個 Gateways 來支援多端口能力。下面的示例中使用單個 Gateway,但可以分為兩個或三個分别定義:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: default-gateway
namespace: istio-system
spec:
selector:
istio: ingressgateway
servers:
- hosts:
-
'*'
port:
name: http
number: 80
protocol: HTTP
-
-
number: 443
protocol: HTTPS
tls:
mode: SIMPLE
privateKey: /etc/istio/ingressgateway-certs/tls.key
serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
- hosts: # For TCP routing this fields seems to be ignored, but it is matched
- '' # with the VirtualService, I use since it will match anything.
網關虛拟服務
VirtualService 資源與 Gateway 資源互相配合支援 Envoy 的配置。下面是一個支援 HTTP 服務的網關虛拟服務的基本配置:
kind: VirtualService
name: counter
gateways:
-
default-gateway.istio-system.svc.cluster.local
hosts:
-
counter.lab.example.com
http:
- match:
-
uri:
prefix: /
- destination:
host: counter port: number: 80
-
現在,當我們添加一個 Gateway 和一個 VirtualService 時,路由已在 Envoy 配置中建立。要檢視此内容,你可以使用如下指令:
kubectl port-forward istio-ingressgateway-xxxx-yyyy-n istio-system 15000
調試入口網關
調試網絡問題有時很困難,是以這裡總結一些有用的指令用于調試。端口轉發到第一個 istio-ingressgateway pod:
kubectl -n istio-system port-forward $(kubectl -n istio-system get pods
-listio=ingressgateway -o=jsonpath="{.items[0].metadata.name}") 15000
然後,可以從端口轉發的入口網關 pod 中獲得 http 路由:
Curl --silent
http://localhost:15000/config_dump|jq .configs[3].dynamic_route_configs[].route_config.virtual_hosts[]
(端口轉發的入口網關 pod)
檢視上述端口轉發的入口網關 pod 的日志資訊:
kubectl -n istio-system logs $(kubectl -n istio-system get pods
-listio=ingressgateway -o=jsonpath="{.items[0].metadata.name}") --tail=300
檢視 Pilot pod 的日志資訊:
-listio=pilot -o=jsonpath="{.items[0].metadata.name}") discovery --tail=300
當啟動端口轉發到入口網關 istio-ingressgateway 之後,可以執行更多操作以擷取更多資訊,例如:
- 需要檢視 Envoy 偵聽器,請點選網址: http://localhost:15000/listeners ;
- 需要打開更詳細的日志記錄,請點選網址: http://localhost:15000/logging
- 可以在根目錄 http://localhost:15000/ 中找到更多資訊。
關于 Istio 的一些 Q&A
Q1:Istio 在實際生産環境實踐中都會遇到哪些瓶頸,常見的優化手段又都有哪些?
A1:阿裡雲之是以推出服務網格 ASM 這個産品,就是把過去一兩年支援客戶使用 Istio 的過程中遇到的太多問題,總結成了經驗并落地到産品中。是以多關注下這個産品的能力就會看到具體解決了哪些問題。在此就不一一贅述了。
Q2:Istio 會導緻性能消耗增加嗎?
A2:這個問題需要一個上下文,這就像問 Java 虛拟機會導緻性能消耗嗎。任何解耦總會帶來一定的通信消耗。建議使用 Istio 前先判斷下自己的應用是否适合解耦、服務化以及容器化,然後再看是否适合采用 Istio 的哪些功能。
Q3:Service Mesh 是很好的工具,但是痛點也很明顯,引入 Istio 會讓運維更加複雜,阿裡雲服務網格産品 ASM 這方面有做什麼改進?
A3:阿裡雲服務網格 ASM 提供了一個全托管式的服務網格平台,相容于社群 Istio 開源服務網格,用于簡化服務的治理,并提供了簡單易用的控制台,托管模式下讓使用者解脫控制面的複雜管理,極大地減輕開發與運維的工作負擔。具體可以參考這個入門教程了解一下:
https://help.aliyun.com/document_detail/149552.htmlQ4:最近在研究 Istio,有真正落地使用的例子嗎?
A4:過去一兩年我們已經支援了大量客戶使用 Istio,譬如有客戶使用 Istio 流量管理來做應用的灰階釋出,有客戶使用它的統一的聲明式的方式來管理入口網關,包括入口網關的 tls 透傳功能、tls 終止以及動态加載證書的能力等等。
Q5:目前阿裡服務網格産品 ASM 針對 Istio 采用什麼樣的監控?
A5:阿裡雲服務網格 ASM 的可觀測性能力從三個次元提供了不同的能力,包括:
- 日志:每一個 Sidecar 代理和入口網關的通路日志及分析報表,可以參考: https://help.aliyun.com/document_detail/162798.html
- 跟蹤:內建了阿裡雲鍊路追蹤服務 Tracing Analysis,為分布式應用的開發者提供了完整的調用鍊路還原、調用請求量統計、鍊路拓撲、應用依賴分析等能力,可以參考: https://help.aliyun.com/document_detail/149551.html
- 監控:內建了 ARMS Prometheus 及 Grafana Dashboard 的能力,這部分的文檔正在輸出,請持續關注産品的文檔: https://help.aliyun.com/product/147365.html 。
Q6:阿裡的 ASM 的 Proxy 會采用 MOSN 嗎?期待 MOSN 成為 Istio 可選資料平面之一。
A6:阿裡雲服務網格 ASM 從一開始的設計就是相容于社群 Istio 開源服務網格,隻要符合與 Istio 控制面規約要求的資料面代理,從理論上都是可以支援的。當然一個新代理的适配是需要一定量的開發工作,這兒我們也想了解下客戶對于這方面的訴求。
Q7:Istio 也有類似 Linkerd 的 mutls 功能嗎?
A7:Istio 預設已經提供了雙向 tls 認證的功能,而且支援漸進式,包括 permissive 和 strict 兩種方式。
本文轉自<阿裡巴巴雲原生技術圈>——阿裡巴巴雲原生小助手