Why is istio?(二)

出處:https://cizixs.com/2018/08/26/what-is-istio

創作不易,在滿足創作共用版權協議的基礎上可以轉載,但請以超鏈接形式註明出處。

前言

隨著微服務架構的流行,服務網格技術獲得了業界的廣泛關注,作為實現雲原生的重要積木,各大廠商也紛紛開始佈局,Amazon在2019年4月份推出了App Mesh;Google、IBM、Lyft聯合開發了Istio。

Istio作為下一代服務網格的整體解決方案,得到了業界的普遍認可,站在kubernetes巨人的肩膀上,極大地提升了分佈式微服務應用的研發和運維效率。

2020是雲原生普及的一年,如何部署、使用、運維Istio將是必須要學習的知識。

什麼是 istio?

官方對 istio 的介紹濃縮成了一句話:

An open platform to connect, secure, control and observe services.

翻譯過來,就是”連接、安全加固、控制和觀察服務的開放平臺“。開放平臺就是指它本身是開源的,服務對應的是微服務,也可以粗略地理解為單個應用。中間的四個動詞就是 istio 的主要功能,官方也各有一句話的說明。這裡再闡釋一下:

  • 連接(Connect):智能控制服務之間的調用流量,能夠實現灰度升級、AB 測試和紅黑部署等功能
  • 安全加固(Secure):自動為服務之間的調用提供認證、授權和加密
  • 控制(Control):應用用戶定義的 policy,保證資源在消費者中公平分配
  • 觀察(Observe):查看服務運行期間的各種數據,比如日誌、監控和 tracing,瞭解服務的運行情況
雲原生 - Why is istio?(二)

雖然聽起來非常高級,功能非常強大,但是一股腦出現這麼多名詞,還都是非常虛的概念,說了跟沒說一樣。要想理解上面這幾句話的含義,我們還是從頭說起,先聊聊 service mesh。

NOTE:其實 istio 的源頭是微服務,但這又是一個比較大的話題,目前可以參考網絡上各種文章。如果有機會,我們再來聊聊微服務。

什麼是 service mesh

一般介紹 service mesh 的文章都會從網絡層的又一個抽象說起,把 service mesh 看做建立在 TCP 層之上的微服務層。我這次換個思路,從 service mesh 的技術根基——網絡代理來分析。

說起網絡代理,我們會想到翻牆,如果對軟件架構比較熟悉的會想到 Nginx 等反向代理軟件。其實網絡代理的範圍比較廣,可以肯定的說,有網絡訪問的地方就會有代理的存在。

Wikipedia 對代理的定義如下:

In computer networks, a proxy server is a server (a computer system or an application) that acts as an intermediary for requests from clients seeking resources from other servers.

NOTE:代理可以是嵌套的,也就是說通信雙方 A、B 中間可以多多層代理,而這些代理的存在有可能對 A、B 是透明的。

簡單來說,網絡代理可以簡單類比成現實生活中的中介,本來需要通信的雙方因為各種原因在中間再加上一道關卡。本來雙方就能完成的通信,為何非要多此一舉呢?那是因為代理可以為整個通信帶來更多的功能,比如:

  • 攔截:代理可以選擇性攔截傳輸的網絡流量,比如一些公司限制員工在上班的時候不能訪問某些遊戲或者電商網站,再比如把我們和世界隔離開來的 GFW,還有在數據中心中拒絕惡意訪問的網關
  • 統計:既然所有的流量都經過代理,那麼代理也可以用來統計網絡中的數據信息,比如瞭解哪些人在訪問哪些網站,通信的應答延遲等
  • 緩存:如果通信雙方比較”遠“,訪問比較慢,那麼代理可以把最近訪問的數據緩存在本地,後面的訪問不用訪問後端來做到加速。CDN 就是這個功能的典型場景
  • 分發:如果某個通信方有多個服務器後端,代理可以根據某些規則來選擇如何把流量發送給多個服務器,也就是我們常說的負載均衡功能。比如著名的 Nginx 軟件
  • 跳板:如果 A、B 雙方因為某些原因不能直接訪問,而代理可以和雙方通信,那麼通過代理,雙方可以繞過原來的限制進行通信。這應該廣大中國網民比較熟悉的場景
  • 注入:既然代理可以看到流量,那麼它也可以修改網絡流量,可以自動在收到的流量中添加一些數據,比如有些寬帶提供商的彈窗廣告
  • ……
雲原生 - Why is istio?(二)

不是要講 service mesh 嗎?為什麼扯了一堆代理的事情?因為 service mesh 可以看做是傳統代理的升級版,用來解決現在微服務框架中出現的問題,可以把 service mesh 看做是分佈式微服務代理。

在傳統模式下,代理一般是集中式的單獨的服務器,所有的請求都要先通過代理,然後再流入轉發到實際的後端。而在 service mesh 中,代理變成了分佈式的,它常駐在了應用的身邊(最常見的就是 kubernetes sidecar 模式,每一個應用的 pod 中都運行著一個代理,負責流量相關的事情)。這樣的話,應用所有的流量都被代理接管,那麼這個代理就能做到上面提到的所有可能的事情,從而帶來無限的想象力。

雲原生 - Why is istio?(二)

此外,原來的代理都是基於網絡流量的,一般都是工作在 IP 或者 TCP 層,很少關心具體的應用邏輯。但是 service mesh 中,代理會知道整個集群的所有應用信息,並且額外添加了熱更新、注入服務發現、降級熔斷、認證授權、超時重試、日誌監控等功能,讓這些通用的功能不必每個應用都自己實現,放在代理中即可。換句話說,service mesh 中的代理對微服務中的應用做了定製化的改進!

雲原生 - Why is istio?(二)

就這樣,藉著微服務和容器化的東風,傳統的代理搖身一變,成了如今炙手可熱的 service mesh。應用微服務之後,每個單獨的微服務都會有很多副本,而且可能會有多個版本,這麼多微服務之間的相互調用和管理非常複雜,但是有了 service mesh,我們可以把這塊內容統一在代理層。

雲原生 - Why is istio?(二)

有了看起來四通八達的分佈式代理,我們還需要對這些代理進行統一的管理。手動更新每個代理的配置,對代理進行升級或者維護是個不可持續的事情,在前面的基礎上,在加上一個控制中心,一個完整的 service mesh 就成了。管理員只需要根據控制中心的 API 來配置整個集群的應用流量、安全規則即可,代理會自動和控制中心打交道根據用戶的期望改變自己的行為。

雲原生 - Why is istio?(二)

NOTE:所以你也可以理解 service mesh 中的代理會搶了 Nginx 的生意,這也是為了 Nginx 也要開始做 NginMesh 的原因。

再來看 istio

瞭解了 service mesh 的概念,我們再來看 istio ,也許就會清楚很多。首先來看 istio 官方給出的架構圖:

雲原生 - Why is istio?(二)

可以看到,istio 就是我們上述提到的 service mesh 架構的一種實現,服務之間的通信(比如這裡的 Service A 訪問 Service B)會通過代理(默認是 envoy)來進行,而且中間的網絡協議支持 HTTP/1.1,HTTP/2,gRPC 或者 TCP,可以說覆蓋了主流的通信協議。控制中心做了進一步的系分,分成了 Pilot、Mixer、和 Citadel,它們的各自功能如下:

  • Pilot:為 envoy 提供了服務發現,流量管理和智能路由(AB測試、金絲雀發佈等),以及錯誤處理(超時、重試、熔斷)功能。用戶通過 pilot 的 API 管理網絡相關的資源對象,pilot 會根據用戶的配置和服務的信息把網絡流量管理變成 envoy 能識別的格式分發到各個 sidecar 代理中。
  • Mixer:為整個集群執行訪問控制(哪些用戶可以訪問哪些服務)和 policy 管理(rate limit,quota 等),並且收集代理觀察到的服務之間的流量統計數據
  • Citadel:為服務之間提供認證和證書管理,可以讓服務自動升級成 TLS 協議

代理會和控制中心通信,一方面可以獲取需要的服務之間的信息,另一方面也可以彙報服務調用的 metrics 數據。知道 istio 的核心架構,再來看看它的功能描述就非常容易理解了。

  • 連接:控制中心可以從集群中獲取所有服務的信息,並分發給代理,這樣代理就能根據用戶的期望來完成服務之間的通信(自動地服務發現、負載均衡、流量控制等)
  • 安全加固:因為所有的流量都是通過代理的,那麼代理接收到不加密的網絡流量之後,可以自動做一次封裝,把它升級成安全的加密流量
  • 控制:用戶可以配置各種規則(比如 RBAC 授權、白名單、rate limit 或者 quota 等),當代理髮現服務之間的訪問不符合這些規則,就直接拒絕掉
  • 觀察:所有的流量都經過代理,因此代理對整個集群的訪問情況知道得一清二楚,它把這些數據上報到控制中心,那麼管理員就能觀察到整個集群的流量情況了

istio 解決什麼問題

雖然看起來非常炫酷,功能也很強大,但是一個架構和產品出來都是要解決具體的問題。所以這部分我們來看看微服務架構中的難題以及 istio 給出的答案。

首先,原來的單個應用拆分成了許多分散的微服務,它們之間相互調用才能完成一個任務,而一旦某個過程出錯(組件越多,出錯的概率也就越大),就非常難以排查。

用戶請求出現問題無外乎兩個問題:錯誤和響應慢。如果請求錯誤,那麼我們需要知道那個步驟出錯了,這麼多的微服務之間的調用怎麼確定哪個有調用成功?哪個沒有調用成功呢?如果是請求響應太慢,我們就需要知道到底哪些地方比較慢?整個鏈路的調用各階段耗時是多少?哪些調用是併發執行的,哪些是串行的?這些問題需要我們能非常清楚整個集群的調用以及流量情況。

雲原生 - Why is istio?(二)

此外,微服務拆分成這麼多組件,如果單個組件出錯的概率不變,那麼整體有地方出錯的概率就會增大。服務調用的時候如果沒有錯誤處理機制,那麼會導致非常多的問題。比如如果應用沒有配置超時參數,或者配置的超時參數不對,則會導致請求的調用鏈超時疊加,對於用戶來說就是請求卡住了;如果沒有重試機制,那麼因為各種原因導致的偶發故障也會導致直接返回錯誤給用戶,造成不好的用戶體驗;此外,如果某些節點異常(比如網絡中斷,或者負載很高),也會導致應用整體的響應時間變成,集群服務應該能自動避開這些節點上的應用;最後,應用也是會出現 bug 的,各種 bug 會導致某些應用不可訪問。這些問題需要每個應用能及時發現問題,並做好對應的處理措施。

雲原生 - Why is istio?(二)

應用數量的增多,對於日常的應用發佈來說也是個難題。應用的發佈需要非常謹慎,如果應用都是一次性升級的,出現錯誤會導致整個線上應用不可用,影響範圍太大;而且,很多情況我們需要同時存在不同的版本,使用 AB 測試驗證哪個版本更好;如果版本升級改動了 API,並且互相有依賴,那麼我們還希望能自動地控制發佈期間不同版本訪問不同的地址。這些問題都需要智能的流量控制機制。

雲原生 - Why is istio?(二)

為了保證整個系統的安全性,每個應用都需要實現一套相似的認證、授權、HTTPS、限流等功能。一方面大多數的程序員對安全相關的功能並不擅長或者感興趣,另外這些完全相似的內容每次都要實現一遍是非常冗餘的。這個問題需要一個能自動管理安全相關內容的系統。

雲原生 - Why is istio?(二)

上面提到的這些問題是不是非常熟悉?它們就是 istio 嘗試解決的問題,如果把上面的問題和 istio 提供的功能做個映射,你會發現它們是非常匹配,畢竟 istio 就是為了解決微服務的這些問題才出現的。

雲原生 - Why is istio?(二)

用什麼姿勢接入istio?

雖然 istio 能解決那麼多的問題,但是引入 istio 並不是沒有代價的。最大的問題是 istio 的複雜性,強大的功能也意味著 istio 的概念和組件非常多,要想理解和掌握 istio ,併成功在生產環境中部署需要非常詳細的規劃。一般情況下,集群管理團隊需要對 kubernetes 非常熟悉,瞭解常用的使用模式,然後採用逐步演進的方式把 istio 的功能分批掌控下來。

第一步,自然是在測試環境搭建一套 istio 的集群,理解所有的核心概念和組件。瞭解 istio 提供的接口和資源,知道它們的用處,思考如何應用到自己的場景中,然後是熟悉 istio 的源代碼,跟進社區的 issues,瞭解目前還存在的 issues 和 bug,思考如何規避或者修復。這一步是基礎,需要積累到 istio 安裝部署、核心概念、功能和缺陷相關的知識,為後面做好準備。

第二步,可以考慮接入 istio 的觀察性功能,包括 logging、tracing、metrics 數據。應用部署到集群中,選擇性地(一般是流量比較小,影響範圍不大的應用)為一些應用開啟 istio 自動注入功能,接管應用的流量,並安裝 prometheus 和 zipkin 等監控組件,收集系統所有的監控數據。這一步可以試探性地瞭解 istio 對應用的性能影響,同時建立服務的性能測試基準,發現服務的性能瓶頸,幫助快速定位應用可能出現的問題。此時,這些功能可以是對應用開發者透明的,只需要集群管理員感知,這樣可以減少可能帶來的風險。

第三步,為應用配置 timeout 超時參數、自動重試、熔斷和降級等功能,增加服務的容錯性。這樣可以避免某些應用錯誤進行這些配置導致問題的出現,這一步完成後需要通知所有的應用開發者刪除掉在應用代碼中對應的處理邏輯。這一步需要開發者和集群管理員同時參與。

第四步,和 ingress、helm、應用上架等相關組件和流程對接,使用 istio 接管應用的升級發佈流程。讓開發者可以配置應用灰度發佈升級的策略,支持應用的藍綠髮布、金絲雀發佈以及 AB 測試。

第五步,接入安全功能。配置應用的 TLS 互信,添加 RBAC 授權,設置應用的流量限制,提升整個集群的安全性。因為安全的問題配置比較繁瑣,而且優先級一般會比功能性相關的特性要低,所以這裡放在了最後。

當然這個步驟只是一個參考,每個公司需要根據自己的情況、人力、時間和節奏來調整,找到適合自己的方案。

總結

Istio 的架構在數據中心和集群管理中非常常見,每個 agent 分佈在各個節點上(可以是服務器、虛擬機、pod、容器)負責接收指令並執行,以及彙報信息;控制中心負責匯聚整個集群的信息,並提供 API 讓用戶對集群進行管理。kubernetes 也是類似的架構,SDN(Software Defined Network) 也是如此。相信以後會有更多類似架構的出現,這是因為數據中心要管理的節點越來越多,我們需要把任務執行分佈到各節點(agent 負責的功能),同時也需要對整個集群進行管理和控制(control plane 的功能),完全去中心化的架構是無法滿足後面這個要求的。

Istio 的出現為負責的微服務架構減輕了很多的負擔,開發者不用關心服務調用的超時、重試、rate limit 的實現,服務之間的安全、授權也自動得到了保證;集群管理員也能夠很方便地發佈應用(AB 測試和灰度發佈),並且能清楚看到整個集群的運行情況。

但是這並不表明有了 istio 就可以高枕無憂了,istio 只是把原來分散在應用內部的複雜性統一抽象出來放到了統一的地方,並沒有讓原來的複雜消失不見。因此我們需要維護 istio 整個集群,而 istio 的架構比較複雜,尤其是它一般還需要架在 kubernetes 之上,這兩個系統都比較複雜,而且它們的穩定性和性能會影響到整個集群。因此再採用 isito 之前,必須做好清楚的規劃,權衡它帶來的好處是否遠大於額外維護它的花費,需要有相關的人才對整個網絡、kubernetes 和 istio 都比較瞭解才行。

https://philcalcado.com/2017/08/03/pattern_service_mesh.html

https://istio.io/docs/concepts/what-is-istio

https://cizixs.com/2018/08/26/what-is-istio


分享到:


相關文章: