使用K8s遇難題?Istio來(lái)幫您!
如果你正在使用容器,特別是Kubernetes,那么你應(yīng)該也聽(tīng)說(shuō)過(guò)Istio。對(duì)于初學(xué)者來(lái)說(shuō),Istio是Kubernetes的服務(wù)網(wǎng)格(service mesh)。所謂服務(wù)網(wǎng)格,它是一個(gè)網(wǎng)絡(luò)層,并且可以動(dòng)態(tài)管理服務(wù)流量,然后以安全的方式進(jìn)行管理。
如何充分使用Istio,這不是一篇博客文章能闡述清楚的。因此,在本文中我將介紹一些它的特性,更重要的是,你可以通過(guò)這篇文章,了解到一些方法來(lái)自動(dòng)化解決某些實(shí)際問(wèn)題。
Istio可以讓你使用一組自定義Kubernetes資源來(lái)管理網(wǎng)絡(luò)流量,并且可以幫助你保護(hù)和加密服務(wù)之間以及集群內(nèi)外的網(wǎng)絡(luò)流量。它全面集成了Kubernetes API,這意味著可以使用與其他Kubernetes配置完全相同的方式來(lái)定義和管理Istio設(shè)置。
權(quán)衡利弊,再做選擇
如果要開(kāi)始使用Istio,首先應(yīng)該問(wèn)自己為什么。Istio提供了一些非常有價(jià)值的功能,如金絲雀發(fā)布等,但是如果不增加一些復(fù)雜性,就無(wú)法使用它們。你還需要投入一定的時(shí)間來(lái)學(xué)習(xí)它。也就是說(shuō),如果你的情況合適使用它,你可以(并且應(yīng)該)在自己的集群中謹(jǐn)慎且逐步地采用Istio的功能。
如果你要從頭開(kāi)始構(gòu)建新環(huán)境,并且經(jīng)過(guò)利弊權(quán)衡決定繼續(xù)使用Istio,那么一定要從一開(kāi)始就使用嚴(yán)格的相互TLS對(duì)其進(jìn)行設(shè)置,并積極使用其強(qiáng)大的功能。具體操作請(qǐng)參考
為了使一切都有價(jià)值并且具有一定的性價(jià)比,我們需要在實(shí)際應(yīng)用程序的上下文中考慮Istio,但是如果沒(méi)有快速免責(zé)聲明的話,最好不要這樣做。如果你只需要管理少量服務(wù)(且位于單個(gè)集群內(nèi)),那么引入Istio的性價(jià)比相對(duì)而言沒(méi)有那么高。
本文中的代碼示例不一定能夠完全幫助你解決你的問(wèn)題,但是如果你需要所有的代碼以及如何使用它的詳細(xì)說(shuō)明都可以在GitLab上找到
接下來(lái)是你在Cloud Native旅程中可能遇到的兩個(gè)常見(jiàn)問(wèn)題,以及如何使用Istio來(lái)解決這些問(wèn)題。
問(wèn)題1:我不相信我的測(cè)試
如果測(cè)試范圍并沒(méi)有完全涵蓋你所更改的應(yīng)用程序,那么你可能會(huì)很快采取行動(dòng)進(jìn)行新一輪測(cè)試,但也有可能應(yīng)用程序無(wú)法正常運(yùn)行了。
在理想狀況下,我們都想要確保每個(gè)代碼經(jīng)過(guò)全面的測(cè)試,否則就不會(huì)將功能添加到應(yīng)用程序中。但是現(xiàn)實(shí)總歸是骨感的,我們常常被ddl追趕,可能還未編寫或者更新測(cè)試,功能就得上傳到項(xiàng)目中了。
解決方案:放慢速度
那么,如何確保我絕大多數(shù)用戶不受代碼中潛伏的任何錯(cuò)誤的影響,又如何進(jìn)行更改和部署新功能呢?答案是通過(guò)先將新版本部署到最少數(shù)量的用戶來(lái)最大程度地減少這些小問(wèn)題的輻射范圍。
如果更改能夠按照預(yù)期工作的話,你可以緩慢增加使用新版本的用戶百分比。如果各項(xiàng)指標(biāo)出現(xiàn)問(wèn)題,你可以輕松回滾你的更改,然后重試。
在沒(méi)有Istio的情況下可以在Kubernetes上運(yùn)行金絲雀部署嗎?當(dāng)然沒(méi)問(wèn)題,但是如果要自動(dòng)化這一過(guò)程,你需要完全將自己的精力放在web服務(wù)器代碼和自定義自動(dòng)化腳本方面。這樣的操作方式性價(jià)比并不高。
Istio有一些十分優(yōu)雅的流量分配解決方案,我們可以使用它們?cè)谇‘?dāng)?shù)臅r(shí)間為合適的版本提供適當(dāng)?shù)目蛻舳朔?wù),并且我們只需調(diào)整其中的1個(gè)或2個(gè)參數(shù)。
為了實(shí)現(xiàn)這一點(diǎn),你需要設(shè)置一個(gè)網(wǎng)關(guān)入口(Ingress gateway)、一個(gè)虛擬服務(wù)(virtual service)和一個(gè)destination rule。這將位于一般的部署和服務(wù)之上,并為你分配流量。
- apiVersion: networking.istio.io/v1alpha3
- kind: Gateway
- metadata:
- name: http-gateway
- spec:
- selector:
- istio: ingressgateway
- servers:
- - port:
- number: 80
- name: http
- protocol: HTTP
- hos
- ts:
- - "*"
- apiVersion: networking.istio.io/v1alpha3
- kind: VirtualService
- metadata:
- name: my-app
- spec:
- hosts:
- - "*"
- gateways:
- - http-gateway
- http:
- - match:
- - uri:
- prefix: "/my-app"
- rewrite:
- uri: "/"
- route:
- - destination:
- host: my-app
- subset: v1
- port:
- number: 80
- weight: 90
- - destination:
- host: my-app
- subset: v2
- port:
- number: 80
- weight: 10
- apiVersion: networking.istio.io/v1alpha3
- kind: DestinationRule
- metadata:
- name: my-app
- spec:
- host: my-app
- subsets:
- - name: v1
- labels:
- version: v1.0.0
- - name: v2
- labels:
- version: v2.0.0
從虛擬服務(wù)的權(quán)重字段中可以看到,Istio將根據(jù)指定的值在應(yīng)用程序的兩個(gè)版本之間分配流量。這些值的總和必須為100%,否則,API將拒絕應(yīng)用該定義。
然后,你(或者理想情況下,在“持續(xù)集成/連續(xù)交付”流水線中手動(dòng)執(zhí)行一個(gè)或多個(gè)步驟)將調(diào)整權(quán)重,以將新版本推廣給更多用戶,直到所有請(qǐng)求由新版本滿足為止,并且以前的版本可以停止維護(hù)。
通過(guò)使用Istio的故障注入功能來(lái)模擬網(wǎng)絡(luò)中斷和實(shí)際流量性能下降,還可以將Istio集成到您的集成測(cè)試策略中。
如果在生產(chǎn)中進(jìn)行測(cè)試的想法給你留下了心理陰影,那一定是你的做法有所欠缺。例如,嘗試在你的虛擬服務(wù)規(guī)范中添加以下代碼片段以添加一些混亂,然后再找一篇文章來(lái)看看怎么用Istio解決這樣的混亂。
- spec:
- hosts:
- - my-app
- http:
- - fault:
- delay:
- fixedDelay: 7s
- percent: 100
- route:
- - destination:
- host: ratings
- subset: v2
問(wèn)題2:市場(chǎng)策略無(wú)法確定發(fā)布版本
通常,業(yè)務(wù)需要針對(duì)實(shí)際用戶測(cè)試應(yīng)用程序的多個(gè)版本。但是有時(shí)實(shí)在無(wú)法搞清楚是哪種營(yíng)銷策略可以帶來(lái)最佳轉(zhuǎn)化率,或者哪種設(shè)計(jì)選擇可以帶來(lái)最佳的客戶留存率。
使用Kubernetes,你可以將流量分為兩個(gè)版本,但是要想從練習(xí)中獲得任何有價(jià)值的見(jiàn)解,則再次需要一大堆自定義代碼來(lái)獲取相關(guān)信息,并以非技術(shù)同事可以理解的方式對(duì)其進(jìn)行處理。
解決方案:使用Istio進(jìn)行A/B測(cè)試
Istio的流量分配規(guī)則可以再次解決這一問(wèn)題,它與Prometheus和Grafana的緊密集成可以幫助你獲取直觀的A/B測(cè)試的結(jié)果。一般而言,根據(jù)傳入數(shù)據(jù)包內(nèi)容的某些部分,幾乎有無(wú)數(shù)種方法來(lái)決定哪些用戶可以獲取你的應(yīng)用程序的版本。
在這一示例中,我們將使用User-Agent字段為不同的瀏覽器提供不同的版本。
- apiVersion: networking.istio.io/v1alpha3
- kind: VirtualService
- metadata:
- name: my-app
- spec:
- hosts:
- - "*"
- gateways:
- - http-gateway
- http:
- - match:
- - headers:
- user-agent:
- regex: ".*Chrome.*"
- uri:
- prefix: "/my-app"
- rewrite:
- uri: "/"
- route:
- - destination:
- host: my-app
- subset: v1
- port:
- number: 80
- - match:
- - headers:
- user-agent:
- regex: ".*Mozilla.*"
- uri:
- prefix: "/my-app"
- rewrite:
- uri: "/"
- route:
- - destination:
- host: my-app
- subset: v2
- port:
- number: 80
從上面的代碼中可以看到,使用Firefox的用戶將獲得應(yīng)用程序的版本1,而Chrome用戶將獲得版本2。如果瀏覽器的“User-Agent”字段不包含“mozilla”或“chrome”,則他們都將不會(huì)獲得任一版本。
要為其他客戶提供服務(wù),您需要添加一條默認(rèn)路由,我將作為練習(xí)留給你。(嘿嘿)
如果你不想安裝其他瀏覽器,只是想嘗試一下,則可以使用帶有頭部標(biāo)志的curl偽裝成所需的任何瀏覽器,例如:
- curl /my-app -H "User-Agent: Chrome"
通過(guò)更改user-agent的值,你可以從命令行測(cè)試所有不同的路由。
總 結(jié)
以上兩種情況大概能讓你體驗(yàn)到Istio強(qiáng)大功能的冰山一角。正如上文所說(shuō),如果沒(méi)有Istio,你依然可以進(jìn)行金絲雀部署和A/B測(cè)試,只是你必須自己實(shí)現(xiàn)流量分配。但這大大增加了開(kāi)發(fā)部署的復(fù)雜性,實(shí)屬性價(jià)比低之選。
我希望這篇文章可以讓你對(duì)Istio的實(shí)際應(yīng)用有很好的理解,并且十分期待你自己嘗試一下。如果你想了解更多關(guān)于Istio的信息,可以訪問(wèn)它們的官網(wǎng),上面有許多有用的資料
值得一提的是,Rancher 2.3 Preview2版本上開(kāi)始支持Istio,用戶可以直接在UI界面中啟動(dòng)Istio并且可以為每個(gè)命名空間注入自動(dòng)sidecar。此外,Rancher簡(jiǎn)化Istio的安裝和配置,內(nèi)置了一個(gè)支持Kiali的儀表盤,用于流量和遙測(cè)的可視化,然后用Jaeger進(jìn)行追蹤,甚至還有自己的Prometheus和Grafana(與用于高級(jí)監(jiān)控的實(shí)例不同)。這一切讓部署和管理Istio變得簡(jiǎn)單而快速。
有關(guān)發(fā)行說(shuō)明和安裝步驟,請(qǐng)?jiān)L問(wèn)GitHub。