设置 Sidecar

注入

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

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

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

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

通过应用 istio-sidecar-injector ConfigMap 中定义的模版进行注入。

手动注入 sidecar

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

Zip

  1. $ istioctl kube-inject -f @samples/sleep/sleep.yaml@ | kubectl apply -f -

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

  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 -

验证 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

自动注入 sidecar

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

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

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

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

禁用或更新注入 webhook

Sidecar 注入 webhook 是默认启用的。如果你希望禁用 webhook,可以使用 HelmsidecarInjectorWebhook.enabled 设置为 false

还有很多其他选项可以配置。

部署应用

部署 sleep 应用。验证 deployment 和 pod 只有一个容器。

Zip

  1. $ kubectl apply -f @samples/sleep/sleep.yaml@
  2. $ kubectl get deployment -o wide
  3. NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
  4. sleep 1 1 1 1 12m sleep tutum/curl app=sleep
  1. $ kubectl get pod
  2. NAME READY STATUS RESTARTS AGE
  3. sleep-776b7bcdcd-7hpnk 1/1 Running 0 4

default namespace 标记为 istio-injection=enabled

  1. $ kubectl label namespace default istio-injection=enabled
  2. $ kubectl get namespace -L istio-injection
  3. NAME STATUS AGE ISTIO-INJECTION
  4. default Active 1h enabled
  5. istio-system Active 1h
  6. kube-public Active 1h
  7. kube-system Active 1h

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

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

查看已注入 pod 的详细状态。你应该看到被注入的 istio-proxy 容器和对应的卷。请确保使用状态为 Running pod 的名称替换以下命令。

  1. $ kubectl describe pod -l app=sleep

禁用 default namespace 注入,并确认新的 pod 在创建时没有 sidecar。

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

理解原理

当 Kubernetes 调用 webhook 时,admissionregistration 配置被应用。默认配置将 sidecar 注入到所有拥有 istio-injection=enabled 标签的 namespace 下的 pod 中。istio-sidecar-injector 配置字典指定了注入 sidecar 的配置。如需更改指定哪些 namespace 被注入,你可以使用以下命令编辑 MutatingWebhookConfiguration

  1. $ kubectl edit mutatingwebhookconfiguration istio-sidecar-injector

修改 MutatingWebhookConfiguration 之后,您应该重启 sidecar 注入器的 pod。

例如,你可以修改 MutatingWebhookConfiguration 使 sidecar 注入到所有不具有某个标签的 namespace 中。编辑这项配置是更高阶的操作。更多有关信息,请参考 Kubernetes 的 MutatingWebhookConfiguration API 文档。

策略

disabled - 默认情况下不会将 sidecar 注入到 pod 中。在 pod 模板规范中添加 sidecar.istio.io/inject 的值为 true 来覆盖默认值并启用注入。

enabled - Sidecar 将默认注入到 pod 中。在 pod 模板规范中添加 sidecar.istio.io/inject 的值为 false 来覆盖默认值并禁用注入。

下面的示例使用 sidecar.istio.io/inject 注解来禁用 sidecar 注入。

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: ignored
  5. spec:
  6. template:
  7. metadata:
  8. annotations:
  9. sidecar.istio.io/inject: "false"
  10. spec:
  11. containers:
  12. - name: ignored
  13. image: tutum/curl
  14. command: ["/bin/sleep","infinity"]

模版

Sidecar 注入模板使用 https://golang.org/pkg/text/template,当解析和执行时,将解码成下面的结构体,包含需要注入到 pod 中的容器和卷。

  1. type SidecarInjectionSpec struct {
  2. RewriteAppHTTPProbe bool `yaml:"rewriteAppHTTPProbe"`
  3. InitContainers []corev1.Container `yaml:"initContainers"`
  4. Containers []corev1.Container `yaml:"containers"`
  5. Volumes []corev1.Volume `yaml:"volumes"`
  6. DNSConfig *corev1.PodDNSConfig `yaml:"dnsConfig"`
  7. ImagePullSecrets []corev1.LocalObjectReference `yaml:"imagePullSecrets"`
  8. }

该模板在运行时应用于以下数据结构。

  1. type SidecarTemplateData struct {
  2. DeploymentMeta *metav1.ObjectMeta
  3. ObjectMeta *metav1.ObjectMeta
  4. Spec *corev1.PodSpec
  5. ProxyConfig *meshconfig.ProxyConfig // Defined by https://istio.io/docs/reference/config/service-mesh.html#proxyconfig
  6. MeshConfig *meshconfig.MeshConfig // Defined by https://istio.io/docs/reference/config/service-mesh.html#meshconfig
  7. }

ObjectMetaSpec 来源于 pod。ProxyConfigMeshConfig 来源于 istio-system namespace 下 istio 的 ConfigMap。模版可以使用这些数据有条件地定义被注入的卷和容器。

例如下面的模版。

  1. containers:
  2. - name: istio-proxy
  3. image: istio.io/proxy:0.5.0
  4. args:
  5. - proxy
  6. - sidecar
  7. - --configPath
  8. - {{ .ProxyConfig.ConfigPath }}
  9. - --binaryPath
  10. - {{ .ProxyConfig.BinaryPath }}
  11. - --serviceCluster
  12. {{ if ne "" (index .ObjectMeta.Labels "app") -}}
  13. - {{ index .ObjectMeta.Labels "app" }}
  14. {{ else -}}
  15. - "istio-proxy"
  16. {{ end -}}

将在使用模版 samples/sleep/sleep.yaml 定义的 pod 被应用时变为

  1. containers:
  2. - name: istio-proxy
  3. image: istio.io/proxy:0.5.0
  4. args:
  5. - proxy
  6. - sidecar
  7. - --configPath
  8. - /etc/istio/proxy
  9. - --binaryPath
  10. - /usr/local/bin/envoy
  11. - --serviceCluster
  12. - sleep

更多控制:添加例外

有些情况下用户无法控制 pod 的创建,例如,这些用户是被其他人创建的。因此他们无法在 pod 中添加 sidecar.istio.io/inject 注解,来明确是否安装 sidecar。

考虑在部署应用程序时创建辅助 pod 作为中间步骤。例如 OpenShift Source to Image Builds,创建这样的 pod 用于构建应用程序的源代码。构建二进制工件后,应用程序 pod 就可以运行了,而用于辅助的 pod 则被丢弃。这些中间 pod 不应该有 Istio sidecar,即使策略被设置为 enabled,并且名称空间被正确标记为自动注入。

对于这种情况,你可以根据 pod 上的标签,指示 Istio 不要在那些 pod 中注入 sidecar。可以通过编辑 istio-sidecar-injector 的 ConfigMap 并添加 neverInjectSelector 条目来实现。它是一个 Kubernetes 标签选择器数组,使用 OR'd,在第一次匹配成功后则停止。看一个例子:

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: istio-sidecar-injector
  5. data:
  6. config: |-
  7. policy: enabled
  8. neverInjectSelector:
  9. - matchExpressions:
  10. - {key: openshift.io/build.name, operator: Exists}
  11. - matchExpressions:
  12. - {key: openshift.io/deployer-pod-for.name, operator: Exists}
  13. template: |-
  14. initContainers:
  15. ...

上面声明的意思是:永远不要注入带有 openshift.io/build.name 或者 openshift.io/deployer-pod-for.name 标签的 pod —— 标签的值无关紧要,我们只检查键是否存在。添加了这个规则之后,就涵盖了上面所说的 OpenShift 的构建用例,也就是说辅助 pod 不会被注入 sidecar(因为 source-to-image 工具产生的辅助 pod 明确包含这些标签)。

完整起见,您还可以使用一个名为 alwaysInjectSelector 的字段,它具有类似的语法,总是将 sidecar 注入匹配标签选择器的 pod 中,而忽略全局策略。

使用标签选择器的方法在表达这些例外时提供了很大的灵活性。查看这些文档看看可以用它们来做什么!

值得注意的是,pod 中的注解具有比标签选择器更高的优先级。如果一个 pod 有 sidecar.istio.io/inject: "true/false" 的标记那么它将先被履行。因此,优先级的顺序为:

Pod Annotations → NeverInjectSelector → AlwaysInjectSelector → Default Policy

卸载 sidecar 自动注入器

  1. $ kubectl delete mutatingwebhookconfiguration istio-sidecar-injector
  2. $ kubectl -n istio-system delete service istio-sidecar-injector
  3. $ kubectl -n istio-system delete deployment istio-sidecar-injector
  4. $ kubectl -n istio-system delete serviceaccount istio-sidecar-injector-service-account
  5. $ kubectl delete clusterrole istio-sidecar-injector-istio-system
  6. $ kubectl delete clusterrolebinding istio-sidecar-injector-admin-role-binding-istio-system

上面的命令不会从 pod 中移除注入的 sidecar。需要进行滚动更新或者直接删除 pod,并强制 deployment 创建它们。

此外,还可以清理在此任务中修改过的其他资源。

  1. $ kubectl label namespace default istio-injection-

相关内容

Pod 和 Service

在启用了 Istio 的集群中运行 Kubernetes 的 Pod 和 Service,您需要做些准备。

揭开 Istio Sidecar 注入模型的神秘面纱

揭秘 Istio 是如何将其数据平面组件添加到现有 deployment。

安装 Istio CNI 插件

安装并使用 Istio CNI 插件,可以让运维人员用更低的权限来部署服务。

DNS 证书管理

在 Istio 中配置和管理 DNS 证书。

安全管理 Webhook

一种更安全管理 Istio webhook 的方法。

Docker Desktop

在 Docker Desktop 中运行 Istio 的设置说明。