三, 跨語言微服務框架 - Istio官方示例(自動注入.請求路由.流量控制.故障注入) 原 薦
基礎的Istio環境已經搭建完成,我們需要開始瞭解Istio提供作為微服務網格的各種機制,也就是本文標題的自動注入.請求路由.故障注入.流量切換,官方很給力的準備的例項專案也不需要大家自己編寫demo來進行測試,那就來時跑跑看吧.
附上:
喵了個咪的部落格:w-blog.cn
Istio官方地址: ofollow,noindex" target="_blank">https://preliminary.istio.io/zh
Istio中文文件: https://preliminary.istio.io/zh/docs/
PS : 此處基於當前最新istio版本1.0.3版本進行搭建和演示
一. 自動注入(sidecar)
說到服務網格必然是侵入式的包裹著你的服務,在中間過程完成了一些列工作,那麼就到了我們的第一個主題自動注入,大家在通過webui或者是kubectl建立的時候預設並不會觸發Istio的容器注入,那麼有以下幾種方式可以讓istio注入生效:
- 使用命令注入istioctl來建立容器
> istioctl kube-inject -f samples/sleep/sleep.yaml | kubectl apply -f -
- 開啟namespace自動注入無論從任何地方建立POD在這個namespace都會自動注入
首先我們需要確認MutatingAdmissionWebhook並且ValidatingAdmissionWebhook許可控制器並以正確的順序添加了,也就是我們在搭建K8S時的修改,並且需要確認啟用了registrationregistration API:
先建立一個用於測試的namespace:
apiVersion: v1 kind: Namespace metadata: name: istio-test labels: name: istio-test
我們可以通過以下命令檢視開啟了自動注入的namespace:
> kubectl get namespace -L istio-injection NAMESTATUSAGEISTIO-INJECTION defaultActive4d istio-systemActive1hdisabled istio-testActive21m kube-publicActive4d kube-systemActive4d
通過以下命令可以開啟自注入:
> kubectl label namespace istio-test istio-injection=enabled NAMESTATUSAGEISTIO-INJECTION defaultActive4d istio-systemActive1hdisabled istio-testActive21menabled kube-publicActive4d kube-systemActive4d
我們在istio中建立一個nginx映象看看和正常的映象有什麼區別:
在容器組中明顯多出了一個 istio-proxy 這個就表示注入成功了
二, 部署示例專案bookinfo
要開始進行請求路由實驗之前我們需要先部署好官方提供的demo其實也就是幾條命名搞定的事情:
建立基礎Deployment + Service
> kubectl apply -n istio-test -f istio-1.0.3/samples/bookinfo/platform/kube/bookinfo.yaml # 確認pod建立成功 NAMEREADYSTATUSRESTARTSAGE details-v1-6764bbc7f7-49mnq2/2Running014m nginx-65c588c7d5-6jmzz2/2Running023m productpage-v1-54b8b9f55-jtwmd2/2Running013m ratings-v1-7bc85949-hcl9r2/2Running014m reviews-v1-fdbf674bb-5n7t72/2Running013m reviews-v2-5bdc5877d6-4fg722/2Running013m reviews-v3-dd846cc78-vp4r72/2Running013m # 確認service建立成功 > kubectl get services -n istio-test NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE detailsClusterIP10.43.31.242<none>9080/TCP35s productpageClusterIP10.43.80.92<none>9080/TCP24s ratingsClusterIP10.43.51.233<none>9080/TCP34s reviewsClusterIP10.43.220.25<none>9080/TCP27s
建立Istio閘道器(可選使用主要控制域名路由的入口):
> kubectl apply -n istio-test -f istio-1.0.3/samples/bookinfo/networking/bookinfo-gateway.yaml # 確定閘道器建立成功 > kubectl get gateway -n istio-test NAMEAGE bookinfo-gateway14s
建立基礎路由規則(控制流量就是控制rule的規則):
> kubectl apply -n istio-test -f istio-1.0.3/samples/bookinfo/networking/destination-rule-all.yaml # 通過以下命令可以檢視路由規則 kubectl get destinationrules -o yaml -n istio-test
三. 請求路由
開始之前我們需要先理解下圖整個服務之間的關係
部署好了之後Istio閘道器會預設佔用31380埠作為80埠的出口,在閘道器中從31380進來的流量進行了路由判斷並且統一路由到了**productpage **9080埠,所以我們訪問http://<node>:31380/productpage能得到以下介面:
因為reviews有v1.v2.v3三個版本,並且在rule配置中都進行了配置,所以多次訪問在右邊的星星會有不一樣的結果(此時概率是3/1):
3.1 所有流量指向V1版本
> kubectl apply -n istio-test -f istio-1.0.3/samples/bookinfo/networking/virtual-service-all-v1.yaml
規則如下,去除了V2和V3:
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v1
現在在無論怎麼重新整理就只能看到V1返回內容:
3.2 指定jason使用者的流量指向到V2版本
> kubectl apply -n istio-test -f istio-1.0.3/samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
規則中定義了在headers中有配置的情況下路由訪問到V2
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - match: - headers: end-user: exact: jason route: - destination: host: reviews subset: v2 - route: - destination: host: reviews subset: v1
登入之後發現怎麼重新整理都顯示的是V2版本的黑星星
四. 故障注入
4.1 HTTP延遲故障
在微服務系統中可能表明看上去沒有問題,可能存在潛在的彈性文件,當請求壓力變大響應時間變長可能會應為一些內部的超時機制不合理等問題導致不可使用,這個時候通過Istio的HTTP延遲故障可以模擬出訪問延遲來排查這類異常BUG
我們將在 reviews:v2 和 ratings 服務之間的一個使用者 jason 注入一個 7 秒的延遲。 這個測試將會發現故意引入 Bookinfo 應用程式中的錯誤。
由於 reviews:v2 服務對其 ratings 服務的呼叫具有 10 秒的硬編碼連線超時,比我們設定的 7s 延遲要大,因此我們期望端到端流程是正常的(沒有任何錯誤)。
> kubectl apply -n istio-test -f istio-1.0.3/samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml > kubectl get -n istio-test virtualservice ratings -o yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: ratings ... spec: hosts: - ratings http: - fault: delay: fixedDelay: 7s percent: 100 match: - headers: end-user: exact: jason route: - destination: host: ratings subset: v1 - route: - destination: host: ratings subset: v1
你期望 Bookinfo 主頁在大約 7 秒鐘載入完成並且沒有錯誤。但是,出現了一個問題,Reviews 部分顯示了錯誤訊息,頁面實際上用了大約 6s。
在 productpage 和 reviews 服務之間超時時間是 6s - 編碼 3s + 1 次重試總共 6s ,reviews 和 ratings 服務之間的硬編碼連線超時為 10s 。由於我們引入的延時,/productpage 提前超時並引發錯誤。
這些型別的錯誤可能發生在典型的企業應用程式中,其中不同的團隊獨立地開發不同的微服務。Istio 的故障注入規則可幫助您識別此類異常,而不會影響終端使用者。
PS : 請注意,這裡僅限制使用者 “jason” 的失敗影響。如果您以任何其他使用者身份登入,則不會遇到任何延遲。
4.2 HTTP abort進行故障注入
測試微服務彈性的另一種方法是引入 HTTP abort 故障,如果異常中斷那麼需要做出對應的處理。為使用者 “jason” 建立故障注入規則傳送 HTTP abort
> kubectl apply -n istio-test -f istio-1.0.3/samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml > kubectl get -n istio-test virtualservice ratings -o yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: ratings ... spec: hosts: - ratings http: - fault: abort: httpStatus: 500 percent: 100 match: - headers: end-user: exact: jason route: - destination: host: ratings subset: v1 - route: - destination: host: ratings subset: v1
立即看到頁面載入並看到 Ratings service is currently unavailable 訊息
我們退出賬號發現又恢復正常了
五.流量控制
一個常見的用例是將流量從一個版本的微服務逐漸遷移到另一個版本。 在Istio中,您可以通過配置一系列規則來實現此目標, 這些規則將一定百分比的流量路由到一個或另一個服務。 在此任務中,您將先分別向 reviews:v1 和 reviews:v3 各發送50%流量。 然後,您將通過向 reviews:v3 傳送100%的流量來完成遷移。
走了上面流程的童鞋現在在不等了的情況下怎麼都是訪問的V1版本的返回,使用下面的命令把50%的流量從 reviews:v1 轉移到 reviews:v3:
> kubectl apply -n istio-test -f istio-1.0.3/samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml > kubectl get -n istio-test virtualservice reviews -o yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews ... spec: hosts: - reviews http: - route: - destination: host: reviews subset: v1 weight: 50 - destination: host: reviews subset: v3 weight: 50
最後將所有流量全部指向到V3版本,會發現始終能夠看到紅色的星星
> kubectl apply -n istio-test -f istio-1.0.3/samples/bookinfo/networking/virtual-service-reviews-v3.yaml > kubectl get -n istio-test virtualservice reviews -o yaml
