Istio 網關之南北向流量管理(內含服務網格專家親自解答)

頭圖.png

作者 | 王夕寧  阿里巴巴高級技術專家

參與阿里巴巴雲原生公衆號文末留言互動,有機會獲得贈書福利!

本文摘自於由阿里雲高級技術專家王夕寧撰寫的《Istio 服務網格技術解析與實踐》一書,文章介紹將集羣外部的客戶端連接到集羣內運行的服務,以及如何從集羣內的服務訪問集羣外部的任何服務,即通常所說的南北向流量管理。其中介紹了 Istio 在南北向流量方面的路由控制能力,引出 Istio 網關的概念及其工作原理。

本文文末彙集並整理了近期 Istio 的相關問題並特邀王夕寧老師進行解答,希望能夠對大家有所幫助~

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 上。

1.png
(tio 網關的工作原理)

Istio 網關的負載均衡作用

典型的服務網格具有一個或多個負載均衡器,也稱爲網關(Gateway),它們從外部網絡終止 TLS 並允許流量進入網格。然後,流量通過邊車網關(Sidecar gateway)流經內部服務。應用程序使用外部服務的場景也很常見,可以直接調用外部服務,或者在某些部署中強制通過專用出口網關(Egress Gateway)離開網格的所有流量。

Istio 具有入口網關的概念,它扮演網絡入口點的角色,負責保護和控制來自集羣外部的流量對集羣的訪問。

2.png
(網關在網格中的使用情況)

此外,Istio 的網關還扮演負載均衡和虛擬主機路由的角色。如圖所示,可以看到默認情況下 Istio 使用 Envoy 代理作爲入口代理。Envoy 是一個功能強大的服務到服務代理,但它也有負載均衡和路由的功能,可代理的流量包括從服務網格外部到其內部運行的服務,或者從集羣內部服務到外部服務。在前面章節中介紹的 Envoy 的所有功能也可以在入口網關中使用。

3.png
(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[]

4.png
(端口轉發的入口網關 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 的可觀測性能力從三個維度提供了不同的能力,包括:

Q6:阿里的 ASM 的 Proxy 會採用 MOSN 嗎?期待 MOSN 成爲 Istio 可選數據平面之一。
A6:阿里雲服務網格 ASM 從一開始的設計就是兼容於社區 Istio 開源服務網格,只要符合與 Istio 控制面規約要求的數據面代理,從理論上都是可以支持的。當然一個新代理的適配是需要一定量的開發工作,這兒我們也想了解下客戶對於這方面的訴求。

Q7:Istio 也有類似 Linkerd 的 mutls 功能嗎?
A7:Istio 默認已經提供了雙向 tls 認證的功能,而且支持漸進式,包括 permissive 和 strict 兩種方式。

- 贈書福利 -

5.png

《Istio 服務網格技術解析與實踐》- 機械工業出版社贊助

5 月 15 日 11:00 前在阿里巴巴雲原生公衆號留言區分享**你在學習 Istio 技術的踩坑經驗、或者對新技術的更新、迭代有何獨特的個人見解,**精選留言點贊前 3 名各送出此書一本!

課程推薦

爲了更多開發者能夠享受到 Serverless 帶來的紅利,這一次,我們集結了 10+ 位阿里巴巴 Serverless 領域技術專家,打造出最適合開發者入門的 Serverless 公開課,讓你即學即用,輕鬆擁抱雲計算的新範式——Serverless。

點擊即可免費觀看課程:https://developer.aliyun.com/learning/roadmap/serverless

阿里巴巴雲原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的公衆號。”

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章