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