基於Istio的灰度平臺實踐學習筆記

來源http://dockone.io/article/9107

上週看到 IBM 分享的 istio-構造,守護,監控微服務的守護神

基於Istio的灰度平臺實踐學習筆記

因此我搜集最新相關文章

【編者的話】Istio目前是Service Mesh最受歡迎的實現方式,

流量管理是Istio一個非常核心的功能。

本次分享主要介紹在Kubernetes平臺上面基於Istio的流量管理做灰度發佈、灰度測試的實踐以及遇到的各種坑。

講個小故事:

馬化騰的灰度機制是這樣的:

很多公司在一開始做產品定義時,要麼確定它是黑的,要麼確定它是白的。

但是馬化騰發現,互聯網產品的定義是有用戶投票決定的。在一開始,我們不定義它是黑,還是白,有一個灰度的週期。在這個灰度週期裡,讓用戶的口碑決定它是生是死,是白還是黑。

Service Mesh是什麼?

服務網格(Service Mesh)是致力於解決服務間通訊的基礎設施層。它負責在現代雲原生應用程序的複雜服務拓撲來可靠地傳遞請求。實際上,Service Mesh 通常是通過一組輕量級網絡代理(Sidecar proxy),與應用程序代碼部署在一起來實現,而無需感知應用程序本身。

可能一句話很難理解Service Mesh到底是什麼。我們通過兩個抽象的場景來看Service Mesh是怎麼發展的。

第一個是服務通訊的發展,當我們有一個需求是兩個服務之間進行通訊。

基於Istio的灰度平臺實踐學習筆記

最原始應該就是通過網線互聯這種最簡單的方式。

隨著計算機變得越來越便宜和越來越流行,連接數量和通過它們的數據量急劇增加。隨著人們越來越依賴網絡系統,工程師需要確保他們構建的軟件符合用戶所需的服務質量,出現了網絡層。如圖1

此時就對我們的程序提出了挑戰,比如說流量控制。

想象一種場景,

計算機A以給定的速率向計算機B發送字節,但不能保證B將以一致且足夠快的速度處理接收的字節。例如,B可能忙於並行運行其他任務,或者數據包可能無序到達,而B被阻止等待應該首先到達的數據包。

這意味著不僅A不具備B的預期性能,而且還可能使事情變得更糟,因為它可能會使B超載,現在必須將所有這些傳入的數據包排隊等待處理。

當出現這種問題時,最簡單的就是在業務裡面實現流量控制的邏輯。如圖2。

技術飛速發展,很快TCP/IP出現,將流控制和許多其他問題納入網絡堆棧本身。

這意味著該段代碼仍然存在,但它已從您的應用程序提取到您的操作系統提供的底層網絡層

我們發現,隨著技術的發展,公共的東西越來越下沉。

  • 知識補充:網絡堆棧

網絡堆棧 內核空間對堆棧通訊數據,可以sockect緩衝區,每個連接都有自己緩衝區tcp協議棧內容。比較複雜 Linux內核參數說明和TCP/IP協議棧 Linux服務器丟包故障的處

基於Istio的灰度平臺實踐學習筆記

第二個場景,是微服務時代的一個場景,微服務時代給我們帶來了很多機遇和新的挑戰。

新的機遇比如說我們可以讓服務的職責更單一,發佈更迅速。

挑戰就像是我們圖1中的問題,服務發現和熔斷。

基於Istio的灰度平臺實踐學習筆記

最開始遇到這樣的問題,開始的方式依舊是在我們的代碼中,編寫對應的邏輯來做。如圖1。

隨著技術發展,有了專門的庫來把公共的東西抽象出來,我們只需要做一個依賴。如圖2 。

與我們在網絡堆棧中看到的類似,非常希望將大規模分佈式服務所需的功能提取到底層平臺中。

人們使用更高級別的協議(如HTTP)編寫非常複雜的應用程序和服務,甚至不考慮TCP如何控制其網絡上的數據包。這種情況是我們對微服務所需要的,其中從事服務工作的工程師可以專注於他們的業務邏輯,避免浪費時間編寫自己的服務基礎架構代碼或管理整個機隊的庫和框架。如圖3。

而這樣的實現方式比較困難,於是後續有一個新的方式。Sidecar,它是重新啟動一個進程,來攔截所有的流量。於是有了圖4這種部署方式。

當我們有很多服務部署的時候,就看到的整體部署圖就變成了很多sidecar之間的通訊。那麼又一個新的挑戰,就是sidecar應該如何管理。那麼control plane就變成了一個不可或缺的組件。用來管理我們的sidecar。

於是有了最終Service Mesh的架構圖。

Istio是什麼?

簡單說是一種Service Mesh架構的實現。

官網的描述為Istio 提供一種簡單的方式來為已部署的服務建立網絡,該網絡具有負載均衡、服務間認證、監控等功能,只需要對服務的代碼進行很少或不需要做任何改動。

想要讓服務支持Istio,

只需要在您的環境中部署一個特殊的sidecar代理,使用Istio控制平面功能配置和管理代理,攔截微服務之間的所有網絡通信。

Istio各模塊的職責:

基於Istio的灰度平臺實踐學習筆記

Istio的架構圖:

基於Istio的灰度平臺實踐學習筆記

為什麼要用Istio?

  • Cloud Native雲原生趨勢
  • 多語言:Java、Python、Go
  • 強大的流量管理

為什麼選擇Istio?

  • Google加持。
  • 一個非常活躍的開源項目。
  • 更新頻次。2月開始到現在更新了18個版本。
  • 最近一次KubeCon大會上,Istio是一個出現頻次非常高的詞。
  • 國內各大雲平臺的首選,阿里,騰訊,華為,螞蟻金服……

Istio測試環境實踐

為什麼又有一個測試環境?

  1. 跟線上環境結構不同。線上結構是通過git group拆分namespace。測試環境在同一個namespace下跑所有服務。
  2. 多環境。現在測試環境有2個,每個裡面跑所有的基礎服務,導致pod數很多,有段時間,測試環境的Pod總數比生產還要多。但是流量卻少很多。
  3. 多語言。現在主要是Java技術棧,和部分的Python,未來還有Go技術棧。Java技術棧的話,Spring Cloud做服務發現,熔斷,負載等功能是沒有問題,但是在多個技術棧的時候,我們就需要再做很多事情來兼容。
  4. 流量管理。就是需要更加強大的流量管理,比如灰度發佈,基於比例的流量策略。

現在的流量管理方式:

基於Istio的灰度平臺實踐學習筆記

基於Istio的灰度平臺實踐學習筆記

當有A-B-C-D的一個調用鏈時,當B有新版本V2發佈,會把B老版本替換。導致所有的人員測試的流量都是相同的服務,這樣的測試環境就變得很不穩定,上游服務可能會受到下游服務發佈的影響。

我們期望的流量方式:

基於Istio的灰度平臺實踐學習筆記

我們期望的方式是,當B發佈新版本V2時,跟B老版本同時運行,只是對應測試B-V2的測試人員的流量會打到B-V2服務。而其他人的流量依然走A-B-C-D。

我們測試環境的部分實現細節:

配置如圖:

常見問題

Pod顯示2/2問題?Pod日誌看不了了,提示:

基於Istio的灰度平臺實踐學習筆記

Error from server (BadRequest): a container name must be specified for pod spring-account-admin-normal-dcd6544cd-ckxjr, choose one of: [istio-proxy account-admin]

因為:

需要選擇container。

需要-c參數來指定container名稱。

Consul取消註冊問題?原來使用Consul做服務發現,當停Pod時,沒有從Consul上註銷。

因為:在業務container關閉的時候,envoy也關閉了。所以訪問失敗了。issue#7136。

解決:preStop腳本,在Envoy關閉時,會檢查是否有非Envoy的進程在運行。如果有,也會超時重試。等待業務服務的優雅停機。

容器啟動順序問題?Pod啟動的時候,連接consul timeout問題。

因為:主要是因為服務啟動的順序問題。當Pod中業務container啟動的時候,Envoy也在啟動,但是initContainer已經啟動完畢,iptables已經配置好了。所以請求打不出去了

解決:我們在容器啟動的時候,加了超時重試。

訪問外網問題。在部署完istio之後,我們所有請求外網的url都返回失敗。

因為:Istio的iptables規則。是攔截所有的請求。

解決:通過配置Istio的參數global.proxy.includeIPRanges來指定Envoy攔截的流量。只攔截Service IP段流量。

漸進式升級Istio怎麼做?

主要是兼容之前的請求鏈路。

原來通過Consul服務發現,本地找到Consul中存儲的服務實例,即Pod IP。通訊的時候使用Pod IP。

需要灰度的流量需要修改為Kubernetes的服務發現,即使用Service IP進行通訊,Envoy也只攔截service ip的流量。即區分SVC的IP段,和Pod的IP段。這樣當業務不改動代碼時,還是走原來的請求鏈路,需要使用灰度功能時,可以修改代碼,來支持灰度測試。

Prometheus內存撐爆問題。有一次測試環境一上午不能用。

因為:開箱即用的Prometheus。

解決:Resources limits。

gRPC Not Started問題,有一次升級完gRPC Starter支持keep header之後,gRPC的請求偶發的出現gRPC Not Started異常。

因為:需要使用header中數據分流,線程中gRPC調用,header丟失。

解決:添加容錯。

Q&A

Q:如何判斷check、quota下放istio-proxy引入的問題?

A:得通過壓測了,看性能損耗了。我們後續會加入Mixer的功能再壓測一輪。現在做的壓測還是不開Mixer功能的場景下壓的。因為我們線上目前還不打算開Mixer。

Q:能否給個demo?

A:目前還沒有開放在外面的demo。可以給些思路,請問你想要什麼要的功能的demo?沒實踐過,聽理論總是有點虛!可以實踐一下。我們主要是用的Istio(Envoy)的流量管理的功能。主要是要配置Istio的流量管理策略。給業務人員再給他們配置yaml文件,學習成本太大,所以做了可視化,有按流量,按用戶,自定義三種方式。主要是把頁面配置編譯成yaml流量配置。

Q:Istio每個服務中得到的訪問IP都是127.0.0.1,這個該怎麼搞?能拿到real client ip?

A:kubectl get svc應該可以查到clusterip,接著Q3,app拿到外面訪問的address都是127.0.0.1的。

嗯,是有這個問題,我們也遇到了,目前還沒有解決方案。Envoy的日誌中是可以拿到的,後續需要看看怎麼帶過去。

Q:服務的應用運行日誌在Istio中如何獲取或者查看,例如log4j控制檯的輸出?

A:應用運行日誌就在應用容器上看啊。我們是通過標準輸出收集到了InfluxDB中。

Q:Envoy的CPU、內存的request、limit一般配置多少?

A:我們壓測的是默認的Envoy的資源限制。沒有修改默認的資源限制。

resources:
limits:
cpu: "2"
memory: 1Gi
requests:
cpu: 100m
memory: 128Mi

Q:裡面在配合Spring Clund有必要嗎?

A:感覺沒必要,重複了,Istio讓程序員更關注業務,將維護管理分離

我們之後會陸續用Istio的方式替換之前在Spring Cloud上的實現。

Q:有配合Alibaba Nacos試試嗎實驗落地的最好,consul.etcd選哪個好點?

A:沒有使用過Alibaba Nacos,我們未來會走Kubernetes的服務發現,所以會選擇etcd吧。

Q:Spring Cloud向Istio遷移好遷移嗎?

A:比較好遷移。我們遇到的問題主要就是通訊的問題。涉及到Feign和gRPC兩種。需要升級一下starter,傳遞一下header。因為我們的流量標籤是在header中傳遞。還有一個重要的就是分享裡提到的,服務發現問題。因為要做漸進式升級,不能一下就給所有的服務上Istio,邊緣服務先上,熱門服務後上,所以要兼容之前的服務發現(Consul),同時有兩個服務發現機制的時候會有些問題。


分享到:


相關文章: