服務網格(Service mesh)是當前新興的架構模式,愈來愈受到人們的青睞。與Kubernetes一塊兒,服務網格能夠造成一個強大的平臺,它能夠解決在微服務集羣或服務基礎設施上發現的高度分佈式環境中出現的技術需求。服務網格是一個專門的基礎設施層,用於促進微服務之間的服務到服務通訊。git
服務網格解決了基於微服務的應用中典型的通訊需求,包括加密隧道、健康檢查、斷路器、負載均衡以及流量許可。若是離開微服務來解決這些需求,會致使開發過程當中產生高昂的費用和耗時。github
在本文中,咱們將對服務網格架構模式解決的最多見的微服務通訊需求進行概述。編程
當你意識到微服務實現了至關多的與最初分配給它們的業務邏輯無關的代碼時,問題就出現了。此外,有可能你有多個微服務在非標準化的流程中實現了相似的功能。換句話說,微服務開發團隊應該專一於業務邏輯,並將低級通訊能力留給特定的層。json
繼續推動咱們的方案,須要考慮微服務的內在動態。在給定的時間內,你可能因爲如下幾個緣由而擁有一個微服務的多個實例:api
簡而言之,微服務到微服務的通訊有特定的需求和問題須要解決。如下圖片展現了這一方案:瀏覽器
該圖示描述了幾個技術挑戰。顯然,Microservice 1的主要職責是均衡全部Microservice 2實例之間的負載。所以,Microservice 1必須弄清楚咱們在請求時刻有多少個Microservice 2實例。換句話說,Microservice 1必須實現服務發現和負載均衡。網絡
另外一方面,Microservice 2必須實現一些服務註冊功能以告知Microservice 1什麼時候有全新的實例。架構
想要擁有一個徹底動態的環境,如下這些功能應該是微服務開發的一部分:併發
總而言之,主要問題是開發團隊花費了大量資源編寫十分複雜的代碼,而這些代碼與微服務預期交付的業務邏輯不直接相關。app
如何將全部微服務均可以調用的外部標準化組件中的全部非功能和操做功能外部化?例如,下圖編譯了全部功能,這些功能不屬於給定的微服務。所以,在肯定全部功能以後,咱們須要決定在哪裏實現它們。
Solution #1 :將全部功能封裝在一個library中
開發者將負責調用library提供的函數來解決微服務通訊需求。
這個解決方案有幾個缺點:
這是一個緊密耦合的解決方案,意味着微服務高度依賴於library
這個模式對於分佈和升級新版本的library來講並不容易
這不符合微服務多語言的原則,由於這會將不一樣的編程語言應用於不一樣的上下文。
Solution #2:透明代理(Transparent Proxy)
這個解決方案實現了一樣的功能集合。可是,採用了一種很是不一樣的方法:每一個微服務都有一個特定的組件,扮演代理的角色,負責處理它的傳入和傳出流量。代理解決了咱們以前描述的庫的缺點,具體以下:
服務網格架構模式
雖然透明代理的方法給微服務開發團隊和微服務通訊需求帶來了一些好處,但仍有一些缺失的部分:
解決方案架構須要另外一個組件,這些組件將被管理員用來定義策略,它將負責向代理傳播策略。
如下圖片展現了最終架構,也就是服務網格模式:
如你所見,該模式包含了咱們所描述的兩個主要組件。
一些重要的事情須要注意:
Kong提供了一個企業級的綜合服務鏈接平臺,其包括了API gateway、Kubernetes ingress controller以及服務網格實現。該平臺容許用戶部署多個環境,如本地、混合雲、多區域以及多雲環境。
讓咱們藉助運行在獨立於雲架構(cloud-agnostic)的Kubernetes集羣上的金絲雀發佈來實現服務網格,該集羣可能包括GKE集羣或任何其餘的Kubernetes發行版。服務網格將由Kong Mesh實現,並由Kong for Kubernetes做爲Kubernetes Ingress Controller。通常而言,ingress controller負責定義進入你的Kubernetes集羣的入口點,暴露部署在其內部的微服務,並對其實行消費策略。
首先,確保你已經安裝Rancher以及正在運行一個由Rancher管理的Kubernetes集羣。在登陸到Rancher以後,選在咱們將要使用的Kubernetes集羣,在本例中爲「kong-rancher」。點擊Cluster Explorer。你將會重定向到如下頁面:
如今,讓咱們從服務網格開始:
一、 Kong Mesh Helm Chart
回到Rancher Cluster Manger主頁並再次選擇你的集羣。點擊菜單欄的「Tools」選項而後點擊Catalogs,以建立一個新的catalog。點擊Add Catalog按鈕,將Kong Mesh的Helm chart收錄其中(https://kong.github.io/kong-m...
選擇Global做爲範圍,Helm v3做爲Helm版本。
如今點擊Apps和Launch來查看在Catalog中可用的Kong Mesh。請注意,Kong做爲Rancher的合做夥伴默認提供了Kong for Kubernetes的Helm chart:
二、 安裝Kong Mesh
點擊頂部菜單欄Namespaces選項並建立一個「kong-mesh-system」命名空間。
將鼠標移到kong-rancher頂部菜單選項上,點擊kong-rancher活動集羣。
點擊Launch kubetcl
建立一個名爲「license.json」的文件,用於存放你從Kong Mesh收到的license。格式以下:
{「license」: {「version」:1,「signature」:「6a7c81af4b0a42b380be25c2816a2bb1d761c0f906ae884f93eeca1fd16c8b5107cb6997c958f45d247078ca50a25399a5f87d546e59ea3be28284c3075a9769」,「payload」: {「customer」:「Kong_SE_Demo_H1FY22」,「license_creation_date」:「2020-11-30」,「product_subscription」:「Kong Enterprise Edition」,「support_plan」:「None」,「admin_seats」:「5」,「dataplanes」:「5」,「license_expiration_date」:「2021-06-30」,「license_key」:「XXXXXXXXXXXXX」}}}
如今使用如下命令建立一個Kubernetes通用密鑰:
kubectl create secret generic kong-mesh-license -n kong-mesh-system --from-file=./license.json
關閉kubectl會話,點擊Default項目以及頂部菜單欄的Apps。點擊Launch按鈕並選擇kong-mesh Helm chart。
點擊Use an existing namespace並選擇咱們剛剛建立的那個。這有幾個參數(https://artifacthub.io/packag... Mesh,但咱們將保留全部默認值。點擊Launch以後,你應該看到Kong Mesh應用程序部署完成。
你能夠再次使用Rancher Cluster Explorer來檢查安裝。點擊左側菜單的Pods並選擇kong-mesh-system的命名空間。
你也能夠像這樣使用kubectl:
NAMESPACE NAME READY STATUS RESTARTS AGE cattle-system cattle-cluster-agent-785fd5f54d-r7x8r 1/1 Running 0 75m fleet-system fleet-agent-77c78f9c74-f97tv 1/1 Running 0 75m kong-mesh-system kuma-control-plane-5b9c6f4598-nvq8q 1/1 Running 0 16m kube-system event-exporter-gke-666b7ffbf7-n9lfl 2/2 Running 0 76m kube-system fluentbit-gke-xqsdv 2/2 Running 0 76m kube-system gke-metrics-agent-gjrqr 1/1 Running 0 76m kube-system konnectivity-agent-4c4hf 1/1 Running 0 76m kube-system kube-dns-66d6b7c877-tq877 4/4 Running 0 76m kube-system kube-dns-autoscaler-5c78d65cd9-5hcxs 1/1 Running 0 76m kube-system kube-proxy-gke-c-kpwnf-default-0-be059c1c-49qp 1/1 Running 0 76m kube-system l7-default-backend-5b76b455d-v6dvg 1/1 Running 0 76m kube-system metrics-server-v0.3.6-547dc87f5f-qntjf 2/2 Running 0 75m kube-system prometheus-to-sd-fdf9j 1/1 Running 0 76m kube-system stackdriver-metadata-agent-cluster-level-68d94db6-64n4r 2/2 Running 1 75m
三、 微服務部署
咱們的Service Mesh部署是基於一個簡單的微服務到微服務的通訊場景。因爲咱們運行的是金絲雀發佈,被調用的微服務有兩個版本:
「magnanimo」:經過Kong暴露Kubernetes ingress controller。
「benigno」:提供了一個 「hello」 endpoint,在這個端點中,它呼應了當前的datetime。它有一個金絲雀發佈,會發送一個稍微不一樣的響應。
下圖展現了這一架構:
建立一個帶有sidecar注入註釋的命名空間。你能夠再次使用Rancher Cluster Manager:選擇你的集羣,而後單擊Projects/Namespaces。點擊Add Namespace。輸入 「kong-mesh-app」 做爲名稱,幷包含一個帶有 「kuma.io/sidecar-injection」 鍵和 「enabled」 做爲其值的註釋。
固然,你也能夠選擇使用kubectl
kubectl create namespace kong-mesh-app kubectl annotate namespace kong-mesh-app kuma.io/sidecar-injection=enabled Submit the following declaration to deploy Magnanimo injecting the Kong Mesh data plane cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: magnanimo namespace: kong-mesh-app spec: replicas: 1 selector: matchLabels: app: magnanimo template: metadata: labels: app: magnanimo spec: containers: - name: magnanimo image: claudioacquaviva/magnanimo ports: - containerPort: 4000 --- apiVersion: v1 kind: Service metadata: name: magnanimo namespace: kong-mesh-app labels: app: magnanimo spec: type: ClusterIP ports: - port: 4000 name: http selector: app: magnanimo EOF
使用Rancher Cluster Manager檢查你的部署。將鼠標移動至kong-rancher菜單上,點擊Default項目,能夠看到當前的部署狀況:
點擊magnanimo檢查部署的細節,包括其pods:
點擊magnanimo pod,檢查其內部運行的容器。
咱們能夠看到,pod有兩個運行的容器:
同理,部署Benigno的時候,也有本身的sidecar:
cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: benigno-v1 namespace: kong-mesh-app spec: replicas: 1 selector: matchLabels: app: benigno template: metadata: labels: app: benigno version: v1 spec: containers: - name: benigno image: claudioacquaviva/benigno ports: - containerPort: 5000 --- apiVersion: v1 kind: Service metadata: name: benigno namespace: kong-mesh-app labels: app: benigno spec: type: ClusterIP ports: - port: 5000 name: http selector: app: benigno EOF And finally, deploy Benigno canary release. Notice that the canary release will be abstracted by the same Benigno Kubernetes Service created before: cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: benigno-v2 namespace: kong-mesh-app spec: replicas: 1 selector: matchLabels: app: benigno template: metadata: labels: app: benigno version: v2 spec: containers: - name: benigno image: claudioacquaviva/benigno\_rc ports: - containerPort: 5000 EOF
使用如下命令檢查部署和Pods:
$ kubectl get pod --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE cattle-system cattle-cluster-agent-785fd5f54d-r7x8r 1/1 Running 0 75m fleet-system fleet-agent-77c78f9c74-f97tv 1/1 Running 0 75m kong-mesh-app benigno-v1-fd4567d95-drnxq 2/2 Running 0 110s kong-mesh-app benigno-v2-b977c867b-lpjpw 2/2 Running 0 30s kong-mesh-app magnanimo-658b67fb9b-tzsjp 2/2 Running 0 5m3s kong-mesh-system kuma-control-plane-5b9c6f4598-nvq8q 1/1 Running 0 16m kube-system event-exporter-gke-666b7ffbf7-n9lfl 2/2 Running 0 76m kube-system fluentbit-gke-xqsdv 2/2 Running 0 76m kube-system gke-metrics-agent-gjrqr 1/1 Running 0 76m kube-system konnectivity-agent-4c4hf 1/1 Running 0 76m kube-system kube-dns-66d6b7c877-tq877 4/4 Running 0 76m kube-system kube-dns-autoscaler-5c78d65cd9-5hcxs 1/1 Running 0 76m kube-system kube-proxy-gke-c-kpwnf-default-0-be059c1c-49qp 1/1 Running 0 76m kube-system l7-default-backend-5b76b455d-v6dvg 1/1 Running 0 76m kube-system metrics-server-v0.3.6-547dc87f5f-qntjf 2/2 Running 0 75m kube-system prometheus-to-sd-fdf9j 1/1 Running 0 76m kube-system stackdriver-metadata-agent-cluster-level-68d94db6-64n4r 2/2 Running 1 75m $ kubectl get service --all-namespaces NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default kubernetes ClusterIP 10.0.16.1 <none> 443/TCP 79m kong-mesh-app benigno ClusterIP 10.0.20.52 <none> 5000/TCP 4m6s kong-mesh-app magnanimo ClusterIP 10.0.30.251 <none> 4000/TCP 7m18s kong-mesh-system kuma-control-plane ClusterIP 10.0.21.228 <none> 5681/TCP,5682/TCP,443/TCP,5676/TCP,5678/TCP,5653/UDP 18m kube-system default-http-backend NodePort 10.0.19.10 <none> 80:32296/TCP 79m kube-system kube-dns ClusterIP 10.0.16.10 <none> 53/UDP,53/TCP 79m kube-system metrics-server ClusterIP 10.0.20.174 <none> 443/TCP 79m
你也可使用Kong Mesh控制檯來檢查微服務和數據平面。在Terminal上運行如下命令:
kubectl port-forward service/kuma-control-plane -n kong-mesh-system 5681
重定向你的瀏覽器到http://localhost:5681/gui。點... to Dashboard和All Data Plane Proxies:
啓動一個循環,看看金絲雀發佈的運行狀況。注意服務已經被部署爲ClusterIP類型,因此你須要用 「port-forward」直接暴露它們。下一步將展現如何用Ingress Controller暴露服務。
在本地terminal上運行:
kubectl port-forward service/magnanimo -n kong-mesh-app 4000
打開另外一個Terminal,開始循環。請求要到Magnanimo提供的4000端口。路徑「/hw2 」將請求路由到Benigno服務,它後面有兩個endpoint,與Benigno兩個版本有關:
while [1]; do curl http://localhost:4000/hw2; echo; done
你應該看到相似下方的結果:
Hello World, Benigno: 2020-11-20 12:57:05.811667 Hello World, Benigno: 2020-11-20 12:57:06.304731 Hello World, Benigno, Canary Release: 2020-11-20 12:57:06.789208 Hello World, Benigno: 2020-11-20 12:57:07.269674 Hello World, Benigno, Canary Release: 2020-11-20 12:57:07.755884 Hello World, Benigno, Canary Release: 2020-11-20 12:57:08.240453 Hello World, Benigno: 2020-11-20 12:57:08.728465 Hello World, Benigno: 2020-11-20 12:57:09.208588 Hello World, Benigno, Canary Release: 2020-11-20 12:57:09.689478 Hello World, Benigno, Canary Release: 2020-11-20 12:57:10.179551 Hello World, Benigno: 2020-11-20 12:57:10.662465 Hello World, Benigno: 2020-11-20 12:57:11.145237 Hello World, Benigno, Canary Release: 2020-11-20 12:57:11.618557 Hello World, Benigno: 2020-11-20 12:57:12.108586 Hello World, Benigno, Canary Release: 2020-11-20 12:57:12.596296 Hello World, Benigno, Canary Release: 2020-11-20 12:57:13.093329 Hello World, Benigno: 2020-11-20 12:57:13.593487 Hello World, Benigno, Canary Release: 2020-11-20 12:57:14.068870
四、 控制金絲雀發佈的成本
正如咱們所見,兩個Benigno微服務發佈的請求使用了循環策略。也就是說,咱們沒法控制金絲雀發佈的花銷。Service Mesh容許咱們定義什麼時候以及如何將金絲雀發佈暴露給咱們的consumer(在本例中指Magnanimo微服務)。
要定義一個策略來控制流向兩個版本的流量,須要使用下面這個聲明。它說90%的流量應該流向當前版本,而只有10%的流量應該重定向到金絲雀發佈。
cat <<EOF | kubectl apply -f - apiVersion: kuma.io/v1alpha1 kind: TrafficRoute mesh: default metadata: namespace: default name: route-1 spec: sources: - match: kuma.io/service: magnanimo\_kong-mesh-app\_svc\_4000 destinations: - match: kuma.io/service: benigno\_kong-mesh-app\_svc\_5000 conf: split: - weight: 90 destination: kuma.io/service: benigno\_kong-mesh-app\_svc\_5000 version: v1 - weight: 10 destination: kuma.io/service: benigno\_kong-mesh-app\_svc\_5000 version: v2 EOF
應用聲明以後,你應該看到以下結果:
Hello World, Benigno: 2020-11-20 13:05:02.553389 Hello World, Benigno: 2020-11-20 13:05:03.041120 Hello World, Benigno: 2020-11-20 13:05:03.532701 Hello World, Benigno: 2020-11-20 13:05:04.021804 Hello World, Benigno: 2020-11-20 13:05:04.515245 Hello World, Benigno, Canary Release: 2020-11-20 13:05:05.000644 Hello World, Benigno: 2020-11-20 13:05:05.482606 Hello World, Benigno: 2020-11-20 13:05:05.963663 Hello World, Benigno, Canary Release: 2020-11-20 13:05:06.446599 Hello World, Benigno: 2020-11-20 13:05:06.926737 Hello World, Benigno: 2020-11-20 13:05:07.410605 Hello World, Benigno: 2020-11-20 13:05:07.890827 Hello World, Benigno: 2020-11-20 13:05:08.374686 Hello World, Benigno: 2020-11-20 13:05:08.857266 Hello World, Benigno: 2020-11-20 13:05:09.337360 Hello World, Benigno: 2020-11-20 13:05:09.816912 Hello World, Benigno: 2020-11-20 13:05:10.301863 Hello World, Benigno: 2020-11-20 13:05:10.782395 Hello World, Benigno: 2020-11-20 13:05:11.262624 Hello World, Benigno: 2020-11-20 13:05:11.743427 Hello World, Benigno: 2020-11-20 13:05:12.221174 Hello World, Benigno: 2020-11-20 13:05:12.705731 Hello World, Benigno: 2020-11-20 13:05:13.196664 Hello World, Benigno: 2020-11-20 13:05:13.680319
五、 安裝Kong for Kubernetes
讓咱們回到Rancher中安裝咱們的Kong for Kubernetes Ingress Controller,並控制服務網格的暴露。在Rancher Catalog頁面中,點擊Kong圖標。接受默認值,而後點擊Launch:
你應該看到Kong和Kong Mesh這兩個應用程序都已經部署完成:
再次使用kubectl檢查安裝:
$ kubectl get pod --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE cattle-system cattle-cluster-agent-785fd5f54d-r7x8r 1/1 Running 0 84m fleet-system fleet-agent-77c78f9c74-f97tv 1/1 Running 0 83m kong-mesh-app benigno-v1-fd4567d95-drnxq 2/2 Running 0 10m kong-mesh-app benigno-v2-b977c867b-lpjpw 2/2 Running 0 8m47s kong-mesh-app magnanimo-658b67fb9b-tzsjp 2/2 Running 0 13m kong-mesh-system kuma-control-plane-5b9c6f4598-nvq8q 1/1 Running 0 24m kong kong-kong-754cd6947-db2j9 2/2 Running 1 72s kube-system event-exporter-gke-666b7ffbf7-n9lfl 2/2 Running 0 85m kube-system fluentbit-gke-xqsdv 2/2 Running 0 84m kube-system gke-metrics-agent-gjrqr 1/1 Running 0 84m kube-system konnectivity-agent-4c4hf 1/1 Running 0 84m kube-system kube-dns-66d6b7c877-tq877 4/4 Running 0 84m kube-system kube-dns-autoscaler-5c78d65cd9-5hcxs 1/1 Running 0 84m kube-system kube-proxy-gke-c-kpwnf-default-0-be059c1c-49qp 1/1 Running 0 84m kube-system l7-default-backend-5b76b455d-v6dvg 1/1 Running 0 85m kube-system metrics-server-v0.3.6-547dc87f5f-qntjf 2/2 Running 0 84m kube-system prometheus-to-sd-fdf9j 1/1 Running 0 84m kube-system stackdriver-metadata-agent-cluster-level-68d94db6-64n4r 2/2 Running 1 84m $ kubectl get service --all-namespaces NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default kubernetes ClusterIP 10.0.16.1 <none> 443/TCP 85m kong-mesh-app benigno ClusterIP 10.0.20.52 <none> 5000/TCP 10m kong-mesh-app magnanimo ClusterIP 10.0.30.251 <none> 4000/TCP 13m kong-mesh-system kuma-control-plane ClusterIP 10.0.21.228 <none> 5681/TCP,5682/TCP,443/TCP,5676/TCP,5678/TCP,5653/UDP 24m kong kong-kong-proxy LoadBalancer 10.0.26.38 35.222.91.194 80:31867/TCP,443:31039/TCP 78s kube-system default-http-backend NodePort 10.0.19.10 <none> 80:32296/TCP 85m kube-system kube-dns ClusterIP 10.0.16.10 <none> 53/UDP,53/TCP 85m kube-system metrics-server ClusterIP 10.0.20.174 <none> 443/TCP 85m
六、 建立Ingress
經過下面的聲明,咱們將經過一個Ingress和它的路由 「/route1」 來暴露Magnanimo微服務。
cat <<EOF | kubectl apply -f - apiVersion: extensions/v1beta1 kind: Ingress metadata: name: route1 namespace: kong-mesh-app annotations: konghq.com/strip-path: "true" spec: rules: - http: paths: - path: /route1 backend: serviceName: magnanimo servicePort: 4000 EOF
如今,臨時的 「port-forward」 暴露機制能夠被正式的Ingress所取代。而咱們的循環也能夠開始消耗Ingress,結果以下: