1. 程式人生 > 實用技巧 >Istio 網路彈性 實踐 之 故障注入 和 呼叫超時

Istio 網路彈性 實踐 之 故障注入 和 呼叫超時

網路彈性介紹

網路彈性也稱為運維彈性,是指網路在遇到災難事件時快速恢復和繼續執行的能力。災難事件的範疇很廣泛,比如長時間停電、網路裝置故障、惡意入侵等。


超時時間

工作中常常會碰到這樣的開發、測試場景,比如:“對方處理請求時間過長,沒有及時響應,我們的程式要怎麼處理來確保不會無限期地等待”。常見的處理方式是被呼叫方使用 sleep 語句模擬響應時間過長,呼叫方設定請求超時時間過短,來造成請求超時的結果。但是這種處理方法有很多的弊端,第一:本屬於網路彈性層的東西,卻需要在程式碼中體現;第二:超時時間設定過長可能導致過多的延遲、設定過短可能導致不必要的失敗,因此超時時間需要動態調整。基於上面兩個弊端,Istio 使用虛擬服務來優雅實現超時處理。


Istio 超時例項

本例項需要結合 Istio 故障注入模擬被呼叫方響應請求慢的場景,有關 Istio 失敗注入之延遲請參考本人的另外一篇博文,簡單到讓你分分鐘輕鬆完爆。

該例項的架構圖如下:

架構說明如下,本例項就是模擬客戶端呼叫 nginx,nginx 將請求轉發給 tomcat 的常見功能。tomcat 響應請求設定為 5s(通過故障注入實現,相當於 sleep 5s 邏輯),nginx 設定 client 的請求超時時間為 2s。因為 nginx 需要在 2s 內返回給 client,而 nginx 請求 tomcat 卻需要 5s,因此模擬 client 呼叫 nginx 超時的情景。

該例項資原始檔一共有 4 個,分別如下:

client.yaml # 客戶端資源

deploy.yaml # nginx、tomcat 的 deployment 資源

svc.yaml # nginx、tomcat 的 service 資源

vs.yaml # Istio 虛擬資源

client.yaml 檔案

資源內容如下圖所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: client
spec:
  replicas: 1
  selector:
    matchLabels:
      app: client
  template:
    metadata:
      labels:
        app: client
    spec:
      containers:
      - name: busybox
        image: busybox
        imagePullPolicy: IfNotPresent
        command: ["/bin/sh", "-c", "sleep 3600"]

deploy.yaml

資源內容如下圖所示:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    server: nginx
    app: web
spec:
  replicas: 1
  selector:
    matchLabels:
      server: nginx
      app: web
  template:
    metadata:
      name: nginx
      labels: 
        server: nginx
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:1.14-alpine
        imagePullPolicy: IfNotPresent
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat
  labels:
    server: tomcat
    app: web
spec:
  replicas: 1
  selector:
    matchLabels:
      server: tomcat
      app: web
  template:
    metadata:
      name: tomcat
      labels: 
        server: tomcat
        app: web
    spec:
      containers:
      - name: tomcat
        image: docker.io/kubeguide/tomcat-app:v1 
        imagePullPolicy: IfNotPresent

svc.yaml

資源內容如下圖所示:

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    server: nginx
  ports:
  - name: http
    port: 80
    targetPort: 80
    protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: tomcat-svc
spec:
  selector:
    server: tomcat
  ports:
  - name: http
    port: 8080
    targetPort: 8080
    protocol: TCP

vs.yaml

Istio 虛擬服務資源內容如下所示:

---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: jiuxi-nginx-vs
spec:
  hosts:
  - nginx-svc
  http:
  - route:
    - destination: 
        host: nginx-svc
    timeout: 2s
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: jiuxi-tomcat-vs
spec:
  hosts:
  - tomcat-svc
  http:
  - fault:
      delay:
        percentage:
          value: 100
        fixedDelay: 5s
    route:
    - destination:
        host: tomcat-svc 

此虛擬服務有兩個知識點。

第一:故障注入:

http:
- fault:
    delay:
      percentage:
      value: 100
   fixedDelay: 5s

該設定說明每次呼叫 tomcat-svc 的 k8s service,都會延遲 5s 才會呼叫。

第二:呼叫超時:

hosts:
- nginx-svc
  http:
  - route:
    - destination:
      host: nginx-svc
    timeout: 2s

該設定說明呼叫 nginx-svc 的 k8s service,請求超時時間是 2s。


超時例項部署

在上面我們編寫完樣例,下面準備部署。

Istio 注入

需要對 client 和 deploy 資原始檔進行 Istio 注入,將 client、nginx、tomcat 都放入到網格中。本人是手工注入 Istio 方式,如果你設定了自動 Istio 注入不會影響,一樣可以輕鬆完爆。

istioctl kube-inject -f client.yaml | kubectl apply -f -

istioctl kube-inject -f deploy.yaml | kubectl apply -f -

執行成功後,通過 kubectl get pods 檢視 Istio 注入情況:

部署 k8s service

部署 svc.yaml:

kubectl apply -f svc.yaml

部署 Istio 虛擬服務

部署 vs.yaml:

kubectl apply -f vs.yaml


超時例項設定

因為要用到 nginx 對 tomcat 的轉發功能,因此需要對 nginx 做一些設定:

登入 nginx pod:

kubectl exec -it nginx-7559f7d487-djzbb -- sh

編輯 nginx 配置檔案:

vi /etc/nginx/conf.d/default.conf

新增和修改如下內容:

編輯完後,再執行如下語句驗證配置和讓配置生效:

自此,整個樣例配置和部署完畢。


超時例項驗證

登入 client,執行如下語句:

kubectl exec -it client-5b77d5949f-nzdtl -- sh

執行如下語句:

wget -q -O - http://nginx-svc

執行結果如下所示:

/ # time wget -q -O - http://nginx-svc
wget: server returned error: HTTP/1.1 504 Gateway Timeout
Command exited with non-zero status 1
real	0m 2.02s
user	0m 0.00s
sys	0m 0.00s

說明 timeout 樣例執行成功。

也可以同樣驗證故障注入效果,執行如下語句:

/ # time wget -q -O - http://tomcat-svc
<!DOCTYPE html>
<html lang="en">
...
</html>
real	0m 5.01s
user	0m 0.00s
sys	0m 0.00s

執行效果是請求 5s 後才會返回,說明 Istio 故障注入(延遲 5s)執行成功。