cni规范: https://www.cni.dev/docs/spec/
/etc/cni/net.d目录下的配置文件命名遵循一个核心原则:按字典顺序(lexicographic order)加载。
官方支持的cni插件:
- bandwidth: 对容器的网络接口进行带宽限速,可设置入口和出口的带宽上限。
- bridge: 最常用的插件之一。在宿主机上创建一个虚拟网桥,并将容器网络接口连接到该网桥,使同一主机上的容器能够通信。
- dhcp: 为容器从外部DHCP服务器获取IP地址、路由等网络配置,而不是由插件静态分配。
- dummy: 创建一个没有任何实际连接的虚拟网络接口,通常用于测试或保留IP地址。
- firewall: 为容器接口配置iptables防火墙规则,实现网络访问控制。
- host-device: 将宿主机上的一个物理或虚拟网络设备直接移入容器网络命名空间供其使用。
- host-local: 一个IP地址管理插件。在宿主机本地维护一个IP地址池,并从池中为容器分配和回收IP地址。
- ipvlan: 在宿主机物理网卡上创建虚拟子接口,并直接分配给容器。所有容器共享物理网卡的MAC地址,但拥有独立的IP地址,网络性能好。
- loopback: 为容器创建回环接口,这是每个容器网络命名空间的基础设备。
- macvlan: 在宿主机物理网卡上创建虚拟子接口,并直接分配给容器。每个容器拥有独立的MAC和IP地址,像物理机一样直接接入二层网络。
- portmap: 实现容器网络的端口映射,将宿主机的端口流量转发到容器内,常用于支持hostPort配置。
- ptp: 在宿主机和容器之间创建一对虚拟以太网设备,形成点对点连接,常用于Underlay网络或特定路由场景。
- sbr: 为容器配置基于源地址的路由策略,用于实现多网卡容器或特定网络路径选择。
- static: 一个IPAM插件,为容器静态分配指定的IP地址、路由和DNS信息。
- tap: 创建一个TAP设备(二层虚拟网卡)并移入容器,常用于需要与虚拟机或特定网络协议栈交互的场景。
- tuning: 调整容器网络接口的各种内核参数,例如MTU、MAC地址、队列长度等。
- vlan: 为容器的网络接口分配一个VLAN ID,实现网络隔离。
- vrf: 将容器的网络接口关联到一个VRF实例中,实现虚拟路由和转发,用于网络隔离和策略路由。
在实际的容器网络配置中,通常会通过一个配置文件将多个插件组合成一个完整的解决方案。例如,一个常见的配置链可能是:bridge+ tuning+ portmap + loopback,并由host-local负责IP地址分配。
{
"cniVersion": "1.0.0",
"name": "mybridge",
"plugins": [
{
"type": "loopback"
},
{
"type": "bridge",
"bridge": "cni0",
"ipam": {
"type": "host-local",
"ranges": [
[
{
"subnet": "10.22.0.0/16",
"rangeStart": "10.22.0.100",
"rangeEnd": "10.22.0.200",
"gateway": "10.22.0.1"
}
]
],
"routes": [
{"dst": "0.0.0.0/0", "gw": "10.22.0.1"}
],
"dataDir": "/var/lib/cni/mybridge"
}
},
{
"type": "tuning"
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
},
"snat": true
}
],
"dns": {
"nameservers": ["8.8.8.8", "8.8.4.4"]
}
}
上面dns配置的注意事项:
- DNS 配置是可选的,如果不指定,容器会继承宿主机的 DNS 配置
- 在 Kubernetes 环境中,通常会通过 kubelet 的 –resolv-conf参数或 Pod 规范中的 dnsConfig字段控制 DNS
- 确保配置的 DNS 服务器可以从容器网络访问到
1. cni是什么?
CNI插件:遵循专门为交付操作设计的appc/CNI规范 Kubelet插件:使用bridge和host-local的CNI插件来实现基本的cbr0
- 安装 kubelet默认有个简单的网络插件和一个默认的整个集群公用的网络。它会在启动时探测插件并记住它,然后在pod生命周期的适当时间执行该插件(这仅适用于Docker,因为rkt管理自己的CNI插件)。可以使用kubelet的两个命令行参数来指定要使用的插件:
- cni-bin-dir: kubelet会在启动的时候探测这个目录(并记录下来)
- network-plugin: 指定在cni-bin-dir目录下的某个插件。它必须和探针之前记录的插件名保持一致。例如cni插件,它的插件名是"cni"
-
Network Plugin的要求 除了要提供用于配置和清理Pod网路的NetworkPlugin的接口,还要给插件提供和kube-proxy相关的支持。因为iptables proxy直接依赖iptables,所以插件可能需要确保iptables可以使用容器的流量。例如,如果这个插件连接容器到一个linux网桥,就必须设置net/bridge/bridge-nf-call-iptables这个sysctl的值为1,以确保iptables proxy功能的正常。如果插件没有使用Linux网桥(但是需要像Open vSwitch之类的其他机制)就需要确保流量被正确路由到该代理。
-
CNI 在kubelet使用–network-plugin=cni命令行参数的时候就会启用CNI网络插件。kubelet会从–cni-conf-dir目录下(默认值为/etc/cni/net.d)读取以字典顺序排序的第一个文件的内容,并从这个文件中获取CNI配置来建立每个pod的网络。这个CNI配置文件必须满足CNI规范,任何被CNI配置文件引用的CNI插件都必须存放在–cni-bin-dir目录下(默认值是/opt/cni/bin)。
2. Q&A
-
容器内要想访问本宿主机的某个端口,就必须让本宿主机的防火墙放行docker或者pod的网段。出了这台机器就不需要,因为出了容器所在的那台机器,源ip就不再是容器ip了。
-
多节点k8s集群,节点间需要放行pod网段么?
不需要完全放行,只需要放行所有节点的ip就行了,例如:
如果不放行,会导致跨节点Pod通信异常,但是不影响本节点Pod间的通信。
当 Pod A(10.244.1.2) 访问 Pod B(10.244.2.3)时,流量如何通过防火墙:
- 数据包从 Pod A 发出,源 IP 10.244.1.2,目的 IP 10.244.2.3。
- Node 1 的路由表将数据包转发到 Node 2(通过 overlay 网络或路由协议)。
- 此时数据包被封装,源 IP 变为 Node 1 的 IP(如 192.168.1.101)。
- Node 2 的防火墙规则检查:
- 源 IP:192.168.1.101(Node 1 的 IP,合法)。
- 目的 IP:10.244.2.3(属于 Pod 网段,合法)。
本文发表于 0001-01-01,最后修改于 0001-01-01。
本站永久域名「 jiavvc.top 」,也可搜索「 极客油画 」找到我。

