网络插件
Kubernetes中的网络插件有几种类型:
- CNI 插件:遵守容器网络接口(Container Network Interface,CNI) 规范,其设计上偏重互操作性。
- Kubernetes 遵从 CNI 规范的 v0.4.0 版本。
- Kubenet 插件:使用
bridge
和host-local
CNI 插件实现了基本的cbr0
。
安装
kubelet 有一个单独的默认网络插件,以及一个对整个集群通用的默认网络。 它在启动时探测插件,记住找到的内容,并在 Pod 生命周期的适当时间执行 所选插件(这仅适用于 Docker,因为 CRI 管理自己的 CNI 插件)。 在使用插件时,需要记住两个 kubelet 命令行参数:
cni-bin-dir
: kubelet 在启动时探测这个目录中的插件network-plugin
: 要使用的网络插件来自cni-bin-dir
。 它必须与从插件目录探测到的插件报告的名称匹配。 对于 CNI 插件,其值为 “cni”。
网络插件要求
除了提供 NetworkPlugin
接口 来配置和清理 Pod 网络之外,该插件还可能需要对 kube-proxy 的特定支持。 iptables 代理显然依赖于 iptables,插件可能需要确保 iptables 能够监控容器的网络通信。 例如,如果插件将容器连接到 Linux 网桥,插件必须将 net/bridge/bridge-nf-call-iptables
系统参数设置为1
,以确保 iptables 代理正常工作。 如果插件不使用 Linux 网桥(而是类似于 Open vSwitch 或者其它一些机制), 它应该确保为代理对容器通信执行正确的路由。
默认情况下,如果未指定 kubelet 网络插件,则使用 noop
插件, 该插件设置 net/bridge/bridge-nf-call-iptables=1
,以确保简单的配置 (如带网桥的 Docker )与 iptables 代理正常工作。
CNI
通过给 Kubelet 传递 --network-plugin=cni
命令行选项可以选择 CNI 插件。 Kubelet 从 --cni-conf-dir
(默认是 /etc/cni/net.d
) 读取文件并使用 该文件中的 CNI 配置来设置各个 Pod 的网络。 CNI 配置文件必须与 CNI 规约 匹配,并且配置所引用的所有所需的 CNI 插件都应存在于 --cni-bin-dir
(默认是 /opt/cni/bin
)下。
如果这个目录中有多个 CNI 配置文件,kubelet 将会使用按文件名的字典顺序排列 的第一个作为配置文件。
除了配置文件指定的 CNI 插件外,Kubernetes 还需要标准的 CNI lo
插件,最低版本是0.2.0。
支持 hostPort
CNI 网络插件支持 hostPort
。 你可以使用官方 portmap 插件,它由 CNI 插件团队提供,或者使用你自己的带有 portMapping 功能的插件。
如果你想要启动 hostPort
支持,则必须在 cni-conf-dir
指定 portMappings capability
。 例如:
{
"name": "k8s-pod-network",
"cniVersion": "0.3.0",
"plugins": [
{
"type": "calico",
"log_level": "info",
"datastore_type": "kubernetes",
"nodename": "127.0.0.1",
"ipam": {
"type": "host-local",
"subnet": "usePodCidr"
},
"policy": {
"type": "k8s"
},
"kubernetes": {
"kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
}
},
{
"type": "portmap",
"capabilities": {"portMappings": true}
}
]
}
支持流量整形
实验功能
CNI 网络插件还支持 pod 入口和出口流量整形。 你可以使用 CNI 插件团队提供的 bandwidth 插件,也可以使用你自己的具有带宽控制功能的插件。
如果你想要启用流量整形支持,你必须将 bandwidth
插件添加到 CNI 配置文件 (默认是 /etc/cni/net.d
)并保证该可执行文件包含在你的 CNI 的 bin 文件夹内 (默认为 /opt/cni/bin
)。
{
"name": "k8s-pod-network",
"cniVersion": "0.3.0",
"plugins": [
{
"type": "calico",
"log_level": "info",
"datastore_type": "kubernetes",
"nodename": "127.0.0.1",
"ipam": {
"type": "host-local",
"subnet": "usePodCidr"
},
"policy": {
"type": "k8s"
},
"kubernetes": {
"kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
}
},
{
"type": "bandwidth",
"capabilities": {"bandwidth": true}
}
]
}
现在,你可以将 kubernetes.io/ingress-bandwidth
和 kubernetes.io/egress-bandwidth
注解添加到 pod 中。例如:
apiVersion: v1
kind: Pod
metadata:
annotations:
kubernetes.io/ingress-bandwidth: 1M
kubernetes.io/egress-bandwidth: 1M
...
kubenet
Kubenet 是一个非常基本的、简单的网络插件,仅适用于 Linux。 它本身并不实现更高级的功能,如跨节点网络或网络策略。 它通常与云驱动一起使用,云驱动为节点间或单节点环境中的通信设置路由规则。
Kubenet 创建名为 cbr0
的网桥,并为每个 pod 创建了一个 veth 对, 每个 Pod 的主机端都连接到 cbr0
。 这个 veth 对的 Pod 端会被分配一个 IP 地址,该 IP 地址隶属于节点所被分配的 IP 地址范围内。节点的 IP 地址范围则通过配置或控制器管理器来设置。 cbr0
被分配一个 MTU,该 MTU 匹配主机上已启用的正常接口的最小 MTU。
使用此插件还需要一些其他条件:
- 需要标准的 CNI
bridge
、lo
以及host-local
插件,最低版本是0.2.0。 kubenet 首先在/opt/cni/bin
中搜索它们。 指定cni-bin-dir
以提供 其它搜索路径。首次找到的匹配将生效。 - Kubelet 必须和
--network-plugin=kubenet
参数一起运行,才能启用该插件。 - Kubelet 还应该和
--non-masquerade-cidr=<clusterCidr>
参数一起运行, 以确保超出此范围的 IP 流量将使用 IP 伪装。 - 节点必须被分配一个 IP 子网,通过kubelet 命令行的
--pod-cidr
选项或 控制器管理器的命令行选项--allocate-node-cidrs=true --cluster-cidr=<cidr>
来设置。
自定义 MTU(使用 kubenet)
要获得最佳的网络性能,必须确保 MTU 的取值配置正确。 网络插件通常会尝试推断出一个合理的 MTU,但有时候这个逻辑不会产生一个最优的 MTU。 例如,如果 Docker 网桥或其他接口有一个小的 MTU, kubenet 当前将选择该 MTU。 或者如果你正在使用 IPSEC 封装,则必须减少 MTU,并且这种计算超出了大多数网络插件的能力范围。
如果需要,你可以使用 network-plugin-mtu
kubelet 选项显式的指定 MTU。 例如:在 AWS 上 eth0
MTU 通常是 9001,因此你可以指定 --network-plugin-mtu=9001
。 如果你正在使用 IPSEC ,你可以减少它以允许封装开销,例如 --network-plugin-mtu=8873
。
此选项会传递给网络插件; 当前 仅 kubenet 支持 network-plugin-mtu
。
用法总结
--network-plugin=cni
用来表明我们要使用cni
网络插件,实际的 CNI 插件 可执行文件位于--cni-bin-dir
(默认是/opt/cni/bin
)下, CNI 插件配置位于--cni-conf-dir
(默认是/etc/cni/net.d
)下。--network-plugin=kubenet
用来表明我们要使用kubenet
网络插件,CNIbridge
和host-local
插件位于/opt/cni/bin
或cni-bin-dir
中。--network-plugin-mtu=9001
指定了我们使用的 MTU,当前仅被kubenet
网络插件使用。