istio-dapr 構建多運行時服務網格
多運行時是一個非常新的概念。在 2020 年,Bilgin Ibryam 提出了 Multi-Runtime(多運行時)的理念,對基於 Sidecar 模式的各種產品形態進行了實踐總結和理論昇華。那到底什麼是多運行時呢?首先還是得從分佈式應用的四大類基本需求講起。簡單來講任何分佈式應用都存在的四大類基本需求:
1、生命週期:包括部署,健康檢查,水平擴展,配置管理等,目前這些需求的最佳實踐,都陸續在 kubernetes 上有了落地。
2、網絡:網絡方面的需求 是 service Mesh 的主戰場,比如 istio 可以滿足這裏絕大部分需求,除了 pub/sub。
3、狀態:包括數據的讀寫,狀態其實是非常難以管理的,涉及冪等,緩存,數據流等等。
4、綁定:主要是指和系統外部資源的交互。
在傳統軟件時代,是耦合在應用代碼裏的,但現如今,有越來越多的分佈式能力從應用中剝離,而剝離的方式也在逐漸變化,從最早期,這些能力從業務代碼剝離到依賴庫中,然後有一些特性剝離到平臺層(kubernetes)。而如今會有更多的非業務能力,剝離到 sidecar 中。作者預測:理論上每個微服務可以有多個 runtime: 一個業務運行時,和多個分佈式能力運行時,但最理想的情況是,或者最可能出現的情況是:在業務之外的運行時合併爲一個,通過高度模塊化、標準化和可配置的方式,給業務提供所有分佈式能力。而 dapr 則在很早之前就完成了對 istio 的集成,理論上我們可以通過運行兩個 sidecar 來提供分佈式能力,istio 關注網絡側,包括不限於服務註冊發現、A/B 測、金絲雀部署、流量鏡像,監控鏈路等等。當然 dapr 這部分有一定重疊,但是沒有 istio 做的那麼細緻,這兩者可以互補。而 dapr 則可以提供 istio 並不具備的網絡功能比如訂閱 / 發佈、狀態管理包括狀態冪等,一致性,actor 等等,也包括綁定,通過綁定和外部系統交互這部分。
附錄:(如果你覺得對你有用,請給個 star)
一、電商 Demo 地址:https://github.com/sd797994/Oxygen-Dapr.EshopSample
二、通訊框架地址:https://github.com/sd797994/Oxygen-Dapr
istio 是什麼呢?簡單來講 istio 是一個 service mesh,和 dapr 的結構類似,都是通過在應用之上插入 sidecar 來提供分佈式能力,同時通過控制平面來對這些 sidecar 進行具體的調度和管控,只不過 istio 更傾向於提供網絡能力,其官網的一句話描述可以概括:“通過領先的服務網格簡化可觀測性,流量管理,安全及策略。” 其功能包括以下幾點:
1、使用 TLS 加密、強身份認證和授權的集羣內服務到服務的安全通信
2、自動負載均衡的 HTTP, gRPC, WebSocket,和 TCP 流量
3、通過豐富的路由規則、重試、故障轉移和故障注入對流量行爲進行細粒度控制
4、一個可插入的策略層和配置 API,支持訪問控制、速率限制和配額
5、對集羣內的所有流量 (包括集羣入口和出口) 進行自動度量、日誌和跟蹤
說了那麼多,我們還是聊聊如何通過 dapr+istio 對我們的電商 demo 進行多運行時集成吧。首先是安裝,安裝可以參考 istio 官方中文文檔,默認安裝 profile=demo 會幫我們安裝 istiod+ingressgateway+egressgateway,istiod 就是我們的控制平面核心,不同於 dapr 將控制平面分散在多個容器的做法,istio 經歷過 1.5 的版本迭代後將所有的功能又合併到了一個容器中。而 ingressgateway 則是用於替代 ingress-controller 的,而 egress 是出口網關,由於 istio 默認對入口和出口流量都有管控,這裏我們不需要限制出口流量,所以設置爲 ALLOW_ANY。同時這是不需要每次都拉取 sidecar 鏡像。
istioctl install --set profile=demo --set meshConfig.outboundTrafficPolicy.mode=ALLOW_ANY --set values.global.imagePullPolicy=IfNotPresent
同樣的我們需要將 ingressgateway 作爲 nodeport 指向我們的 30882,記住這裏需要先把之前安裝的 ingress-controller 的 svc 的 30882 修改爲其他端口,否則會衝突。
kubectl edit svc istio-ingressgateway -n istio-system
-> 文件內容改動如下:
...
- name: http2 #只需要修改http2即可
nodePort: 30882
port: 80
protocol: TCP
...
type: NodePort #改成NodePort,下面的部分刪除
status:
loadBalancer:
ingress:
- hostname: localhost
接着我們看看 kubectl get po -n istio-system 確保三個 pod 都已經 running 即可,接着我們安裝一些 dashboard 需要等下通過這些來觀察 istio,進入安裝的 istio 根目錄,找到 \ samples\addons,執行 kubectl apply -f . 即可將 Kiali 和其他插件安裝完畢,其中 kiali 是 istio 的官方儀表板,安裝完成後可以通過 istioctl dashboard kiali 將 kiali 啓動起來,當然你也可以通過修改 kubectl edit svc kiali -n istio-system 設置 nodeport 來永久暴露 kiali 面板,這裏不贅述。可以看到我們的 dapreshop 裏所有的 pod 目前狀態都是 missing sidecar,說明 sidecar 尚未注入。
接着我們來注入 istio 的 sidecar 到我們的電商 demo。很簡單,只需要執行 kubectl label ns dapreshop istio-injection=enabled 在我們的 dapreshop 這個 namespace 打上自動注入的標籤,接着我們 kubectl delete po --all -n dapreshop 重啓所有 pod 即可將該空間下的 pod 都自動注入 sidecar。如果你不需要某些 pod 注入 sidecar,則禁用它即可:
template:
metadata:
labels:
app: accountservice
version: v1
annotations:
sidecar.istio.io/inject: "false"
如果一切順利,等待一段時間後,我們可以看到每一個 pod 都會被正確的注入 istio 的 sidcar,而 istio sidecar 工作原理和 dapr 不一樣,它是通過修改 ip 規則轉發流量的方式強制攔截,流量模型如下:
接着我們需要編寫入口流量,讓我們的流量通過 istio 的網關接管,yaml 如下:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: dapreshop-gateway
namespace: dapreshop
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: apigateway
namespace: dapreshop
spec:
hosts:
- "api.dapreshop.com"
gateways:
- dapreshop-gateway
http:
- route:
- destination:
port:
number: 80
host: apigateway
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: mobiledapreshop
namespace: dapreshop
spec:
hosts:
- "m.dapreshop.com"
gateways:
- dapreshop-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 80
host: mobilefrontend
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: admindapreshop
namespace: dapreshop
spec:
hosts:
- "admin.dapreshop.com"
gateways:
- dapreshop-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 80
host: adminfrontend
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: oauthdapreshop
namespace: dapreshop
spec:
hosts:
- "oauth.dapreshop.com"
gateways:
- dapreshop-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 80
host: oauthservice-dapr
apply 以後,我們可以通過 kugectl get gw,vs -n dapreshop。可以看到相關資源已經注入成功了,接着就可以訪問我們的 http://admin.dapreshop.com:30882/, 可以看到頁面被正確打開了,說明流量已經通過 istio 正確轉發了。接着我們操作一下平臺,然後登錄 kiali 即可看到正確的鏈路調用情況了
今天的分享就到這裏,這只是一個簡單的 demo 級別的演示,其他的還需要大家多自行摸索,照例歡迎 fork+star~
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/BFW5D3zR4QxYq60TRWosag