服務(wù)網(wǎng)格仍然很難
來(lái)源:6d.cn/8gd2
北美KubeCon + CloudNativeCon虛擬大會(huì)贊助商客座文章作者:Lin Sun,IBM高級(jí)技術(shù)人員
在今年8月的歐洲ServiceMeshCon會(huì)議上,來(lái)自Linkerd的William Morgan和我共同發(fā)表了篇題為service mesh is still hard的演講。William詳細(xì)介紹了對(duì)Linkerd的改進(jìn),而我介紹了對(duì)Istio的改進(jìn)。很明顯,這兩個(gè)項(xiàng)目都在努力讓用戶更容易地采用服務(wù)網(wǎng)格(service mesh)。
服務(wù)網(wǎng)格已經(jīng)比一、兩年前成熟了很多,但是對(duì)于用戶來(lái)說(shuō)仍然很困難。服務(wù)網(wǎng)格有兩種類型的技術(shù)角色,平臺(tái)所有者(platform owner)和服務(wù)所有者(service owner)。平臺(tái)所有者,也稱為網(wǎng)格管理員,擁有服務(wù)平臺(tái),并為服務(wù)所有者定義采用服務(wù)網(wǎng)格的總體策略和實(shí)現(xiàn)。服務(wù)所有者在網(wǎng)格中擁有一個(gè)或多個(gè)服務(wù)。
平臺(tái)所有者使用服務(wù)網(wǎng)格變得更加容易,因?yàn)檫@些項(xiàng)目正在實(shí)現(xiàn)簡(jiǎn)化網(wǎng)絡(luò)配置、安全策略配置和整個(gè)網(wǎng)格可視化的方法。例如,在Istio中,平臺(tái)所有者可以按照他們喜歡的范圍設(shè)置Istio身份驗(yàn)證策略或授權(quán)策略。在將目標(biāo)服務(wù)的實(shí)際路由行為和流量策略委托給服務(wù)所有者時(shí),平臺(tái)所有者可以在主機(jī)/端口/TLS相關(guān)設(shè)置上配置入口網(wǎng)關(guān)。實(shí)現(xiàn)經(jīng)過(guò)良好測(cè)試的常見場(chǎng)景的服務(wù)所有者從Istio的可用性改進(jìn)中獲益,可以輕松地將其微服務(wù)裝載到網(wǎng)格中。實(shí)現(xiàn)不太常見場(chǎng)景的服務(wù)所有者繼續(xù)遇到陡峭的學(xué)習(xí)曲線。
我相信服務(wù)網(wǎng)還是很難,原因如下:
1. 缺乏關(guān)于是否需要服務(wù)網(wǎng)格的明確指導(dǎo)
在用戶開始評(píng)估多個(gè)服務(wù)網(wǎng)格或深入到一個(gè)特定的服務(wù)網(wǎng)格之前,他們需要關(guān)于服務(wù)網(wǎng)格是否有用的指導(dǎo)。不幸的是,這并不是一個(gè)簡(jiǎn)單的是或不是的問(wèn)題。有多個(gè)因素需要考慮:
你的工程組織里有多少人?
你有多少微服務(wù)?
這些微服務(wù)使用什么語(yǔ)言?
你有采用開源項(xiàng)目的經(jīng)驗(yàn)嗎?
你在哪些平臺(tái)上運(yùn)行你的服務(wù)?
你從服務(wù)網(wǎng)格需要什么功能?
對(duì)于一個(gè)給定的服務(wù)網(wǎng)格項(xiàng)目,這些特性是否穩(wěn)定?
更復(fù)雜的是,對(duì)于不同的服務(wù)網(wǎng)格項(xiàng)目,答案可能是不同的。甚至在Istio 1.5之前的早期版本中,我們也采用了微服務(wù)來(lái)充分利用網(wǎng)格,但是我們決定將多個(gè)Istio控制面組件轉(zhuǎn)換為一個(gè)獨(dú)立的應(yīng)用程序來(lái)降低操作的復(fù)雜性。對(duì)于這種情況,運(yùn)行一個(gè)單體服務(wù)比運(yùn)行4個(gè)或5個(gè)微服務(wù)更合理。
2. 你的服務(wù)可能會(huì)在射入邊車后立即中斷
去年感恩節(jié),我試圖幫助一個(gè)用戶在網(wǎng)格運(yùn)行一個(gè)Zookeeper服務(wù),使用最新的Zookeeper Helm chart。Zookeeper作為Kubernetes StatefulSet運(yùn)行。當(dāng)我試圖將Envoy邊車(sidecar)代理注入到每個(gè)Zookeeper pod時(shí),由于無(wú)法建立領(lǐng)導(dǎo)者和成員之間的溝通,Zookeeper pod無(wú)法運(yùn)行并一直重啟。默認(rèn)情況下,Zookeeper監(jiān)聽pod的IP地址,以實(shí)現(xiàn)服務(wù)器之間的通信。然而,Istio和其他服務(wù)網(wǎng)格需要localhost(127.0.0.1)作為偵聽的地址,這使得Zookeeper服務(wù)器無(wú)法彼此通信。

通過(guò)與上游社區(qū)的合作,我們?yōu)閆ookeeper以及Casssandra、Elasticsearch、Redis和Apache NiFi添加了個(gè)配置應(yīng)變方法。我確信還有其他應(yīng)用程序與邊車不兼容。如果你知道任何一些,請(qǐng)通知社區(qū)。
https://istio.io/latest/faq/applications/#zookeeper
3. 你的服務(wù)在開始或停止時(shí)可能有奇怪的行為
應(yīng)用程序容器可能在邊車之前啟動(dòng),并導(dǎo)致應(yīng)用程序失敗。在停止時(shí)間也會(huì)發(fā)生類似的挑戰(zhàn),即邊車可能會(huì)在應(yīng)用程序容器之前停止。
Kubernetes缺乏聲明容器依賴關(guān)系的標(biāo)準(zhǔn)方法。有個(gè)邊車Kubernetes增強(qiáng)建議(KEP),但是它還沒(méi)有在Kubernetes的版本中實(shí)現(xiàn),需要一段時(shí)間才能穩(wěn)定下來(lái)?,F(xiàn)在,服務(wù)所有者可能會(huì)在啟動(dòng)或停止時(shí)觀察到意外的行為。
https://github.com/kubernetes/enhancements/issues/753
為了幫助解決這個(gè)問(wèn)題,Istio為平臺(tái)所有者實(shí)現(xiàn)了個(gè)全局配置選項(xiàng),可以延遲應(yīng)用程序的啟動(dòng),直到邊車準(zhǔn)備就緒。Istio很快也將允許服務(wù)所有者在pod級(jí)別上進(jìn)行配置。
4. 服務(wù)零配置可以,零代碼更改不可行
服務(wù)網(wǎng)格項(xiàng)目的主要目標(biāo)之一是為服務(wù)所有者提供零配置。一些像Istio這樣的項(xiàng)目已經(jīng)添加了智能協(xié)議檢測(cè)來(lái)幫助檢測(cè)協(xié)議并簡(jiǎn)化網(wǎng)格的加載體驗(yàn),然而,我們?nèi)匀唤ㄗh用戶在生產(chǎn)中顯式聲明協(xié)議。隨著Kubernetes中添加了appProtocol設(shè)置,服務(wù)所有者現(xiàn)在有了種標(biāo)準(zhǔn)的方法來(lái)為運(yùn)行在新的Kubernetes版本(例如1.19)中的Kubernetes服務(wù)配置應(yīng)用程序協(xié)議。
https://kubernetes.io/docs/concepts/services-networking/service/#application-protocol
不幸的是,要充分利用服務(wù)網(wǎng)格的強(qiáng)大功能,零代碼更改并不可行。
為了讓服務(wù)所有者和平臺(tái)所有者正確地觀察服務(wù)跟蹤,在服務(wù)之間傳播跟蹤頭非常重要。
為了避免混淆和意外行為,重新檢查服務(wù)代碼中的重試和超時(shí)非常重要,以查看是否應(yīng)該調(diào)整它們,并了解它們的行為與邊車代理配置的重試和超時(shí)之間的關(guān)系。
為了讓邊車代理檢查從應(yīng)用程序容器發(fā)送的流量并智能地利用內(nèi)容來(lái)做出決策,例如基于請(qǐng)求的路由或基于標(biāo)頭的授權(quán),對(duì)于服務(wù)所有者而言,確保從源服務(wù)發(fā)送純流量“plain traffic”到目標(biāo)服務(wù)至關(guān)重要,并信任邊車代理安全地升級(jí)連接。
5. 服務(wù)所有者需要了解客戶端和服務(wù)端配置的細(xì)微差別
在使用服務(wù)網(wǎng)格之前,我不知道Envoy代理有這么多配置是與超時(shí)和重試有關(guān)。大多數(shù)用戶都熟悉請(qǐng)求超時(shí)、空閑超時(shí)和重試次數(shù),但有一些細(xì)微差別和復(fù)雜性:
當(dāng)涉及到空閑超時(shí)時(shí),HTTP協(xié)議下有個(gè)idle_timeout,它應(yīng)用于HTTP連接管理器和上游集群HTTP連接。對(duì)于不存在上游或下游活動(dòng)的流,可以使用stream_idle_timeout,甚至可以使用idle_timeout路由覆蓋stream_idle_timeout。
自動(dòng)重試也很復(fù)雜。重試不僅僅是重試的次數(shù),而是允許的最大重試次數(shù)(可能不是實(shí)際的重試次數(shù))。實(shí)際的重試數(shù)量取決于重試條件、路由請(qǐng)求超時(shí)和重試之間的間隔,這些必須在請(qǐng)求超時(shí)和重試的總體預(yù)算之內(nèi)。
在非服務(wù)網(wǎng)格環(huán)境中,源和目標(biāo)容器之間只有一個(gè)連接池,但在服務(wù)網(wǎng)格環(huán)境中,有三個(gè)連接池:
源容器到源邊車代理
源邊車代理到目標(biāo)邊車?yán)?/span>
目標(biāo)邊車代理到目標(biāo)容器
每個(gè)連接池都有自己的單獨(dú)配置。Karl Stoney有個(gè)很棒的博客,解釋了其中的復(fù)雜性,以及這三個(gè)連接池任何一個(gè)可能會(huì)出現(xiàn)錯(cuò)誤,以及需要進(jìn)行哪些檢查才能修復(fù)它們。
https://karlstoney.com/2019/05/31/istio-503s-ucs-and-tcp-fun-times/
總結(jié)
我希望上述挑戰(zhàn)能與你產(chǎn)生共鳴,無(wú)論你在何階段采用服務(wù)網(wǎng)格。我期待著觀察所有項(xiàng)目的創(chuàng)新,因?yàn)槲覀冋κ狗?wù)網(wǎng)格盡可能的無(wú)聊但有用。
