一. 自動(dòng)注入(sidecar)
說到服務(wù)網(wǎng)格必然是侵入式的包裹著你的服務(wù),在中間過程完成了一些列工作,那么就到了我們的第一個(gè)主題自動(dòng)注入,大家在通過webui或者是kubectl創(chuàng)建的時(shí)候默認(rèn)并不會(huì)觸發(fā)Istio的容器注入,那么有以下幾種方式可以讓istio注入生效:
- 使用命令注入istioctl來創(chuàng)建容器
> istioctl kube-inject -f samples/sleep/sleep.yaml | kubectl apply -f -
- 開啟namespace自動(dòng)注入無論從任何地方創(chuàng)建POD在這個(gè)namespace都會(huì)自動(dòng)注入
首先我們需要確認(rèn)MutatingAdmissionWebhook并且ValidatingAdmissionWebhook許可控制器并以正確的順序添加了,也就是我們?cè)诖罱↘8S時(shí)的修改,并且需要確認(rèn)啟用了registrationregistration API:
先創(chuàng)建一個(gè)用于測(cè)試的namespace:
apiVersion: v1
kind: Namespace
metadata:
name: istio-test
labels:
name: istio-test
我們可以通過以下命令查看開啟了自動(dòng)注入的namespace:
> kubectl get namespace -L istio-injection
NAME STATUS AGE ISTIO-INJECTION
default Active 4d
istio-system Active 1h disabled
istio-test Active 21m
kube-public Active 4d
kube-system Active 4d
通過以下命令可以開啟自注入:
> kubectl label namespace istio-test istio-injection=enabled
NAME STATUS AGE ISTIO-INJECTION
default Active 4d
istio-system Active 1h disabled
istio-test Active 21m enabled
kube-public Active 4d
kube-system Active 4d
我們?cè)趇stio中創(chuàng)建一個(gè)nginx鏡像看看和正常的鏡像有什么區(qū)別:
在容器組中明顯多出了一個(gè)istio-proxy這個(gè)就表示注入成功了
二, 部署示例項(xiàng)目bookinfo
要開始進(jìn)行請(qǐng)求路由實(shí)驗(yàn)之前我們需要先部署好官方提供的demo其實(shí)也就是幾條命名搞定的事情:
創(chuàng)建基礎(chǔ)Deployment + Service
> kubectl apply -n istio-test -f istio-1.0.3/samples/bookinfo/platform/kube/bookinfo.yaml
# 確認(rèn)pod創(chuàng)建成功
NAME READY STATUS RESTARTS AGE
details-v1-6764bbc7f7-49mnq 2/2 Running 0 14m
nginx-65c588c7d5-6jmzz 2/2 Running 0 23m
productpage-v1-54b8b9f55-jtwmd 2/2 Running 0 13m
ratings-v1-7bc85949-hcl9r 2/2 Running 0 14m
reviews-v1-fdbf674bb-5n7t7 2/2 Running 0 13m
reviews-v2-5bdc5877d6-4fg72 2/2 Running 0 13m
reviews-v3-dd846cc78-vp4r7 2/2 Running 0 13m
# 確認(rèn)service創(chuàng)建成功
> kubectl get services -n istio-test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.43.31.242 <none> 9080/TCP 35s
productpage ClusterIP 10.43.80.92 <none> 9080/TCP 24s
ratings ClusterIP 10.43.51.233 <none> 9080/TCP 34s
reviews ClusterIP 10.43.220.25 <none> 9080/TCP 27s
創(chuàng)建Istio網(wǎng)關(guān)(可選使用主要控制域名路由的入口):
> kubectl apply -n istio-test -f istio-1.0.3/samples/bookinfo/networking/bookinfo-gateway.yaml
# 確定網(wǎng)關(guān)創(chuàng)建成功
> kubectl get gateway -n istio-test
NAME AGE
bookinfo-gateway 14s
創(chuàng)建基礎(chǔ)路由規(guī)則(控制流量就是控制rule的規(guī)則):
> kubectl apply -n istio-test -f istio-1.0.3/samples/bookinfo/networking/destination-rule-all.yaml
# 通過以下命令可以查看路由規(guī)則
kubectl get destinationrules -o yaml -n istio-test
三. 請(qǐng)求路由
開始之前我們需要先理解下圖整個(gè)服務(wù)之間的關(guān)系
部署好了之后Istio網(wǎng)關(guān)會(huì)默認(rèn)占用31380端口作為80端口的出口,在網(wǎng)關(guān)中從31380進(jìn)來的流量進(jìn)行了路由判斷并且統(tǒng)一路由到了**productpage
**9080端口,所以我們?cè)L問http://:31380/productpage能得到以下界面:
因?yàn)閞eviews有v1.v2.v3三個(gè)版本,并且在rule配置中都進(jìn)行了配置,所以多次訪問在右邊的星星會(huì)有不一樣的結(jié)果(此時(shí)概率是3/1):
3.1 所有流量指向V1版本
> kubectl apply -n istio-test -f istio-1.0.3/samples/bookinfo/networking/virtual-service-all-v1.yaml
規(guī)則如下,去除了V2和V3:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
現(xiàn)在在無論怎么刷新就只能看到V1返回內(nèi)容:
3.2 指定jason用戶的流量指向到V2版本
> kubectl apply -n istio-test -f istio-1.0.3/samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
規(guī)則中定義了在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
登錄之后發(fā)現(xiàn)怎么刷新都顯示的是V2版本的黑星星
四. 故障注入
4.1 HTTP延遲故障
在微服務(wù)系統(tǒng)中可能表明看上去沒有問題,可能存在潛在的彈性文檔,當(dāng)請(qǐng)求壓力變大響應(yīng)時(shí)間變長可能會(huì)應(yīng)為一些內(nèi)部的超時(shí)機(jī)制不合理等問題導(dǎo)致不可使用,這個(gè)時(shí)候通過Istio的HTTP延遲故障可以模擬出訪問延遲來排查這類異常BUG
我們將在 reviews:v2 和 ratings 服務(wù)之間的一個(gè)用戶 jason 注入一個(gè) 7 秒的延遲。 這個(gè)測(cè)試將會(huì)發(fā)現(xiàn)故意引入 Bookinfo 應(yīng)用程序中的錯(cuò)誤。
由于 reviews:v2 服務(wù)對(duì)其 ratings 服務(wù)的調(diào)用具有 10 秒的硬編碼連接超時(shí),比我們?cè)O(shè)置的 7s 延遲要大,因此我們期望端到端流程是正常的(沒有任何錯(cuò)誤)。
> 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 秒鐘加載完成并且沒有錯(cuò)誤。但是,出現(xiàn)了一個(gè)問題,Reviews 部分顯示了錯(cuò)誤消息,頁面實(shí)際上用了大約 6s。
在 productpage 和 reviews 服務(wù)之間超時(shí)時(shí)間是 6s - 編碼 3s + 1 次重試總共 6s ,reviews 和 ratings 服務(wù)之間的硬編碼連接超時(shí)為 10s 。由于我們引入的延時(shí),/productpage 提前超時(shí)并引發(fā)錯(cuò)誤。
這些類型的錯(cuò)誤可能發(fā)生在典型的企業(yè)應(yīng)用程序中,其中不同的團(tuán)隊(duì)獨(dú)立地開發(fā)不同的微服務(wù)。Istio 的故障注入規(guī)則可幫助您識(shí)別此類異常,而不會(huì)影響最終用戶。
PS : 請(qǐng)注意,這里僅限制用戶 “jason” 的失敗影響。如果您以任何其他用戶身份登錄,則不會(huì)遇到任何延遲。
4.2 HTTP abort進(jìn)行故障注入
測(cè)試微服務(wù)彈性的另一種方法是引入 HTTP abort 故障,如果異常中斷那么需要做出對(duì)應(yīng)的處理。為用戶 “jason” 創(chuàng)建故障注入規(guī)則發(fā)送 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 消息
我們退出賬號(hào)發(fā)現(xiàn)又恢復(fù)正常了
五.流量控制
一個(gè)常見的用例是將流量從一個(gè)版本的微服務(wù)逐漸遷移到另一個(gè)版本。 在Istio中,您可以通過配置一系列規(guī)則來實(shí)現(xiàn)此目標(biāo), 這些規(guī)則將一定百分比的流量路由到一個(gè)或另一個(gè)服務(wù)。 在此任務(wù)中,您將先分別向 reviews:v1 和 reviews:v3 各發(fā)送50%流量。 然后,您將通過向 reviews:v3 發(fā)送100%的流量來完成遷移。
走了上面流程的童鞋現(xiàn)在在不等了的情況下怎么都是訪問的V1版本的返回,使用下面的命令把50%的流量從 reviews:v1 轉(zhuǎn)移到 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版本,會(huì)發(fā)現(xiàn)始終能夠看到紅色的星星
> 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