CNCF CNI系列之二:CNI(container network interface)概览(以macvlan为例)

一、前言

CNCF的CNI是一个接口规范,这个规范定义了输入、输出的标准和调用的接口。只要调用CNI插件的实体遵守这个规范,就能从CNI拿到满足网络互通条件的网络参数(如IP地址、网关、路由、DNS等),这些网络参数可以配置container实例。

本文通过分析手动调用macvlan CNI的过程,了解CNI接口规范的运行模式。

转载自https://blog.csdn.net/cloudvtech

二、container宿主机配置

所在网段:192.168.122.0/24

网卡配置:

 eth0:  mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 52:54:00:d8:d2:1e brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.135/24 brd 192.168.122.255 scope global dynamic eth0
       valid_lft 2355sec preferred_lft 2355sec
    inet6 fe80::5054:ff:fed8:d21e/64 scope link
       valid_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"):
  • CRT(container 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的STDIN(JSON文件)或者环境变量被传输给CNI plugin。

转载自https://blog.csdn.net/cloudvtech

四、手动配置和调用macvlan CNI plugin

1. 启动一个container

docker run --net=none -dt centos
ffecae44150e #container ID

docker 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  mtu 1500
        inet 192.168.122.3  netmask 255.255.255.0  broadcast 0.0.0.0
        inet6 fe80::858:c0ff:fea8:7a03  prefixlen 64  scopeid 0x20
        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 0
        TX packets 5155  bytes 356496 (348.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10
        loop  txqueuelen 1  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX 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) 56(84) 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

你可能感兴趣的:(container,容器,容器网络,kubernetes,CNI)