Istio技術與實踐03:最佳實踐之sidecar自動注入

PaaS小魔仙發表於2018-08-30

Istio 通過對 serviceMesh 中的每個 pod 注入 sidecar,來實現無侵入式的服務治理能力。其中,sidecar 的注入是其能力實現的重要一環(本文主要介紹在 kubernetes 叢集中的注入方式)。

sidecar 注入有兩種方式,一是通過建立 webhook 資源,利用k8s的webhook能力實現pod的自動注入,二是通過 istioctl 工具,對 yaml 檔案進行手動注入。在這裡對這兩種方式進行簡單介紹。

webhook自動注入:

準備條件:

  • 自動注入功能需要 kubernetes 1.9或更高版本;
  • kubernetes 環境需支援 MutatingAdmissionWebhook;
$ kubectl api-versions | grep admissionregistration
admissionregistration.k8s.io/v1beta1
複製程式碼
  • 需要在 kube-apiserver 的啟動引數中加入
  • 確保 master 到 node 容器網路通訊正常。

自動注入控制:

  • 可通過在 sidecar-injector 的 configmap 中設定 policy=disabled 欄位來設定是否啟用自動注入(此處為全域性控制是否啟用自動注入功能);
$ kubectl get cm istio-sidecar-injector -nistio-system
apiVersion: v1
kind: ConfigMap
metadata:
name: istio-sidecar-injector
namespace: istio-system
data:
config: |-
    policy: enabled     //enabeld為開啟,disabeld為關閉
    
複製程式碼
  • 為需要自動注入的 namespace 打上標籤 istio-injection: enabled(此處為ns級別的自動注入控制)。
$ kubectl get namespace -L istio-injection
NAME           STATUS    AGE       ISTIO-INJECTION
default        Active    1h
istio-system   Active    1h
kube-public    Active    1h
kube-system    Active    1h
$ kubectl label namespace default istio-injection=enabled
namespace "default" labeled
$ kubectl get namespace -L istio-injection
NAME           STATUS    AGE       ISTIO-INJECTION
default        Active    1h        enabled
istio-system   Active    1h
kube-public    Active    1h
kube-system    Active    1h
複製程式碼
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: test
spec:
replicas: 1
template:
metadata:
annotations:
sidecar.istio.io/inject: “true”
// true為啟用自動注入,false為關閉自動注入
複製程式碼
  • 定義 webhook 引數檔案 MutatingWebhookConfiguration,格式如下(在 helm 包的 sidecarInject 中)。

這裡的語義就是,監聽具有 istio-injection: enabled 的 label 的 namespace 下的 pod 資源,當發生 rules(CREATE POD)的動作時,則呼叫 services(istio-sidecar-injector.istio-system的/inject 介面)。

apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
  name: istio-sidecar-injector
 namespace: {{ .Release.Namespace }}
labels:
 app: istio-sidecar-injector
webhooks:
- name: sidecar-injector.istio.io
  clientConfig:
service:
  name: istio-sidecar-injector
namespace: {{ .Release.Namespace }}
  path: "/inject"
 caBundle: ""
rules:
- operations: [ "CREATE" ]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
failurePolicy: Fail
namespaceSelector:
matchLabels:
istio-injection: enabled
複製程式碼
  • webhook 工作流程圖
    Istio技術與實踐03:最佳實踐之sidecar自動注入

    介紹了自動注入的注意事項與原理,終於可以測試下自動注入的結果了

  • 首先安裝 Istio 控制面,確保 sidecar-inject 安裝完成;
$ kubectl get po -nistio-system | grep sidecar-injector
istio-sidecar-injector-5fb5999bf8-59k79          1/1       Running   0
1d
複製程式碼
  • 部署一個簡單的測試 deploy,此處我們以 nginx 為例;
$ kubectl get po | grep nginx
nginx-v1-74c674fbd5-fl9bh         1/1       Running   0          22s
複製程式碼
  • 我們用步驟b).II中的方式為 default 的 namespace 打上自動注入標籤,刪除 pod,觀察 pod 狀態,可以看到pod的容器數由1變為2;
$ kubectl get po | grep nginx
nginx-v1-54fbccf6fd-ff4k2         2/2       Running       0          4s
nginx-v1-74c674fbd5-fl9bh         1/1       Terminating   0          5m
複製程式碼
  • 可以看到sidecar容器已經注入成功,我們看下pod的描述資訊,觀察下自動注入做了什麼。可以看到,自動注入向pod中插入了一個初始化容器istio-init和一個sidecar容器istio-proxy(詳細引數可以參考configmap:istio-sidecar-injector);
$ kubectl describe po nginx-v1-54fbccf6fd-ff4k2
Name:           nginx-v1-54fbccf6fd-ff4k2
Namespace:      default
Status:         Running

...

Init Containers:
 istio-init:
Container ID:  
 docker://96951306e214594d0c1e550f732a81781287f79f0e5a3262455f38535d42d61f
Image:         istio/proxy_init:0.8.0

...

Containers:
 container-0:
Container ID:   
docker://237781c7ce1e8c1f49f68047142ce1738822bafbe504f836f51873cbb1ac1f5d
Image:          nginx:1.12-alpine-perl
Port:           80/TCP
State:          Running

...

istio-proxy:
Container ID:  
docker://7208d32552918a5853fd56171bdbab3de3ae734242d23b140f6e5c2a1a4bce64
Image:         istio/proxyv2:0.8.0
Args:
proxy
sidecar
     --configPath
/etc/istio/proxy
--binaryPath
/usr/local/bin/envoy
--serviceCluster
nginx
 
...
複製程式碼

istioctl手動注入:

  • 下載 istioctl 工具並拷貝至環境,連結https://github.com/istio/istio/releases/
  • 將 istioctl 二進位制拷貝至/usr/local/bin目錄下
mv -f istioctl /usr/local/bin
複製程式碼
  • mv -f istioctl /usr/local/bin
$ kubectl get cm -n istio-system | grep istio-sidecar-injector
istio-sidecar-injector                  1         15h
複製程式碼
  • 準備需要注入的檔案 test.yaml
  • 執行 istioctl 會在原始內容的基礎上加入 sidecar 的配置內容,並輸出到控制檯。
$ kubectl apply -f <(istioctl kube-inject -f test.yaml)
複製程式碼
  • 將 istioctl 處理之後的內容部署到 kubernetes 上
$ kubectl apply -f <(istioctl kube-inject -f test.yaml)
複製程式碼
  • 可以通過 k8s 命令檢視 pod 詳細內容
$ kubectl describe pod test-c9f4b55c7-np4cf
複製程式碼

總結:

這裡更推薦自動注入的方式來實現 sidecar 的注入,可以通過在 deployment 的 annotation 中加入對應的 key 來實現自動注入的控制。自動注入實現的邏輯並不複雜,主要是對 k8s 中 webhook 的使用,以及通過模板,向 deployment 中注入相應的 container 資源等。

相關文章