安装 Sidecar

注入

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

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

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

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

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

自动注入 Sidecar

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

虽然准入控制器默认情况下是启用的,但一些 Kubernetes 发行版会禁用这些控制器。 如果出现这种情况,根据指示说明来启用准入控制器

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

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

部署应用

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

Zip

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

default 命名空间标记为 istio-injection=enabled

  1. $ kubectl label namespace default istio-injection=enabled --overwrite
  2. $ kubectl get namespace -L istio-injection
  3. NAME STATUS AGE ISTIO-INJECTION
  4. default Active 5m9s enabled
  5. ...

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

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

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

  1. $ kubectl describe pod -l app=sleep
  2. ...
  3. Events:
  4. Type Reason Age From Message
  5. ---- ------ ---- ---- -------
  6. ...
  7. Normal Created 11s kubelet Created container istio-init
  8. Normal Started 11s kubelet Started container istio-init
  9. ...
  10. Normal Created 10s kubelet Created container sleep
  11. Normal Started 10s kubelet Started container sleep
  12. ...
  13. Normal Created 9s kubelet Created container istio-proxy
  14. Normal Started 8s kubelet Started container istio-proxy

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

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

控制注入策略

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

资源标签启用的值禁用的值
Namespaceistio-injectionenableddisabled
Podsidecar.istio.io/inject“true”“false”

如果您正在使用控制平面修订版,将通过匹配 istio.io/rev 标签来转为使用特定修订版的标签。例如,对于名为 canary 的修订版:

资源启用的标签禁用的标签
Namespaceistio.io/rev=canaryistio-injection=disabled
Podistio.io/rev=canarysidecar.istio.io/inject=”false”

如果 istio-injection 标签和 istio.io/rev 标签在同一个命名空间中,则优先使用 istio-injection 标签。

按照以下逻辑配置注入器:

  1. 如果禁用其中任何一个标签(istio-injectionsidecar.istio.io/inject), 则不会注入 Pod。
  2. 如果启用其中任何一个标签(istio-injectionsidecar.istio.io/injectistio.io/rev), 则会注入 Pod。
  3. 如果两个标签都没有设置,且启用了 .values.sidecarInjectorWebhook.enableNamespacesByDefault, 则会注入 Pod。这在默认情况下是不启用的,所以 Pod 通常不会被注入。

手动注入 Sidecar

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

Zip

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

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

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

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

Zip

  1. $ istioctl kube-inject \
  2. --injectConfigFile inject-config.yaml \
  3. --meshConfigFile mesh-config.yaml \
  4. --valuesFile inject-values.yaml \
  5. --filename @samples/sleep/sleep.yaml@ \
  6. | kubectl apply -f -
  7. serviceaccount/sleep created
  8. service/sleep created
  9. deployment.apps/sleep created

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

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

自定义注入

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

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

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

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: example
  5. spec:
  6. containers:
  7. - name: hello
  8. image: alpine
  9. - name: istio-proxy
  10. image: auto
  11. resources:
  12. requests:
  13. cpu: "100m"
  14. volumeMounts:
  15. - mountPath: /etc/certs
  16. name: certs
  17. lifecycle:
  18. preStop:
  19. exec:
  20. command: ["sleep", "10"]
  21. volumes:
  22. - name: certs
  23. secret:
  24. secretName: istio-certs

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

  • Kubernetes 要求在注入运行之前配置 image。虽然可以您可以设置一个指定的 Image 来覆盖默认的 image 配置,但建议将 image 设置为 auto,可使 Sidecar 注入自动选择要使用的 Image。
  • Pod 中一些字段取决于相关设置。例如,CPU 请求必须小于 CPU 限制。 如果两个字段没有一起配置,Pod 可能会无法启动。
  • 在某些情况下,securityContext.RunAsUsersecurityContext.RunAsGroup 字段可能不会被接受, 例如,当使用 TPROXY 模式时,因为它要求 Sidecar 以用户 0 运行。 错误地覆盖这些字段可能会导致流量丢失,因此应格外小心。

另外,某些字段可通过在 Pod 上的注解进行配置, 但是不建议使用上述方法进行自定义设置。必须特别注意某些注解:

  • 如果设置了 sidecar.istio.io/proxyCPU,则务必显式设置 sidecar.istio.io/proxyCPULimit。 否则该 Sidecar 的 cpu 限制将被设置为 unlimited。
  • 如果设置了 sidecar.istio.io/proxyMemory,则务必显式设置 sidecar.istio.io/proxyMemoryLimit。 否则该 Sidecar 的 memory 限制将被设置为 unlimited。

例如,参见以下不完整的资源注解配置和相应注入的资源设置:

  1. spec:
  2. template:
  3. metadata:
  4. annotations:
  5. sidecar.istio.io/proxyCPU: "200m"
  6. sidecar.istio.io/proxyMemoryLimit: "5Gi"
  1. spec:
  2. containers:
  3. - name: istio-proxy
  4. resources:
  5. limits:
  6. memory: 5Gi
  7. requests:
  8. cpu: 200m
  9. memory: 5Gi
  10. securityContext:
  11. allowPrivilegeEscalation: false

自定义模板(试验特性)

此功能为试验特性功能,可随时更改或删除。

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

  1. apiVersion: install.istio.io/v1alpha1
  2. kind: IstioOperator
  3. metadata:
  4. name: istio
  5. spec:
  6. values:
  7. sidecarInjectorWebhook:
  8. templates:
  9. custom: |
  10. spec:
  11. containers:
  12. - name: istio-proxy
  13. env:
  14. - name: GREETING
  15. value: hello-world

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

除了 sidecar 之外,默认还会提供 gateway 模板以支持将代理注入到 Gateway Deployment 中。