kubernetes深度分析 cni calico
5. containerd 使用 calixxx 虚拟网卡通过 veth pair 的方式生成 对端虚拟网卡eth0 for pod,并放入pod对应的网络命名空间。网络的配置方式以cni插件的方式支持动态扩展,calico即其中一种网络插件。calico 的地址分配使用calico-ipam进行,但该工具管理的地址数据存放在etcd中,可以使用calicoctl进行查看。4. 在calico场景
工作原理
cni主要为pod提供网络配置,完成集群内pod与pod的网络联通。网络的配置方式以cni插件的方式支持动态扩展,calico即其中一种网络插件。
下面以calico作为网络插件的场景为例,分析cni的工作原理
1. cni 逻辑主要在containerd中,当kubelet 发现pod需要创建时将通过rpc调用containerd 为pod配置网络。
2. containerd中的cni逻辑将加载目录 /etc/cni/net.d/ 下的配置文件,每个没配置文件将触发网络插件的注册。
3. 当创建pod网络时,将根据注册的插件调用 /opt/cni/bin/ 下的bin文件并传入参数执行完成网络的配置。
4. 在calico场景下,在节点上创建了联通节点间流量的隧道tunl0,并为每个pod创建了calixxx的虚拟网卡。
5. containerd 使用 calixxx 虚拟网卡通过 veth pair 的方式生成 对端虚拟网卡eth0 for pod,并放入pod对应的网络命名空间。
6. 当不同节点的pod相互访问时,流量将通过 eth0(in pod) --->calixxxx-->tunl0-->calixxx--->eth0(in pod) 连通过。

配置分析
cni配置文件
通过配置 "snat": true 可以确定节点间通信将采用snat的方式,calico在ipip模式下会采用该方式。
{
"name": "k8s-pod-network",
"cniVersion": "0.3.1",
"plugins": [
{
"container_settings": {
"allow_ip_forwarding": false
},
"datastore_type": "kubernetes",
"endpoint_status_dir": "/var/run/calico/endpoint-status",
"ipam": {
"assign_ipv4": "true",
"assign_ipv6": "false",
"type": "calico-ipam"
},
"kubernetes": {
"k8s_api_root": "https://172.21.0.1:443",
"kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
},
"log_file_max_age": 30,
"log_file_max_count": 10,
"log_file_max_size": 100,
"log_file_path": "/var/log/calico/cni/cni.log",
"log_level": "Info",
"mtu": 0,
"nodename_file_optional": false,
"policy": {
"type": "k8s"
},
"policy_setup_timeout_seconds": 0,
"type": "calico"
},
{
"capabilities": {
"bandwidth": true
},
"type": "bandwidth"
},
{
"capabilities": {
"portMappings": true
},
"snat": true,
"type": "portmap"
}
]
}
cni执行文件
在对应目录可以看到cni插件配置文件中使用的bin文件
# ls /opt/cni/bin/
bandwidth calico calico-ipam portmap tuning
sandbox的配置
通过pod中sandbox的容器id找到sandbox 容器的配置文件
run/containerd/io.containerd.runtime.v2.task/k8s.io/[容器ID]/config.json
在其中可见该sandbox的网络空间
{"type":"network","path":"/var/run/netns/cni-4ac0638e-de4d-9d47-3089-0acef8c9d42c"}]
pod的网络
pod的网络即pod下容器使用的网络,进入查询到的sandbox所属网络空间
查询网卡
容器中eth0是 if111 的 veth pair
3e24a842738d0# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
3: eth0@if111: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether 4e:38:34:db:7b:7c brd ff:ff:ff:ff:ff:ff link-netnsid 0
查询路由
容器中路由都使用eth0作为出口,但目的地址 为 169.254.1.1,但地址并不重要,因为对网络设置了proxy,最终都将拦截至所在主机。
ee3d527278a5edb53e24a842738d0# ip r
default via 169.254.1.1 dev eth0
169.254.1.1 dev eth0 scope link
容器网卡的都对端网卡
根据if111索引, 在节点查询网卡, 可找到容器网卡的对端网卡如下
111: cali670e662a9a9@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netns cni-4ac0638e-de4d-9d47-3089-0acef8c9d42c
该网卡的路由
172.20.147.27 dev cali670e662a9a9 scope link
该地址刚好对应pod的地址
1/1 Running 0 28d 172.20.147.27
即节点上的其他pod访问172.20.147.27,将通过calixxxx 最终路由到目标pod的网卡.
节点间的网络
查询节点路由可以看到, 还有 172.20.241.0/26 段的路由。而目的地址刚好对应该网段pod的所在节点。当本节点的pod访问10.246.0.102 节点上的pod时将通过该tunl0 隧道转发。
172.20.241.0/26 via 10.246.0.102 dev tunl0 proto bird onlink
地址的分配
calico 的地址分配使用calico-ipam进行,但该工具管理的地址数据存放在etcd中,可以使用calicoctl进行查看。
每个Block对应一个节点的可分配地址。
./calicoctl-linux-amd64 ipam show --show-blocks
+----------+-----------------+-----------+------------+--------------+
| GROUPING | CIDR | IPS TOTAL | IPS IN USE | IPS FREE |
+----------+-----------------+-----------+------------+--------------+
| IP Pool | 172.20.0.0/16 | 65536 | 61 (0%) | 65475 (100%) |
| Block | 172.20.147.0/26 | 64 | 24 (38%) | 40 (62%) |
| Block | 172.20.241.0/26 | 64 | 37 (58%) | 27 (42%) |
+----------+-----------------+-----------+------------+--------------+
更多推荐



所有评论(0)