工作原理

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%)     |
+----------+-----------------+-----------+------------+--------------+

 

 

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐