做者:Rinor Maloku
譯者:殷龍飛
審校:孫海洲
原文:https://medium.com/google-cloud/back-to-microservices-with-istio-p1-827c872daa53
Istio 是一個由Google,IBM和Lyft團隊合做開發的開源項目,它提供了基於微服務的應用程序複雜性的解決方案,僅舉幾例:css
流量管理 :超時,重試,負載均衡,html
安全性: 最終用戶身份驗證和受權,前端
可觀察性: 跟蹤,監控和記錄。git
全部這些均可以在應用程序層中解決,可是您的服務再也不是「微型」,相對於提供業務價值的資源,實現這些的全部額外工做都是公司資源的壓力。咱們來舉個例子:github
PM:添加反饋功能須要多長時間?web
開發:兩個衝刺(敏捷開發中的術語,通常一個衝刺週期30天)。正則表達式
PM:什麼......? 那只是一個CRUD!算法
開發:建立CRUD很容易,但咱們須要對用戶和服務進行身份驗證和受權。並且因爲網絡不可靠,咱們須要在客戶端實施重試和熔斷器,並確保咱們不會佔用整個系統,咱們須要Timeout和Bulkheads,另外還要檢測咱們須要監控的問題,跟蹤[... ]sql
PM:那麼咱們就把它放在產品服務中吧。哎呀!chrome
你明白了,必須知足全部形式才能夠爲咱們添加一項巨大的服務(有不少不是業務功能的代碼)。在本文中,咱們將展現Istio如何從咱們的服務中刪除全部上述交叉問題。
注意: 本文假設您具備Kubernetes的知識。若是不是這種狀況,我建議您閱讀 我對Kubernetes的介紹,而後繼續閱讀本文。
在沒有Istio的世界中,一個服務向另外一個服務直接發出請求,而且在發生故障的狀況下,服務須要經過重試,超時,打開熔斷器等來處理它。
爲了解決這個問題,Istio經過與服務徹底分離,並經過攔截全部網絡通訊來提供一種巧妙的解決方案。這樣作能夠實現:
Fault Tolerance - 使用響應狀態代碼,它能夠在請求失敗並重試時理解。
Canary Rollouts - 僅將指定百分比的請求轉發到新版本的服務。
監控和指標 - 服務響應所花費的時間。
跟蹤和可觀察性 - 它在每一個請求中添加特殊header,並在集羣中跟蹤它們。
安全性 - 提取JWT令牌並對用戶進行身份驗證和受權。
僅舉幾例(僅舉幾例),讓您感興趣! 咱們來看一些技術細節吧!
Istio攔截全部網絡流量,並經過在每一個pod中注入智能代理做爲sidecar來應用一組規則。啓用全部功能的代理包括 數據平面, 而且這些代理可由控制平面 動態配置。
注入的代理使Istio可以輕鬆知足咱們的要求。舉個例子,咱們來看看重試和熔斷器功能。
總結一下:
Envoy將請求發送到服務B的第一個實例,但它失敗了。
Envoy sidecar重試。(1)
返回對調用代理的失敗請求。
這將打開熔斷器並在後續請求中調用下一個服務。(2)
這意味着您沒必要使用另外一個重試庫,您沒必要在編程語言X,Y或Z中開發本身的Circuit Breaking和Service Discovery實現。全部這些都是開箱即用的。這些功能都是經過Istio來實現,你不須要更改代碼。
很好! 如今你想加入Istio的航行,但你仍然有一些疑慮,一些懸而未決的問題。這是一個一刀切的方案,你對它持懷疑態度,由於它老是最終成爲一刀切的無解方案!
你最終低聲說了這個問題:「這是可配置的嗎?」
歡迎個人朋友來巡航,咱們將爲你們介紹一下控制平面。
由三個組件組成: Pilot、 Mixer 和 Citadel,它們組合使用Envoys來路由流量,實施策略和收集遙測數據。以下圖所示。
Envoy(即數據平面)使用由Istio定義的 Kubernetes自定義資源定義 進行配置。這意味着對你而言,它只是另外一個具備熟悉語法的Kubernetes資源。建立後將由控制平面獲取,並將其應用於Envoy。
咱們描述了Istio與咱們服務的關係,但咱們反過來思考一下,咱們的服務與Istio的關係是什麼?
坦率地說,咱們的服務對Istio的存在有着儘量多的瞭解,就像魚對水同樣,他們會問本身「這究竟是什麼水?」。
這意味着您能夠選擇一個工做集羣,在部署了Istio的組件後,其中的服務將繼續工做,而且以相同的方式,您能夠刪除組件,一切都會很好。能夠理解的是,您將失去Istio提供的功能。
咱們已經有足夠的理論,下面讓咱們把這些理論付諸實踐!
Istio至少須要一個具備4個vCPU和8 GB RAM的Kubernetes集羣。要快速設置集羣並跟進本文,我建議使用Google雲端平臺,它爲新用戶提供 300美圓的免費試用版 。
使用Kubernetes命令行工具建立集羣並配置訪問後,咱們已準備好使用Helm Package管理器安裝Istio。
按照官方文檔中的說明在您的計算機上安裝Helm客戶端 。咱們將在下一節中使用它來生成Istio安裝模板。
從最新版本下載Istio的資源,將內容提取到一個咱們將稱之爲的目錄中[istio-resources]
。
要輕鬆識別Istio資源 istio-system
,請在Kubernetes集羣中建立命名空間 :
$ kubectl create namespace istio-system複製代碼
而後進入到 [istio-resources]
目錄並執行如下命令來完成安裝 :
$ helm template install/kubernetes/helm/istio \ --set global.mtls.enabled = false \ --set tracing.enabled = true \ --set kiali.enabled = true \ --set grafana.enabled = true \ --namespace istio-system > istio.yaml複製代碼
上面的命令將Istio的核心組件輸出到文件 istio.yaml
中。咱們使用如下參數自定義模板:
global.mtls.enabled 設置爲false以保持引入的重點。
tracing.enabled 容許使用jaeger跟蹤請求。
kiali.enabled 在咱們的集羣中安裝Kiali以實現服務和流量的可視化
grafana.enabled 安裝Grafana,爲了收集指標的可視化。
經過執行如下命令應用生成的資源
$ kubectl apply -f istio.yaml複製代碼
這標誌着咱們集羣中Istio安裝的完成!等到istio-system
命名空間中的全部pod都處於Running或Completed狀態,執行如下命令:
$ kubectl get pods -n istio-system複製代碼
如今咱們已準備好繼續下一部分,咱們將在其中啓動並運行示例應用程序。
咱們將使用Kubernetes簡介文章中使用的相同微服務應用程序,它足以在實踐中展現Istio的功能。
該應用程序由四個微服務組成:
SA-Frontend服務 :提供前端Reactjs應用程序。
SA-WebApp服務 :處理對Sentiment Analysis的請求。
SA-Logic服務 :執行sentiment Analysis。
SA反饋服務 :接收用戶關於分析準確性的反饋。
在圖6中,除了服務以外,咱們還看到Ingress Controller在Kubernetes中將傳入的請求路由到適當的服務,Istio使用了一個名爲Ingress Gateway的相似概念,將在本文的後續部分中介紹。
要跟進本文,請克隆存儲庫istio-mastery( github.com/rinormaloku… ),其中包含Kubernetes和Istio的應用程序和清單。
注入是 自動 或 手動 完成的 。要啓用自動sidecar注入,咱們須要 istio-injection=enabled
經過執行如下命令 來標記命名空間 :
$ kubectl label namespace default istio-injection=enabled namespace/default labeled複製代碼
從如今開始,部署到默認命名空間的每一個pod都將得到注入的sidecar。爲了驗證這一點,咱們經過進入到 [istio-mastery]
存儲庫的根文件夾 並執行如下命令 來部署示例應用程序 :
$ kubectl apply -f resource-manifests/kube persistentvolumeclaim/sqlite-pvc created deployment.extensions/sa-feedback created service/sa-feedback created deployment.extensions/sa-frontend created service/sa-frontend created deployment.extensions/sa-logic created service/sa-logic created deployment.extensions/sa-web-app created service/sa-web-app created複製代碼
在部署的服務中,經過執行如下命令 kubectl get pods
驗證pod有兩個容器(service和sidecar), 並確保準備好後,咱們看到值「 2/2 」表示兩個容器都在運行。以下所示:
$ kubectl get pods NAME READY STATUS RESTARTS AGE sa-feedback-55f5dc4d9c-c9wfv 2/2 Running 0 12m sa-frontend-558f8986-hhkj9 2/2 Running 0 12m sa-logic-568498cb4d-2sjwj 2/2 Running 0 12m sa-logic-568498cb4d-p4f8c 2/2 Running 0 12m sa-web-app-599cf47c7c-s7cvd 2/2 Running 0 12m複製代碼
視覺呈如今圖7中。
如今,應用程序啓動並運行,咱們須要容許傳入流量到達咱們的應用程序。
容許流量進入集羣的最佳作法是經過Istio的 入口網關 將其自身置於集羣的邊緣,並在傳入流量上實現Istio的功能,如路由,負載均衡,安全性和監控。
在Istio的安裝過程當中, Ingress Gateway
組件和在外部公開它的服務已安裝到集羣中。要獲取服務外部IP,請執行如下命令:
$ kubectl get svc -n istio-system -l istio=ingressgateway NAME TYPE CLUSTER-IP EXTERNAL-IP istio-ingressgateway LoadBalancer 10.0.132.127 13.93.30.120複製代碼
在本文的後續部分中,咱們將訪問此IP上的應用程序(稱爲EXTERNAL-IP),爲方便起見,經過執行如下命令將其保存在變量中:
$ EXTERNAL_IP=$(kubectl get svc -n istio-system \
-l app=istio-ingressgateway \
-o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}')
複製代碼
若是您在瀏覽器中訪問此IP而且您將收到服務不可用錯誤,則 默認狀況下Istio將阻止任何傳入流量, 直到咱們定義網關。
網關是在咱們的集羣中安裝Istio時定義的Kubernetes自定義資源定義,使咱們可以指定咱們但願容許傳入流量的端口,協議和主機。
在咱們的場景中,咱們但願容許全部主機在端口80上使用HTTP流量。達到如下定義:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: http-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
複製代碼
除了選擇器istio:ingressgateway
以外,全部配置都是不須要說明的。使用此選擇器,咱們能夠指定應用配置的Ingress Gateway,在咱們的示例中,它是安裝在Istio設置上的默認入口網關控制器。
經過執行如下命令應用配置:
$ kubectl apply -f resource-manifests/istio/http-gateway.yaml
gateway.networking.istio.io/http-gateway created
複製代碼
網關如今容許在端口80中進行訪問,但它不知道在何處路由請求。這須要使用Virtual Service來實現。
VirtualService指示Ingress Gateway如何路由容許進入集羣的請求。
對於咱們度過即將到來的應用程序請求 HTTP網關 必須被路由到 sa-frontend
,sa-web-app
和sa-feedback
服務(出了如圖8)。
讓咱們分解如下路由到SA-Frontend的請求:
**/**
應將精確路徑 路由到SA-Frontend以獲取Index.html
**/static/***
應將前綴路徑 路由到SA-Frontend以獲取前端所需的任何靜態文件,如Css和JavaScript文件。
匹配正則表達式的路徑'^.*\.(ico|png|jpg)$'
應該路由到SA-Frontend,咱們應該把圖像資源路由到前端。
這是經過如下配置實現的:
kind: VirtualService
metadata:
name: sa-external-services
spec:
hosts:
- "*"
gateways:
- http-gateway # 1
http:
- match:
- uri:
exact: /
- uri:
exact: /callback
- uri:
prefix: /static
- uri:
regex: '^.*\.(ico|png|jpg)$'
route:
- destination:
host: sa-frontend # 2
port:
number: 80
複製代碼
這裏的重點是:
此VirtualService適用於經過http網關 發出的請求
Destination定義請求路由到的服務。
注意: 上面的配置位於文件中 sa-virtualservice-external.yaml
,它還包含用於路由到SA-WebApp和SA-Feedback的配置,但爲簡潔起見,已縮短。
經過執行如下命令應用VirtualService:
$ kubectl apply -f resource-manifests/istio/sa-virtualservice-external.yaml
virtualservice.networking.istio.io/sa-external-services created
複製代碼
注意: 當咱們應用Istio資源時,Kubernetes API服務器會建立一個由Istio控制平面接收的事件,而後將新配置應用於每一個pod的Envoy代理。Ingress Gateway控制器是另外一個由控制平面配置的Envoy,如圖9所示。
如今能夠訪問Sentiment Analysis應用程序了 http://{EXTERNAL-IP}/
。若是您得到Not Found狀態,請不要擔憂
。
在轉到下一部分以前,請使用該應用程序生成一些流量。
要訪問Kiali的Admin UI,請執行如下命令:
$ kubectl port-forward \
$(kubectl get pod -n istio-system -l app=kiali \
-o jsonpath='{.items[0].metadata.name}') \
-n istio-system 20001
複製代碼
並 http://localhost:20001/ 使用「admin」(不含引號)爲用戶和密碼打開登陸。有不少有用的功能,例如檢查Istio組件的配置,根據攔截網絡請求和回答收集的信息可視化服務,「誰在調用誰?」,「哪一個版本的服務有故障?」等等,花一些時間檢驗Kiali的功能,而後再轉到下一節,用Grafana可視化指標!
使用Grafana將Istio收集的指標劃分爲Prometheus和Visualized。要訪問Grafana的Admin UI,請執行如下命令並打開http://localhost:3000。
$ kubectl -n istio-system port-forward \
$(kubectl -n istio-system get pod -l app=grafana \
-o jsonpath={.items[0].metadata.name}) 3000
複製代碼
在左上角單擊菜單Home 並選擇 Istio Service Dashboard 並在左上角選擇以sa-web-app開頭的服務,您將看到收集的指標,以下圖所示:
個人媽呀,這是一個沒有任何數據的視圖,管理層永遠不會贊同這一點。讓咱們經過執行如下命令生成一些負載:
$ while true; do \
curl -i http://$EXTERNAL_IP/sentiment \
-H 「Content-type: application/json」 \
-d ‘{「sentence」: 「I love yogobella」}’; \
sleep .8; done
複製代碼
如今咱們擁有更漂亮的圖表,此外,咱們擁有Prometheus用於監控和Grafana用於可視化指標這些使人驚訝的工具,使咱們可以隨時瞭解服務的性能,健康情況,升級或降級!
最後,咱們將研究整個服務中的跟蹤請求。
咱們須要跟蹤,由於咱們所擁有的服務越多,就越難找出失敗的緣由。咱們來看下面圖片中的簡單案例:
請求進入,失敗,
?
?
?二者都有例外狀況,讓咱們來看看每一個日誌。你發現本身這麼作了多少次? 咱們的工做更像是軟件偵探而不是開發人員。
這是微服務中的一個廣泛問題,它使用分佈式跟蹤系統解決,其中服務將惟一的header相互傳遞,而後將此信息轉發到請求跟蹤放在一塊兒的分佈式跟蹤系統。一個例子如圖13所示。
Istio使用Jaeger Tracer實現OpenTracing API,這是一個獨立於供應商的框架。要訪問Jaegers UI,請執行如下命令:
$ kubectl port-forward -n istio-system \
$(kubectl get pod -n istio-system -l app=jaeger \
-o jsonpath='{.items[0].metadata.name}') 16686
複製代碼
而後在 http://localhost:16686 中打開UI,選擇 sa-web-app 服務,
服務,
。隨後單擊該按鈕 查找痕跡, 這顯示最近的痕跡,選擇任何和全部的痕跡的詳細分類將會顯示 ,如圖14所示。
跟蹤顯示:
請求來到 istio-ingressgateway (它是第一次與其中一個服務聯繫,所以對於生成跟蹤ID的請求)而後網關將請求轉發給 sa-web-app
服務。
在 sa-web-app
服務中,請求由Envoysidecar拾取並建立一個span(這就是咱們在跟蹤中看到它的緣由)並轉發到 sa-web-app
容器實例。
這裏方法 sentimentAnalysis 處理請求。這些跟蹤由應用程序生成,這意味着須要更改代碼)。
從POST請求sa-logic
開始的位置。跟蹤ID須要sa-web-app
傳遞 。
5. ...
注意 :在第4點,咱們的應用程序須要獲取Istio生成的header,並在下一個請求時將其傳遞下來,以下圖所示。
Istio作主要的繁重工做,由於它在傳入的請求上生成header,在每一個sidecar上建立新的span,傳遞它們,可是若是沒有咱們的服務傳遞header,咱們將失去請求的完整跟蹤。
要傳遞的header是:
x-request-id
x-b3-traceid
x-b3-spanid
x-b3-parentspanid
x-b3-sampled
x-b3-flags
x-ot-span-context
複製代碼
儘管這是一項簡單的任務,但已經有許多庫 能夠簡化這一過程,例如在 sa-web-app
服務中, RestTemplate 客戶端經過簡單地依賴項中 添加Jaeger和OpenTracing庫來傳遞header 。
如今,在調查咱們開箱即用(或部分開箱即用)以後,讓咱們來看看這裏的主題,細粒度路由,管理網絡流量,安全性等等!
使用Envoy的Istio爲您的集羣提供了許多新功能,從而實現:
動態請求路由 :Canary部署,A/B測試,
負載均衡: 簡單和一致的哈希平衡,
故障恢復 :超時,重試,熔斷器,
故障注入 :延遲,停止請求等
在本文的序列中,咱們將在咱們的應用程序中展現這些功能,並在此過程當中介紹一些新概念。咱們將研究的第一個概念是DestinationRules,並使用那些咱們將啓用A/B測試的概念。
當咱們有兩個版本的應用程序(一般版本視覺上有所不一樣)時使用A/B測試,而且咱們不是100%確定會增長用戶交互,所以咱們同時嘗試兩個版本並收集指標。
執行如下命令以部署演示A/B測試所需的前端的第二個版本:
$ kubectl apply -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
deployment.extensions/sa-frontend-green created
複製代碼
綠色版本的部署清單有兩點不一樣:
該image基於不一樣的標籤: istio-green
pod標有 version: green
。
而做爲雙方部署在標籤 app: sa-frontend
經過虛擬服務路由的請求 sa-external-services
的服務 sa-frontend
會被轉發到全部的實例,並將於負載採用循環算法,這將致使在圖16中提出的負載均衡問題。
找不到這些文件,由於它們在應用程序的不一樣版本中的命名方式不一樣。讓咱們驗證一下:
$ curl --silent http://$EXTERNAL_IP/ | tr '"' '\n' | grep main
/static/css/main.c7071b22.css
/static/js/main.059f8e9c.js
$ curl --silent http://$EXTERNAL_IP/ | tr '"' '\n' | grep main
/static/css/main.f87cd8c9.css
/static/js/main.f7659dbb.js
複製代碼
這意味着請求一個版本的靜態文件的index.html
能夠被負載均衡到提供另外一個版本的pod,其中能夠理解的是其餘文件不存在。
這意味着,爲了讓咱們的應用程序正常工做,咱們須要引入限制「爲index.html服務的應用程序的版本,必須爲後續請求提供服務」。
咱們將使用Consistent Hash Loadbalancing來實現這一點,這 是 使用預約義屬性(例如HTTP header)未來自同一客戶端的請求轉發到同一後端實例的過程。由 DestionatioRules提供。
在 VirtualService 將請求路由到正確的服務以後,而後使用 DestinationRules, 咱們能夠指定適用於此服務實例的流量的策略,如圖17所示。
注意: 圖17以易於理解的方式可視化Istio資源如何影響網絡流量。可是,準確地說,決定將請求轉發到哪一個實例是由CRD配置的Ingress Gateway的Envoy作出的。
使用目標規則,咱們能夠將負載均衡配置爲具備一致性哈希,並確保同一用戶由同一服務實例響應。經過如下配置實現:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: sa-frontend
spec:
host: sa-frontend
trafficPolicy:
loadBalancer:
consistentHash:
httpHeaderName: version # 1
複製代碼
根據「version」標頭的內容生成一致的哈希。
經過執行如下命令應用配置並嘗試一下!
$ kubectl apply -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml
destinationrule.networking.istio.io/sa-frontend created
複製代碼
執行如下命令並驗證在指定版本header時是否得到相同的文件:
$ curl --silent -H "version: yogo" http://$EXTERNAL_IP/ | tr '"' '\n' | grep main
複製代碼
注意: 爲了方便在瀏覽器中進行測試,您可使用此 Chrome擴展程序 向版本header添加不一樣的值,。
DestinationRules具備更多LoadBalancing功能,全部詳細信息均可以查看 官方文檔 。
在繼續更詳細地探索VirtualService以前,請執行如下命令,刪除應用程序的綠色版本和目標規則:
$ kubectl delete -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
deployment.extensions 「sa-frontend-green」 deleted
$ kubectl delete -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml
destinationrule.networking.istio.io 「sa-frontend」 deleted
複製代碼
當咱們想要測試生產中的更改但不影響最終用戶時,會使用影子或鏡像,所以咱們將請求鏡像到具備更改並評估它的第二個實例中。
要測試此功能,能夠 經過執行如下命令 建立SA-Logic的第二個實例(
):
$ kubectl apply -f resource-manifests/kube/shadowing/sa-logic-service-buggy.yaml
deployment.extensions/sa-logic-buggy created
複製代碼
執行如下命令並驗證全部實例都標有相應的版本,另外還有app=sa-logic
標記:
$ kubectl get pods -l app=sa-logic --show-labels
NAME READY LABELS
sa-logic-568498cb4d-2sjwj 2/2 app=sa-logic,version=v1
sa-logic-568498cb4d-p4f8c 2/2 app=sa-logic,version=v1
sa-logic-buggy-76dff55847-2fl66 2/2 app=sa-logic,version=v2
sa-logic-buggy-76dff55847-kx8zz 2/2 app=sa-logic,version=v2
複製代碼
當 sa-logic
服務目標pod標記爲 app=sa-logic
時,任何傳入請求將在全部實例之間進行負載均衡,如圖18所示。
但咱們但願將請求路由到版本爲v1的實例,並鏡像到版本爲v2的實例,如圖19所示。
這是使用VirtualService與DestinationRule結合實現的,其中目標規則指定到特定子集的子集和VirtualService路由。
咱們使用如下配置定義子集:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: sa-logic
spec:
host: sa-logic # 1
subsets:
- name: v1 # 2
labels:
version: v1 # 3
- name: v2
labels:
version: v2
複製代碼
主機定義此規則僅在向 sa-logic
服務發生路由時適用
路由到子集實例時使用的子集名稱。
Label定義了須要匹配的鍵值對,以使實例成爲子集的一部分。
應用執行如下命令的配置:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-destinationrule.yaml
destinationrule.networking.istio.io/sa-logic created
複製代碼
經過定義子集,咱們能夠繼續並配置VirtualService以應用於請求 sa-logic
所在的請求:
路由到名爲v1的子集,
鏡像到名爲v2的子集。
這是經過如下清單實現的:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sa-logic
spec:
hosts:
- sa-logic
http:
- route:
- destination:
host: sa-logic
subset: v1
mirror:
host: sa-logic
subset: v2
複製代碼
因爲一切配置都是不言自明的,讓咱們看看它的執行:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-shadowing-vs.yaml
virtualservice.networking.istio.io/sa-logic created
複製代碼
經過執行如下命令添加一些負載:
$ while true; do curl -v http://$EXTERNAL_IP/sentiment \
-H 「Content-type: application/json」 \
-d ‘{「sentence」: 「I love yogobella」}’; \
sleep .8; done
複製代碼
檢查Grafana中的結果,在那裏咱們能夠看到有錯誤的版本大約有60%的請求失敗,但沒有一個失敗影響最終用戶,由於它們被當前活動的服務響應。
在本節中,咱們第一次看到應用於咱們服務的envoy的VirtualService,當對此 sa-web-app
提出請求時, sa-logic
經過sidecar Envoy,經過VirtualService配置爲路由到子集v1並鏡像到服務的子集v2 sa-logic
。
我能夠看到你在想「Darn man Virtual Services很簡單!」,在下一節中,咱們將把句子擴展爲「Simply Amazing!」。
Canary Deployment是向少數用戶推出新版本應用程序的過程,做爲驗證缺乏問題的一個步驟,而後向更普遍的受衆提供更高質量的發佈保證。
咱們將繼續使用相同的buggy子集 sa-logic
來演示canary部署。
讓咱們大膽地開始,經過應用下面的VirtualService,將20%的用戶發送到有缺陷的版本(這表明金絲雀部署)和80%的健康服務:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sa-logic
spec:
hosts:
- sa-logic
http:
- route:
- destination:
host: sa-logic
subset: v1
weight: 80 # 1
- destination:
host: sa-logic
subset: v2
weight: 20 # 1
複製代碼
權重指定要轉發到目標或目標子集的請求的百分比。
sa-logic
使用如下命令 更新之前的 虛擬服務配置:
$ kubectl apply -f resource-manifests/istio/canary/sa-logic-subsets-canary-versusyaml
virtualservice.networking.istio.io/sa-logic configured
複製代碼
咱們當即看到咱們的一些請求失敗了:
$ while true; do \
curl -i http://$EXTERNAL_IP/sentiment \
-H 「Content-type: application/json」 \
-d ‘{「sentence」: 「I love yogobella」}’ \
--silent -w 「Time: %{time_total}s \t Status: %{http_code}\n」 \
-o /dev/null; sleep .1; done
Time: 0.153075s Status: 200
Time: 0.137581s Status: 200
Time: 0.139345s Status: 200
Time: 30.291806s Status: 500
複製代碼
VirtualServices啓用了Canary Deployments,經過這種方法,咱們將潛在的損害減小到了20%的用戶羣。漂亮! 如今,每當咱們對代碼不安全時,咱們就可使用Shadowing和Canary Deployments,換句話說,老是如此。😜
代碼並不老是錯誤的。在「 分佈式計算的8個謬誤 」列表中,第一個謬論是「網絡可靠」。網絡不可靠,這就是咱們須要超時和重試的緣由。
出於演示目的,咱們將繼續使用有缺陷的版本 sa-logic
,其中隨機故障模擬網絡的不可靠性。
有缺陷的服務有三分之一的機會花費太長時間來響應,三分之一的機會之內部服務器錯誤結束,其他的成功完成。
爲了緩解這些問題並改善用戶體驗,咱們能夠:
若是服務時間超過8秒,則超時
重試失敗的請求。
這是經過如下資源定義實現的:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sa-logic
spec:
hosts:
- sa-logic
http:
- route:
- destination:
host: sa-logic
subset: v1
weight: 50
- destination:
host: sa-logic
subset: v2
weight: 50
timeout: 8s # 1
retries:
attempts: 3 # 2
perTryTimeout: 3s # 3
複製代碼
請求的超時時間爲8秒,
它嘗試了3次,
若是嘗試時間超過3秒,則嘗試將請求標記爲失敗。
這是一種優化,由於用戶不會等待超過8秒,而且咱們在發生故障時重試三次,從而增長了致使響應成功的機會。
使用如下命令應用更新的配置:
$ kubectl apply -f resource-manifests/istio/retries/sa-logic-retries-timeouts-vs.yaml
virtualservice.networking.istio.io/sa-logic configured
複製代碼
並查看Grafana圖表,瞭解成功率的改善狀況(如圖21所示)。
在 sa-logic-buggy
經過執行如下命令 進入下一部分delete 和VirtualService 以前 :
$ kubectl delete deployment sa-logic-buggy
deployment.extensions 「sa-logic-buggy」 deleted
$ kubectl delete virtualservice sa-logic
virtualservice.networking.istio.io 「sa-logic」 deleted
複製代碼
微服務架構中的兩個重要模式,能夠實現服務的自我修復。
該 熔斷器 是用來阻止請求將視爲不健康服務的一個實例,並使它可以恢復,在此期間客戶端的請求轉發到該服務的健康狀況(增長成功率)。
該 隔離模式 整個系統降級來隔離錯誤,防止錯誤傳播,舉一個隔離故障例子,服務B處於損壞狀態和其它服務(服務B的客戶端)發出請求到服務B,這將致使該客戶端將使用了本身的線程池,將沒法提供其餘請求(即便這些請求與服務B無關)。
我將跳過這些模式的實現,由於您能夠查看 官方文檔中的實現,我很興奮地展現身份驗證和受權,這將是下一篇文章的主題。
在本文中,咱們在Kubernetes集羣中部署了Istio,並使用其自定義資源定義(如 網關, VirtualServices, DestinationRules 及其組件)啓用瞭如下功能:
使用 Kiali,經過查看正在運行的服務,它們如何執行,以及它們關係,來觀察咱們的服務 。
使用 Prometheus 和 Grafana 進行收集和可視化 。
請求 Jaeger 跟蹤 (Hunter的德語)。
對網絡流量進行全面細粒度控制,實現 Canary Deployments, A/B測試和Shadowing 。
輕鬆實現 重試,超時和CircuitBreakers 。
全部這些均可以在沒有代碼更改或任何其餘依賴性的狀況下實現,從而使您的服務保持小巧,易於操做和維護
對於您的開發團隊來講,消除這些跨領域的問題並將它們集中到Istio的控制平面,意味着新服務很容易引入,它們不會佔用大量資源,由於開發人員能夠專一於解決業務問題。到目前爲止,沒有任何開發人員抱怨「必須解決有趣的業務問題!」。
我很樂意在下面的評論中聽到您的想法,並隨時在 Twitter 或個人頁面 rinormaloku.com 上與我 聯繫,並繼續關注下一篇文章,咱們將解決最後一層認證和受權問題!