为了使服务网格正常工作,Istio需要在网格中的每个Pod中注入一个Envoy代理,然后必须通过iptables规则操纵Pod的流量,从而应用程序进出站的流量劫持到Envoy代理。由于每个Pod的iptables规则都是网络命名空间级别的,因此更改不会影响节点上的其他Pod。
默认情况下,Istio使用名为istio-init
的initContainer来创建必要的iptables规则,然后再启动Pod中的其他容器。这就要求网格中的Pod具足够的部署[NET_ADMIN容器](https://zhuanlan.zhihu.com/p/%3C/code%3Ehttps://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container)的 Kubernetes RBAC 权限。NET_ADMIN capabilities 是允许重新配置网络的内核功能。
通常,我们要避免为应用程序Pod提供此 capabilities,因为Istio 用户权限的提升,对于某些组织的安全政策来说,可能是难以接受的。
解决此问题的一种方法是使用CNI插件将iptables的规则配置从pod中移除。
CNI插件
CNI,它的全称是 Container Network Interface,即容器网络的 API 接口。
它是 K8s 中标准的一个调用网络实现的接口。Kubelet 通过这个标准的 API 来调用不同的网络插件以实现不同的网络配置方式,实现了这个接口的就是 CNI 插件,它实现了一系列的 CNI API 接口。常见的 CNI 插件包括 Calico、flannel、Terway、Weave Net 以及 Contiv。
Istio CNI 插件会在 Kubernetes pod 生命周期的网络设置阶段完成 Istio 网格的 pod 流量转发设置工作,因此用户在部署 pods 到 Istio 网格中时,不再需要配置[NET_ADMIN](https://link.zhihu.com/?target=https%3A//istio.io/latest/zh/docs/ops/deployment/requirements/)
capabilities了。 Istio CNI 插件代替了istio-init
容器所实现的功能。
前提条件
- 安装支持 CNI 的 Kubernetes 集群,并且
kubelet
使用--network-plugin=cni
参数启用 CNI 插件。
- AWS EKS、Azure AKS 和 IBM Cloud IKS 集群具备这一功能。
- Google Cloud GKE 集群需要启用网络策略功能,以让 Kubernetes 配置为
network-plugin=cni
。 - OpenShift 默认启用了 CNI。
- Kubernetes 需要启用 ServiceAccount 准入控制器。
- Kubernetes 文档中强烈建议所有使用
ServiceAccounts
的 Kubernetes 安装实例都启用该控制器。
安装
- 确认 Kubernetes 环境的 CNI 插件的
--cni-bin-dir
和--cni-conf-dir
设置。 任何非默认设置都需要参考托管 Kubernetes 设置。 - 使用
istioctl
安装 Istio CNI 和 Istio。 参考 Istio 安装的说明,并设置--set components.cni.enabled=true
和--set cni.components.cni.enabled=true
选项。 在上一步中,如果istio-cni
不是按照默认设置安装的,还需要设置--set values.cni.cniBinDir=...
和--set values.cni.cniConfDir=...
选项。
需要流量重定向的Pod
Istio CNI插件通过根据以下条件列表进行检查来查找需要重定向流量的Pod:
- 该pod不在配置的excludeNamespaces列表中的命名空间中
- 该pod 包含一个名为
istio-proxy
的容器 - 该pod 中有多个容器
- 该pod 无
sidecar.istio.io/inject
注解或该注解值为true
Istio的CNI插件可作为CNI插件链运行。这意味着其配置将作为新的配置列表元素添加到现有CNI插件的配置中。有关更多详细信息,请参见CNI的规范。
其他
Istio CNI 插件在容器运行时的进程空间内运行。因此kubelet
进程会将插件的日志记到它的日志中。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。