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