安装 Sidecar

注入

为了充分利用 Istio 的所有特性,网格中的 Pod 必须运行一个 Istio Sidecar 代理。

下面的章节描述了向 Pod 中注入 Istio Sidecar 的两种方法:使用 istioctl 手动注入或启用 Pod 所属命名空间的 Istio sidecar 注入器自动注入。

手动注入直接修改配置,如 Deployment,并将代理配置注入其中。

当 Pod 所属命名空间启用自动注入后,自动注入器会使用准入控制器在创建 Pod 时自动注入代理配置。

如果您不确定使用哪一种方法,建议使用自动注入。

手动注入 Sidecar

要手动注入 Deployment,请使用 istioctl kube-inject

Zip
$ istioctl kube-inject -f @samples/sleep/sleep.yaml@ | kubectl apply -f -
serviceaccount/sleep created
service/sleep created
deployment.apps/sleep created

默认情况下将使用集群内的配置,或者使用该配置的本地副本来完成注入。

$ kubectl -n istio-system get configmap istio-sidecar-injector -o=jsonpath='{.data.config}' > inject-config.yaml
$ kubectl -n istio-system get configmap istio-sidecar-injector -o=jsonpath='{.data.values}' > inject-values.yaml
$ kubectl -n istio-system get configmap istio -o=jsonpath='{.data.mesh}' > mesh-config.yaml

指定输入文件,运行 kube-inject 并部署。

Zip
$ istioctl kube-inject \
    --injectConfigFile inject-config.yaml \
    --meshConfigFile mesh-config.yaml \
    --valuesFile inject-values.yaml \
    --filename @samples/sleep/sleep.yaml@ \
    | kubectl apply -f -
serviceaccount/sleep created
service/sleep created
deployment.apps/sleep created

验证 Sidecar 是否已经被注入到 READY 列下 2/2 的 Sleep Pod 中。

$ kubectl get pod  -l app=sleep
NAME                     READY   STATUS    RESTARTS   AGE
sleep-64c6f57bc8-f5n4x   2/2     Running   0          24s

自动注入 Sidecar

使用 Istio 提供的准入控制器变更 Webhook,可以将 Sidecar 自动添加到可用的 Kubernetes Pod 中。

当你在一个命名空间中设置了 istio-injection=enabled 标签,且 Injection webhook 被启用后,任何新的 Pod 都有将在创建时自动添加 Sidecar。

请注意,区别于手动注入,自动注入发生在 Pod 层面。你将看不到 Deployment 本身有任何更改。取而代之,需要检查单独的 Pod(使用 kubectl describe)来查询被注入的代理。

部署应用

部署 sleep 应用。验证 Deployment 和 Pod 只有一个容器。

Zip
$ kubectl apply -f @samples/sleep/sleep.yaml@
$ kubectl get deployment -o wide
NAME    READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                    SELECTOR
sleep   1/1     1            1           12s   sleep        curlimages/curl           app=sleep
$ kubectl get pod
NAME                    READY   STATUS    RESTARTS   AGE
sleep-8f795f47d-hdcgs   1/1     Running   0          42s

default Namespace 标记为 istio-injection=enabled

$ kubectl label namespace default istio-injection=enabled --overwrite
$ kubectl get namespace -L istio-injection
NAME                 STATUS   AGE     ISTIO-INJECTION
default              Active   5m9s    enabled
istio-system         Active   4m58s   disabled
kube-node-lease      Active   5m10s
kube-public          Active   5m10s
kube-system          Active   5m10s
local-path-storage   Active   5m7s

注入发生在 Pod 创建时。杀死正在运行的 Pod 并验证新创建的 Pod 是否注入 Sidecar。原来的 Pod 具有 READY 为 1/1 的容器,注入 Sidecar 后的 Pod 则具有 READY 为 2/2 的容器。

$ kubectl delete pod -l app=sleep
$ kubectl get pod -l app=sleep
pod "sleep-776b7bcdcd-7hpnk" deleted
NAME                     READY     STATUS        RESTARTS   AGE
sleep-776b7bcdcd-7hpnk   1/1       Terminating   0          1m
sleep-776b7bcdcd-bhn9m   2/2       Running       0          7s

查看已注入 Pod 的详细状态。你应该看到被注入的 istio-proxy 容器和对应的卷。

$ kubectl describe pod -l app=sleep
...
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  ...
  Normal  Created    11s   kubelet            Created container istio-init
  Normal  Started    11s   kubelet            Started container istio-init
  ...
  Normal  Created    10s   kubelet            Created container sleep
  Normal  Started    10s   kubelet            Started container sleep
  ...
  Normal  Created    9s    kubelet            Created container istio-proxy
  Normal  Started    8s    kubelet            Started container istio-proxy

禁用 default Namespace 注入,并确认新的 Pod 在创建时没有 Sidecar。

$ kubectl label namespace default istio-injection-
$ kubectl delete pod -l app=sleep
$ kubectl get pod
namespace/default labeled
pod "sleep-776b7bcdcd-bhn9m" deleted
NAME                     READY     STATUS        RESTARTS   AGE
sleep-776b7bcdcd-bhn9m   2/2       Terminating   0          2m
sleep-776b7bcdcd-gmvnr   1/1       Running       0          2s

控制注入政策

在上面例子中,您在命名空间层级启用和禁用了注入。注入也可以通过配置 Pod 上的 sidecar.istio.io/inject 标签,在每个 Pod 的基础上进行控制。

ResourceLabelEnabled valueDisabled value
Namespaceistio-injectionenableddisabled
Podsidecar.istio.io/inject"true""false"

注入的配置如下:

  1. 如果禁用其中一个标签,则不注入 Pod
  2. 如果启用其中一个标签,则注入 Pod
  3. 如果两个标签都没有设置,如果启用 .values.sidecarInjectorWebhook.enableNamespacesByDefault, 则会注入 Pod。在默认情况下是不启用的,所以 Pod 通常不会被注入。

自定义注入

通常,Pod 的注入是基于 Sidecar 注入模板,在 istio-sidecar-injector Configmap 中配置。每个 Pod 的配置可用于覆盖各个 Pod 上的选项。可通过在 Pod 中添加一个 istio-proxy 容器来完成。Sidecar 注入将会把自定义的任何配置视为默认注入模板的覆盖。

自定义这些设置时,需格外小心,因为允许完全自定义生成的 Pod,包括进行一些更改而导致 Sidecar 容器无法正常运行。

例如,以下配置可自定义各种设置,包括降低 CPU 请求,添加 Volume 挂载,和添加 preStop Hook:

apiVersion: v1
kind: Pod
metadata:
  name: example
spec:
  containers:
  - name: hello
    image: alpine
  - name: istio-proxy
    image: auto
    resources:
      requests:
        cpu: "100m"
    volumeMounts:
    - mountPath: /etc/certs
      name: certs
    lifecycle:
      preStop:
        exec:
          command: ["sleep", "10"]
  volumes:
  - name: certs
    secret:
      secretName: istio-certs

通常,可以设置 Pod 中的任何字段。但是必须注意某些字段:

  • Kubernetes 要求在注入运行之前配置 image。虽然可以您可以设置一个指定的 Image 来覆盖默认的 image 配置,但建议将 image 设置为 auto,可使 Sidecar 注入自动选择要使用的 Image。
  • Pod 中一些字段取决于相关设置。例如,CPU 请求必须小于 CPU 限制。如果两个字段没有一起配置, Pod 可能会无法启动。

另外,某些字段可通过在 Pod 上的 Annotations 配置,但是不建议使用上述方法进行自定义设置。

自定义模板[试验特性]{custom-templates-[experimental]}

可以在安装时定义一个自定义模板,例如,将 GREETING 环境变量注入到 istio-proxy 容器中:

apiVersion: operator.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: istio
spec:
  values:
    sidecarInjectorWebhook:
      templates:
        custom: |
          spec:
            containers:
            - name: istio-proxy
              env:
              - name: GREETING
                value: hello-world

默认情况下,Pod 会使用 sidecar 注入模板,自动创建模板。这可通过 inject.istio.io/templates 注释来替换。例如要应用默认模板和自定义模板,您可以设置 inject.istio.io/templates=sidecar,custom

这些信息有用吗?
Do you have any suggestions for improvement?

Thanks for your feedback!