做者 | 王夕寧 阿里巴巴高級技術專家html
參與阿里巴巴雲原生公衆號文末留言互動,有機會得到贈書福利!node
本文摘自於由阿里雲高級技術專家王夕寧撰寫的《Istio 服務網格技術解析與實踐》一書,文章介紹將集羣外部的客戶端鏈接到集羣內運行的服務,以及如何從集羣內的服務訪問集羣外部的任何服務,即一般所說的南北向流量管理。其中介紹了 Istio 在南北向流量方面的路由控制能力,引出 Istio 網關的概念及其工做原理。mysql
本文文末聚集並整理了近期 Istio 的相關問題並特邀王夕寧老師進行解答,但願可以對你們有所幫助~sql
Istio 網關
網絡社區中有一個術語 Ingress,是指入口請求到集羣內服務的流量管理。Ingress 指的是源自本地網絡以外的流量,指向本地集羣網絡中的端點。此流量首先路由到公開的入口點,以便經過執行一些本地網絡的規則和策略來確認哪些流量被容許進入。若是流量未經過這些入口點,則沒法與集羣內的任何服務鏈接。若是入口點容許流量進入,則將其代理到本地網絡中的合適節點。Istio 對入口流量的管理是由 Istio 網關進行的。json
Istio 網關的工做原理
傳統上,Kubernetes 使用 Ingress 控制器來處理從外部進入集羣的流量。使用 Istio 時,狀況再也不如此。Istio 網關用新的 Gateway 資源和 VirtualServices 資源來控制入口流量,它們協同工做以將流量路由到網格中。在網格內部不須要 Gateways,由於服務能夠經過集羣本地服務名稱相互訪問。api
那麼 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)離開網格的全部流量。less
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 protocol: TCP - name: mysql nodePort: 30306 port: 3306 protocol: TCP
入口網關部署
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 - hosts: - '*' port: name: https 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. port: name: mysql number: 3306 protocol: TCP
網關虛擬服務
VirtualService 資源與 Gateway 資源相互配合支持 Envoy 的配置。下面是一個支持 HTTP 服務的網關虛擬服務的基本配置:
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: counter spec: gateways: - default-gateway.istio-system.svc.cluster.local hosts: - counter.lab.example.com http: - match: - uri: prefix: / route: - 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 的日誌信息:
kubectl -n istio-system logs $(kubectl -n istio-system get pods -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服務網格技術解析與實戰》讀者可免費體驗 ASM 產品進行學習!點擊瞭解阿里雲服務網格產品 ASM: www.aliyun.com/product/servicemesh
做者簡介
王夕寧 阿里雲高級技術專家,阿里雲服務網格產品 ASM 及 Istio on Kubernetes 技術負責人,專一於 Kubernetes、雲原生、服務網格等領域。曾在 IBM 中國開發中心工做,擔任過專利技術評審委員會主席,擁有 40 多項相關領域的國際技術專利。《Istio 服務網格解析與實戰》一書由其撰寫,詳細介紹了 Istio 的基本原理與開發實戰,包含大量精選案例和參考代碼能夠下載,可快速入門 Istio 開發。Gartner 認爲,2020 年服務網格將成爲全部領先的容器管理系統的標配技術。本書適合全部對微服務和雲原生感興趣的讀者,推薦你們對本書進行深刻的閱讀。
關於 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.html
Q4:最近在研究 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 兩種方式。
- 贈書福利 -
《Istio 服務網格技術解析與實踐》- 機械工業出版社贊助
5 月 15 日 11:00 前在阿里巴巴雲原生公衆號留言區分享**你在學習 Istio 技術的踩坑經驗、或者對新技術的更新、迭代有何獨特的我的看法,**精選留言點贊前 3 名各送出此書一本!
課程推薦
爲了更多開發者可以享受到 Serverless 帶來的紅利,這一次,咱們集結了 10+ 位阿里巴巴 Serverless 領域技術專家,打造出最適合開發者入門的 Serverless 公開課,讓你即學即用,輕鬆擁抱雲計算的新範式——Serverless。
點擊便可免費觀看課程:https://developer.aliyun.com/learning/roadmap/serverless
「阿里巴巴雲原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,作最懂雲原生開發者的公衆號。」