安装 Istio CNI 插件
按照此流程利用 Istio 容器网络接口(CNI)来安装、配置和使用 Istio 网格。
默认情况下,Istio 会在网格中部署的 Pod 上注入一个 initContainer
:istio-init
。
istio-init
容器会将 Pod 的网络流量劫持到 Istio Sidecar 代理上。
这需要用户或部署 Pod 的 Service Account 具有足够的部署
NET_ADMIN
容器的 Kubernetes RBAC 权限。
Istio 用户权限的提升,对于某些组织的安全政策来说,可能是难以接受的。
Istio CNI 插件就是一个能够替代 istio-init
容器来实现相同的网络功能但却不需要 Istio 用户申请额外的 Kubernetes RBAC 授权的方案。
Istio CNI 插件会在 Kubernetes Pod 生命周期的网络设置阶段完成 Istio 网格的 Pod 流量转发设置工作,因此用户在部署 Pod 到 Istio 网格中时,不再需要配置 NET_ADMIN
功能需求了。
Istio CNI 插件代替了 istio-init
容器所实现的功能。
安装 CNI
前提条件
安装支持 CNI 的 Kubernetes 集群,并且
kubelet
使用--network-plugin=cni
参数启用 CNI 插件。- AWS EKS、Azure AKS 和 IBM Cloud IKS 集群具备这一功能。
- Google Cloud GKE 集群在启用以下特性时启用 CNI: network policy, intranode visibility, workload identity, pod security policy, dataplane v2。
- OpenShift 默认启用了 CNI。
Kubernetes 需要启用 ServiceAccount 准入控制器。
- Kubernetes 文档中强烈建议所有使用
ServiceAccounts
的 Kubernetes 安装实例都启用该控制器。
- Kubernetes 文档中强烈建议所有使用
用 CNI 插件安装 Istio
在大多数环境中,可以使用以下配置安装基础的 Istio 集群并启用 CNI:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
components:
cni:
enabled: true
这将部署 istio-cni-node
DaemonSet 到集群中,将 Istio CNI 插件可执行文件安装到每个节点上并为此插件设置必要的配置。
CNI DaemonSet 使用 system-node-critical
PriorityClass
来运行。
有几个常用的安装选项:
components.cni.namespace=kube-system
配置命名空间以安装 CNI DaemonSet。values.cni.cniBinDir
和values.cni.cniConfDir
配置安装插件可执行文件的目录路径并创建插件配置。values.cni.cniConfFileName
配置插件配置文件的名称。values.cni.chained
控制是否将插件配置为链式的 CNI 插件。
托管 Kubernetes 设置
istio-cni
插件预期可用于任何使用 CNI 插件的托管 Kubernetes 版本。
默认的安装配置适用于大多数平台。某些平台需要特殊的安装设置。
Google Kubernetes Engine
apiVersion: install.istio.io/v1alpha1 kind: IstioOperator spec: components: cni: enabled: true namespace: kube-system values: cni: cniBinDir: /home/kubernetes/bin
Red Hat OpenShift 4.2+
apiVersion: install.istio.io/v1alpha1 kind: IstioOperator spec: components: cni: enabled: true namespace: kube-system values: sidecarInjectorWebhook: injectedAnnotations: k8s.v1.cni.cncf.io/networks: istio-cni cni: cniBinDir: /var/lib/cni/bin cniConfDir: /etc/cni/multus/net.d cniConfFileName: istio-cni.conf chained: false
操作细节
升级
当使用原地升级来升级 Istio 时,CNI 组件可以使用一个 IstioOperator
资源与控制平面一起升级。
使用金丝雀升级升级 Istio 时,由于 CNI 组件以集群单例运行,建议将 CNI 组件与改版后的控制平面分开运行和升级。
下面的 IstioOperator
可用于独立操作 CNI 组件。
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
profile: empty # Do not include other components
components:
cni:
enabled: true
values:
cni:
excludeNamespaces:
- istio-system
- kube-system
在启用 CNI 组件的情况下安装修订的控制平面时,需要设置 values.istio_cni.enabled
,这样 Sidecar 注入程序就不会注入 istio-init
初始化容器。
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
revision: REVISION_NAME
...
values:
istio_cni:
enabled: true
...
1.x
版本的 CNI 插件兼容 1.x-1
、1.x
和 1.x+1
版本的控制平面,这意味着 CNI 和控制平面可以按任何顺序进行升级,只要它们的版本差异在一个次要版本之内。
竞争条件和缓解措施
Istio CNI DaemonSet 在每个节点上安装 CNI 网络插件。
但是,在将 DaemonSet Pod 调度到一个节点上与 CNI 插件被安装好并准备就绪之间存在一个时间间隔。
应用 Pod 有可能在这个时间间隔内启动,而 kubelet
不了解 Istio CNI 插件。
结果应用 Pod 在没有 Istio 流量重定向的情况下启动并绕过了 Istio Sidecar。
为了缓解应用 Pod 和 Istio CNI DaemonSet 之间的竞争,添加了一个 istio-validation
初始化容器作为 Sidecar 注入的一部分。
该容器会检测流量重定向是否设置正确,如果不正确则阻止 Pod 启动。CNI DaemonSet 将检测并驱逐任何卡在这种状态下的 Pod。
当新的 Pod 启动时,它应该正确设置流量重定向。此缓解措施默认被启用,可以通过将 values.cni.repair.enabled
设置为 false 来关闭。
流量重定向参数
为了将应用 Pod 的网络命名空间中的流量重定向至 Istio Sidecar,Istio CNI 插件配置了命名空间的 iptables。 您可以使用与正常情况相同的 Pod 注解来调整流量重定向参数,例如要包含或排除在重定向之外的端口和 IP 范围。 有关可用参数,请参阅资源注解。
和应用的初始化容器的兼容性
Istio CNI 插件可能会导致与任何应用 initContainers
的网络连通性问题。
使用 Istio CNI 时,kubelet
会通过以下步骤启动一个注入的 Pod:
- Istio CNI 插件在 Pod 内设置流量重定向到 Istio Sidecar。
- 等待所有的初始化容器成功执行完毕。
- Istio Sidecar 跟随 Pod 的其它容器一起启动。
初始化容器在 Sidecar 启动之前执行,这会导致在它们执行期间会有流量丢失。 可以用以下的一种或所有设置来防止流量丢失:
- 使用
runAsUser
讲过初始化容器的uid
设置为1337
。1337
是 Sidecar 代理使用的uid
。 这个uid
发送的流量并非通过 Istio 的iptables
规则进行捕获。 应用容器流量仍将像往常一样被捕获。 - 设置
traffic.sidecar.istio.io/excludeOutboundIPRanges
注解来禁止重定向流量到任何与初始化容器有通信的 CIDR。 - 设置
traffic.sidecar.istio.io/excludeOutboundPorts
注解来禁止重定向流量到初始化容器所用到的出站端口。
和其它 CNI 插件的兼容性
Istio CNI 插件维护着与当前需要 NET_ADMIN
和 NET_RAW
能力的 istio-init
容器相同的 CNI 插件集。
Istio CNI 插件作为一个链式 CNI 插件存在。也就是说它的配置会作为一个新的配置列表元素被加入到现存 CNI 插件配置中。
参考 CNI 规范参考中的更多细节。
当 Pod 被创建或删除时,容器运行时会按照列表顺序调用每个插件。Istio CNI 插件只会把应用 Pod 的流量重定向到 Sidecar 中(通过在 Pod 的网络命名空间中使用 iptables
完成)。