Sidecar Injector自动注入的原理 –《云原生服务网格Istio》书摘04

本节书摘来自华为云原生技术丛书《云原生服务网格Istio:原理,实践,架构与源码解析》一书原理篇的第6章透明的Sidecar机制,6.1.1小节Sidecar Injector自动注入的原理。更多内容参照原书,或者关注容器魔方公众号。

Sidecar注入

我们都知道,Istio的流量管理、策略、遥测等功能无须应用程序做任何改动,这种无侵入式的方式全部依赖于Sidecar。应用程序发送或者接收的流量都被Sidecar拦截,并由Sidecar进行认证、鉴权、策略执行及遥测数据上报等众多治理功能。

如图6-1所示,在Kubernetes中,Sidecar容器与应用容器共存于同一个Pod中,并且共享同一个Network Namespaces,因此Sidecar容器与应用容器共享同一个网络协议栈,这也是Sidecar能够通过iptables拦截应用进出口流量的根本原因。

图6-1  Istio的Sidecar模式

在Istio中进行Sidecar注入有两种方式:一种是通过istioctl命令行工具手动注入;另一种是通Istio Sidecar Injector自动注入。

这两种方式的最终目的都是在应用Pod中注入init容器及istio-proxy容器这两个Sidecar容器。如下所示,通过部署Istio的sleep应用,Sidecar是通过sidecar-injector自动注入的,查看注入的Sidecar容器:

(1)istio-proxy 容器:

 1- args:                 # istio-proxy 容器命令行参数
 2    - proxy
 3- sidecar
 4    - --domain
 5- $(POD_NAMESPACE).svc.cluster.local
 6    - --configPath
 7- /etc/istio/proxy
 8- --binaryPath
 9    - /usr/local/bin/envoy
10    - --serviceCluster
11  - sleep.default
12    - --drainDuration
13- 45s
14    - --parentShutdownDuration
15- 1m0s
16    - --discoveryAddress
17    - istio-pilot.istio-system:15011
18    - --zipkinAddress
19    - zipkin.istio-system:9411
20    - --connectTimeout
21    - 10s
22    - --proxyAdminPort
23- "15000"
24    - --controlPlaneAuthPolicy
25    - MUTUAL_TLS
26    - --statusPort
27- "15020"
28    - --applicationPorts
29    - ""
30    env:                       # istio-proxy 容器环境变量
31  - name: POD_NAME
32      valueFrom:
33        fieldRef:
34          apiVersion: v1
35          fieldPath: metadata.name
36  - name: POD_NAMESPACE
37      valueFrom:
38        fieldRef:
39          apiVersion: v1
40          fieldPath: metadata.namespace
41  - name: INSTANCE_IP
42      valueFrom:
43        fieldRef:
44          apiVersion: v1
45          fieldPath: status.podIP
46    - name: ISTIO_META_POD_NAME
47      valueFrom:
48        fieldRef:
49          apiVersion: v1
50          fieldPath: metadata.name
51- name: ISTIO_META_CONFIG_NAMESPACE
52      valueFrom:
53        fieldRef:
54          apiVersion: v1
55          fieldPath: metadata.namespace
56- name: ISTIO_META_INTERCEPTION_MODE
57      value: REDIRECT
58- name: ISTIO_METAJSON_LABELS
59      value: |
60        {"app":"sleep","pod-template-hash":"7f59fddf5f"}        
61    image: gcr.io/istio-release/proxyv2:release-1.1-20190124-15-51
62    imagePullPolicy: IfNotPresent
63    name: istio-proxy
64    ……
65    volumeMounts:                  # istio-proxy挂载的证书及配置文件
66- mountPath: /etc/istio/proxy
67      name: istio-envoy
68    - mountPath: /etc/certs/
69      name: istio-certs
70      readOnly: true
71- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
72      name: sleep-token-266l9
73      readOnly: true

(2)istio-init容器:

 1initContainers:                # istio-init容器,用于初始化Pod网络
 2- args:
 3  - -p
 4- "15001"
 5    - -u
 6- "1337"
 7    - -m
 8- REDIRECT
 9    - -i
10    - '*'
11    - -x
12    - ""
13    - -b
14    - ""
15    - -d
16- "15020"
17image: gcr.io/istio-release/proxy_init:release-1.1-20190124-15-51
18    imagePullPolicy: IfNotPresent
19    name: istio-init
20    ……
21    securityContext:
22      capabilities:
23        add:
24  - NET_ADMIN
25      procMount: Default

Sidecar Injector自动注入的原理

Sidecar Injector是Istio中实现自动注入Sidecar的组件,它是以Kubernetes准入控制器Admission Controller的形式运行的。Admission Controller的基本工作原理是拦截Kube-apiserver的请求,在对象持久化之前、认证鉴权之后进行拦截。Admission Controller有两种:一种是内置的,另一种是用户自定义的。Kubernetes允许用户以Webhook的方式自定义准入控制器,Sidecar Injector就是这样一种特殊的MutatingAdmissionWebhook。

如图6-2所示,Sidecar Injector只在创建Pod时进行Sidecar容器注入,在Pod的创建请求到达Kube-apiserver后,首先进行认证鉴权,然后在准入控制阶段,Kube-apiserver以REST的方式同步调用Sidecar Injector Webhook服务进行init与istio-proxy容器的注入,最后将Pod对象持久化存储到etcd中。

图6-2  Sidecar Injector的工作原理

Sidecar Injector可以通过MutatingWebhookConfiguration API动态配置生效,Istio中的MutatingWebhook配置如下:

 1apiVersion: admissionregistration.k8s.io/v1beta1
 2kind: MutatingWebhookConfiguration
 3metadata:
 4  creationTimestamp: "2019-02-12T06:00:51Z"
 5  generation: 4
 6  labels:
 7    app: sidecarInjectorWebhook
 8    chart: sidecarInjectorWebhook
 9    heritage: Tiller
10    release: istio
11  name: istio-sidecar-injector
12resourceVersion: "2974010"
13  selfLink: /apis/admissionregistration.k8s.io/v1beta1/mutatingwebhookconfigurations/istio-sidecar-injector
14  uid: 8d62addb-2e8b-11e9-b464-fa163ed0737f
15webhooks:
16- clientConfig:
17    caBundle: ……
18    service:
19      name: istio-sidecar-injector
20      namespace: istio-system
21      path: /inject
22  failurePolicy: Fail
23  name: sidecar-injector.istio.io
24  namespaceSelector:
25    matchLabels:
26      istio-injection: enabled
27  rules:
28  - apiGroups:
29    - ""
30apiVersions:
31    - v1
32    operations:
33- CREATE
34    resources:
35  - pods
36  sideEffects: Unknown

从以上配置可知,Sidecar Injector只对标签匹配“istio-injection: enabled”的命名空间下的Pod资源对象的创建生效。Webhook服务的访问路径为“/inject”,地址及访问凭证等都在clientConfig字段下进行配置。

Istio Sidecar Injector组件是由sidecar-injector进程实现的,本书在之后将二者视为同一概念。Sidecar Injector的实现主要由两部分组成:

  • 维护MutatingWebhookConfiguration;
  • 启动Webhook Server,为应用工作负载自动注入Sidecar容器。

MutatingWebhookConfiguration对象的维护主要指监听本地证书的变化及Kubernetes MutatingWebhookConfiguration资源的变化,以检查CA证书或者CA数据是否有更新,并且在本地CA证书与MutatingWebhookConfiguration中的CA证书不一致时,自动更新MutatingWebhookConfiguration对象。