# istio 的自动注入

从小白角度上来讲，istio 的吸引力不在于那些花里胡哨或者说精彩纷呈的功能，而是

- 第一：背景深厚
- 第二：可以流水线操作的一键注入功能

而目前的 0.2 预发布版又提供了自动注入功能，进一步提高了易用性。

## 开始之前

istio 的 0.2.4 版本。

根据官方文档，自动注入功能需要 Kubernetes 1.7.4 以上，并且需要启用两个 Alpha 功能，可以把
如下参数加入 kube-apiserver 的启动文件之中：

    --runtime-config=admissionregistration.k8s.io/v1alpha1=true
    --runtime-config=batch/v2alpha1=true

## 开启自动注入功能

    kubectl apply -f install/kubernetes/istio-initializer.yaml

等待运行结果。注意其中的镜像地址可以按需求进行编辑。

## 测试自动注入

> 默认的规则中，这一功能对 kube-system kube-public 和 istio-system
> 这三个命名空间是无效的。

在 Default 命名空间中，运行这样两个应用：

~~~yaml
apiVersion: v1
kind: Service
metadata:
  name: service-one
  labels:
    app: service-one
spec:
  ports:
  - port: 80
    targetPort: 8080
    name: http
  selector:
    app: service-one
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: service-one
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: service-one
    spec:
      containers:
      - name: app
        image: gcr.io/google_containers/echoserver:1.4
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: service-two
  labels:
    app: service-two
spec:
  ports:
  - port: 80
    targetPort: 8080
    name: http-status
  selector:
    app: service-two
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: service-two
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: service-two
    spec:
      containers:
      - name: app
        image: gcr.io/google_containers/echoserver:1.4
        ports:
        - containerPort: 8080
~~~

运行成功之后，我们可以看看自动注入对这两个 Deployment 做了什么：

    kubectl get deploy service-one -o yaml

会看到返回内容中多了些东西：

~~~yaml

...

annotations:
  sidecar.istio.io/status: injected-version-0.2.4

...

image: docker.io/istio/proxy:0.2.4
  imagePullPolicy: IfNotPresent

...

initContainers:
 - args:
   - -p
   - "15001"
   - -u
   - "1337"
   image: docker.io/istio/proxy_init:0.2.4
~~~

很明显的动了手脚，接下来获取一下 Pod 信息：

    # kubectl get po | grep service
    service-one-2087957768-fpqqd   2/2       Running           0          1h
    service-two-875897890-tmfng    2/2       Running           0          1h

测试 Pod 的功能：

    kubectl exec -it service-one-2087957768-fpqqd -c app -- curl service-two:80

会看到从 Service one 的 pod 中使用 curl 访问 service-two 的服务，会被注入一些内容，
证明这一功能正常生效：

    ...

    HEADERS RECEIVED:
    accept=*/*
    content-length=0
    host=service-two
    user-agent=curl/7.47.0
    x-b3-sampled=1
    x-b3-spanid=0000c703da4c3c5d
    x-b3-traceid=0000c703da4c3c5d
    x-envoy-expected-rq-timeout-ms=15000
    x-forwarded-proto=http
    x-ot-span-context=0000c703da4c3c5d;0000c703da4c3c5d;0000000000000000
    x-request-id=207c124e-36ee-973e-bcc0-84dc70b8c71f

    ...

## 幕后

istio 会根据存储于`istio-inject` config-map 中的策略，对集群中的新的工作负载进行监控，
如果有了符合条件的对象生成，就会利用 PATCH 方法对对象进行更新，注入所需内容。

缺省策略如下：

~~~yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: istio-inject
  namespace: istio-system
data:
  config: |-
    policy: "enabled"
    namespaces: [""] # 除了几个特定名称之外的所有命名空间
    initializerName: "sidecar.initializer.istio.io"
    params: # 自定义 sidecar 执行参数
      initImage: docker.io/istio/proxy_init:0.2.4
      proxyImage: docker.io/istio/proxy:0.2.4
      verbosity: 2
      version: 0.2.4
      meshConfigMapName: istio
      imagePullPolicy: IfNotPresent
~~~

### Policy

- **off**：关闭注入
- **disabled**：禁用注入，但是可以设置`sidecar.istio.io/inject`标签为`true`，来强制开启。
- **enabled**：启用注入，可以设置`sidecar.istio.io/inject`标签为`false`来关闭这一功能。
