一、前言
CNCF的CNI是一个接口规范,这个规范定义了输入、输出的标准和调用的接口。只要调用CNI插件的实体遵守这个规范,就能从CNI拿到满足网络互通条件的网络参数如IP地址、网关、路由、DNS等),这些网络参数可以配置container实例。
本文通过分析手动调用macvlan CNI的过程,了解CNI接口规范的运行模式。
转载自https://blog.csdn.net/cloudvtech
二、container宿主机配置
所在网段:192.168.122.0/24
网卡配置:
eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000link/ether 52:54:00:d8:d2:1e brd ff:ff:ff:ff:ff:ffinet 192.168.122.135/24 brd 192.168.122.255 scope global dynamic eth0valid_lft 2355sec preferred_lft 2355secinet6 fe80::5054:ff:fed8:d21e/64 scope linkvalid_lft forever preferred_lft forever
转载自https://blog.csdn.net/cloudvtech
三、CNI接口规范
1. CNI接口支持的调用法方
添加网络、删除网络、添加网络列表、删除网络列表。
CNI plugin的功能可以概括为将container加入网络并被container的网络接口配置网络信息。
2. CNI插件
CNI插件必须是一个可执行文件。CNI插件负责将网络接口比如veth的一端)插入container network namespace里面,并在主机上进行link level比如veth的另一端)配置,使得container的在link level能够联通到主机。然后,CNI将IP配置给网络接口并设置相关路由。
3. 设计考量
CNI设计的时候考虑了以下问题https://github.com/containernetworking/cni/blob/master/SPEC.md, "General considerations"):
- CRTcontainer run time)必须在调用CNI plugin之前为容器创建一个network namespace。
- CRI必须确定这个container应属于哪个网络,并为每个网络确定哪些插件必须被执行。
- 网络配置采用JSON格式。网络配置包括必填字段,如name和type以及插件(类型)。网络配置允许不同的CNI plugin有一部分自定义的参数,为此,有一个可选的字段args,可以包含特定CNI plugin所需的不同的信息。
- CRI必须按顺序为每个网络执行相应的CNI plugin,将container添加到每个网络中。
- 在完成container生命周期后,运行时必须以相反的顺序执行插件(相对于执行添加container的顺序)以将container与网络断开连接。
- CRI关注CNI plugin的ADD和DEL操作,并且DEL操作具有等幂性。
- container必须由ContainerID唯一标识。
- CRI不能调用同一个网络名称或containerID执行两次ADD(没有相应的DEL)。换句话说,给定的container ID必须只能添加到特定的网络一次。
4. ADD操作
参数
- Container ID
- Network namespace 路径,比如 /proc/[pid]/ns/net
- JSON格式CNI网络配置参数,告诉container需要加入什么样的网络
- 不同CNI plugin特定的参数
- container内部的网卡名字
返回值
- container内部网卡或宿主机上受影响的网卡如macvlan plugin)列表
- 给每个网卡分配的网络配置IP、网关、路由)
- DNS信息
5. DEL操作
与ADD操作类似
6. 环境变量参数
- CNI_COMMAND: CNI操作,ADD, DEL or VERSION.
- CNI_CONTAINERID: Container ID
- CNI_NETNS: 指向container network namespace文件的路径
- CNI_IFNAME: container内部网络接口的名字
- CNI_ARGS: key-value对的额外参数
- CNI_PATH: CNI plugin binary的路径
以上的配置必须在CNI plugin可执行文件被调用时作为CNI plugin的STDINJSON文件)或者环境变量被传输给CNI plugin。
转载自https://blog.csdn.net/cloudvtech
四、手动配置和调用macvlan CNI plugin
1. 启动一个container
docker run --net=none -dt centos
ffecae44150e #container IDdocker inspect -f '{{ .State.Pid }}' ffecae44150e
7077 #container进程号
2. 准备JSON格式CNI需要加入的网络的描述文件
/etc/cni/net.d/10-maclannet.conf
{"name": "macvlannet", #CNI实例名字"type": "macvlan", #CNI类型"master": "eth0", #CNI作用的网卡"ipam": { #IP管理的子plugin的设置"type": "host-local", #IP管理plugin的类型"subnet": "192.168.122.0/24", #IP管理plugin所需的子网参数"routes": [ #IP管理plugin所需的路由参数{ "dst": "0.0.0.0/0" }]}
}
3. CNI的环境变量参数
export CNI_COMMAND=ADD #CNI的命令,ADD或者DEL
export CNI_IFNAME=eth0 #container内网卡的名字
export CNI_CONTAINERID=ffecae44150e #container的ID
export CNI_PATH=/opt/cni/bin/ #CNI可执行文件的路径
export CNI_NETNS=/proc/7077/ns/net #CNI所需的container namespace的路径
4. 手动运行CNI plugin可执行文件
/opt/cni/bin/macvlan < /etc/cni/net.d/10-maclannet.conf
输出结果如下:
{"ip4": {"ip": "192.168.122.3/24","gateway": "192.168.122.1","routes": [{"dst": "0.0.0.0/0","gw": "192.168.122.1"}]},"dns": {}
}
包括分配的IP地址、网关、路由等信息
5. 在container内验证CNI的返回结果
docker exec -it ff bash
[root@ffecae44150e /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.122.3 netmask 255.255.255.0 broadcast 0.0.0.0inet6 fe80::858:c0ff:fea8:7a03 prefixlen 64 scopeid 0x20<link>ether 0a:58:c0:a8:7a:03 txqueuelen 0 Ethernet)RX packets 5589 bytes 15085040 14.3 MiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 5155 bytes 356496 348.1 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536inet 127.0.0.1 netmask 255.0.0.0inet6 ::1 prefixlen 128 scopeid 0x10<host>loop txqueuelen 1 Local Loopback)RX packets 0 bytes 0 0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
从宿主机ping container IP
[root@os-cni-test ~]# ping 192.168.122.3
PING 192.168.122.3 192.168.122.3) 5684) bytes of data.
64 bytes from 192.168.122.3: icmp_seq=1 ttl=64 time=0.312 ms
64 bytes from 192.168.122.3: icmp_seq=2 ttl=64 time=0.518 ms
64 bytes from 192.168.122.3: icmp_seq=3 ttl=64 time=0.449 ms
^C
--- 192.168.122.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.312/0.426/0.518/0.087 ms
转载自https://blog.csdn.net/cloudvtech