安装 Sidecar
注入
为了充分利用 Istio 的所有特性,网格中的 Pod 必须运行一个 Istio Sidecar 代理。
下面的章节描述了向 Pod 中注入 Istio Sidecar 的两种方法:使用
istioctl
手动注入或启用
Pod 所属命名空间的 Istio Sidecar 注入器自动注入。
当 Pod 所属命名空间启用自动注入后,自动注入器会使用准入控制器在创建 Pod 时自动注入代理配置。
手动注入直接修改配置,如 Deployment,并将代理配置注入其中。
如果您不确定使用哪一种方法,建议使用自动注入。
自动注入 Sidecar
使用 Istio 提供的准入控制器变更 Webhook, 可以将 Sidecar 自动添加到可用的 Kubernetes Pod 中。
当您在一个命名空间中设置了 istio-injection=enabled
标签,且 Injection Webhook
被启用后,任何新的 Pod 都有将在创建时自动添加 Sidecar。
请注意,区别于手动注入,自动注入发生在 Pod 层面。您将看不到 Deployment 本身有任何更改。
取而代之,需要检查单独的 Pod(使用 kubectl describe
)来查询被注入的代理。
部署应用
部署 curl 应用,验证 Deployment 和 Pod 只有一个容器。
$ kubectl apply -f @samples/curl/curl.yaml@
$ kubectl get deployment -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
curl 1/1 1 1 12s curl curlimages/curl app=curl
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
curl-8f795f47d-hdcgs 1/1 Running 0 42s
将 default
命名空间标记为 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
...
注入发生在 Pod 创建时。杀死正在运行的 Pod 并验证新创建的 Pod 是否注入 Sidecar。
原来的 Pod 具有 1/1 READY
个容器,注入 Sidecar 后的 Pod 则具有 READY 为 2/2 READY
个容器。
$ kubectl delete pod -l app=curl
$ kubectl get pod -l app=curl
pod "curl-776b7bcdcd-7hpnk" deleted
NAME READY STATUS RESTARTS AGE
curl-776b7bcdcd-7hpnk 1/1 Terminating 0 1m
curl-776b7bcdcd-bhn9m 2/2 Running 0 7s
查看已注入 Pod 的详细状态。您应该看到被注入的 istio-proxy
容器和对应的卷。
$ kubectl describe pod -l app=curl
...
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 curl
Normal Started 10s kubelet Started container curl
...
Normal Created 9s kubelet Created container istio-proxy
Normal Started 8s kubelet Started container istio-proxy
禁用 default
命名空间的注入,并确认新的 Pod 在创建时没有 Sidecar。
$ kubectl label namespace default istio-injection-
$ kubectl delete pod -l app=curl
$ kubectl get pod
namespace/default labeled
pod "curl-776b7bcdcd-bhn9m" deleted
NAME READY STATUS RESTARTS AGE
curl-776b7bcdcd-bhn9m 2/2 Terminating 0 2m
curl-776b7bcdcd-gmvnr 1/1 Running 0 2s
控制注入策略
在上面例子中,您在命名空间层级启用和禁用了注入。
注入也可以通过配置 Pod 上的 sidecar.istio.io/inject
标签,在每个 Pod 的基础上进行控制。
资源 | 标签 | 启用的值 | 禁用的值 |
---|---|---|---|
Namespace | istio-injection | enabled | disabled |
Pod | sidecar.istio.io/inject | "true" | "false" |
如果您正在使用控制平面修订版,将通过匹配 istio.io/rev
标签来转为使用特定修订版的标签。例如,对于名为 canary
的修订版:
资源 | 启用的标签 | 禁用的标签 |
---|---|---|
Namespace | istio.io/rev=canary | istio-injection=disabled |
Pod | istio.io/rev=canary | sidecar.istio.io/inject="false" |
如果 istio-injection
标签和 istio.io/rev
标签在同一个命名空间中,则优先使用 istio-injection
标签。
按照以下逻辑配置注入器:
- 如果禁用其中任何一个标签(
istio-injection
或sidecar.istio.io/inject
), 则不会注入 Pod。 - 如果启用其中任何一个标签(
istio-injection
或sidecar.istio.io/inject
或istio.io/rev
), 则会注入 Pod。 - 如果两个标签都没有设置,且启用了
.values.sidecarInjectorWebhook.enableNamespacesByDefault
, 则会注入 Pod。这在默认情况下是不启用的,所以 Pod 通常不会被注入。
手动注入 Sidecar
要手动注入 Deployment,请使用 istioctl kube-inject
:
$ istioctl kube-inject -f @samples/curl/curl.yaml@ | kubectl apply -f -
serviceaccount/curl created
service/curl created
deployment.apps/curl 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
并部署。
$ istioctl kube-inject \
--injectConfigFile inject-config.yaml \
--meshConfigFile mesh-config.yaml \
--valuesFile inject-values.yaml \
--filename @samples/curl/curl.yaml@ \
| kubectl apply -f -
serviceaccount/curl created
service/curl created
deployment.apps/curl created
验证 Sidecar 是否已经被注入到 READY 列下 2/2
的 curl Pod 中。
$ kubectl get pod -l app=curl
NAME READY STATUS RESTARTS AGE
curl-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:
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: ["curl", "10"]
volumes:
- name: certs
secret:
secretName: istio-certs
通常,可以设置 Pod 中的任何字段。但是必须注意某些字段:
- Kubernetes 要求在注入运行之前配置
image
。虽然可以您可以设置一个指定的 Image 来覆盖默认的image
配置,但建议将image
设置为auto
,可使 Sidecar 注入自动选择要使用的 Image。 Pod
中一些字段取决于相关设置。例如,CPU 请求必须小于 CPU 限制。 如果两个字段没有一起配置,Pod 可能会无法启动。- 在某些情况下,
securityContext.RunAsUser
和securityContext.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。
例如,参见以下不完整的资源注解配置和相应注入的资源设置:
spec:
template:
metadata:
annotations:
sidecar.istio.io/proxyCPU: "200m"
sidecar.istio.io/proxyMemoryLimit: "5Gi"
spec:
containers:
- name: istio-proxy
resources:
limits:
memory: 5Gi
requests:
cpu: 200m
memory: 5Gi
securityContext:
allowPrivilegeEscalation: false
自定义模板(试验特性)
可以在安装时定义一个完全自定义的模板。
例如,定义一个自定义模板,将 GREETING
环境变量注入到 istio-proxy
容器中:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
name: istio
spec:
values:
sidecarInjectorWebhook:
templates:
custom: |
spec:
containers:
- name: istio-proxy
env:
- name: GREETING
value: hello-world
默认情况下,istio
会使用自动创建的 sidecar
模板对 Pod 进行注入。
这可通过 inject.istio.io/templates
注解来替换。
例如要应用默认模板和自定义模板,您可以设置 inject.istio.io/templates=sidecar,custom
。
除了 sidecar
之外,默认还会提供 gateway
模板以支持将代理注入到 Gateway Deployment 中。