• Understanding CNI (Container Networking Interface)


    Understanding CNI (Container Networking Interface)

     https://github.com/containernetworking/cni

     执行 kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml
    在宿主机的 /opt/cni/bin 目录下看到它们,如下所示:
    root@ubuntu:~# ls /opt/cni/bin 
    antrea  bandwidth  bridge  dhcp  firewall  flannel  host-device  host-local  ipvlan  loopback  macvlan  portmap  ptp  sbr  static  tuning  vlan  whereabouts
    root@ubuntu:~# 

    这些 CNI 的基础可执行文件,按照功能可以分为三类:

    1. 第一类,叫作 Main 插件,它是用来创建具体网络设备的二进制文件。比如,bridge(网桥设备)、ipvlan、loopback(lo 设备)、macvlan、ptp(Veth Pair 设备),以及 vlan。

      Flannel、Weave 等项目,都属于“网桥”类型的 CNI 插件。所以在具体的实现中,它们往往会调用 bridge 这个二进制文件

    2. 第二类,叫作 IPAM(IP Address Management)插件,它是负责分配 IP 地址的二进制文件。比如,dhcp,这个文件会向 DHCP 服务器发起请求;host-local,则会使用预先配置的 IP 地址段来进行分配。

    3. 第三类,是由 CNI 社区维护的内置 CNI 插件。比如:flannel,就是专门为 Flannel 项目提供的 CNI 插件;tuning,是一个通过 sysctl 调整网络设备参数的二进制文件;portmap,是一个通过 iptables 配置端口映射的二进制文件;bandwidth,是一个使用 Token Bucket Filter (TBF) 来进行限流的二进制文件。

    从这些二进制文件中,我们可以看到,如果要实现一个给 Kubernetes 用的容器网络方案,其实需要做两部分工作,以 Flannel 项目为例:

    首先,实现这个网络方案本身。这一部分需要编写的,其实就是 flanneld 进程里的主要逻辑。比如,创建和配置 flannel.1 设备、配置宿主机路由、配置 ARP 和 FDB 表里的信息等等。

    然后,实现该网络方案对应的 CNI 插件。这一部分主要需要做的,就是配置 Infra 容器里面的网络栈,并把它连接在 CNI 网桥上。

    调用实现

    在每台宿主机上生成对应的CNI配置文件/etc/cni/net.d/10-flannel.conflist,kubernetes集群会使用这个配置文件来作为容器网络配置方案

    root@ubuntu:~# ls /etc/cni/net.d/
    10-antrea.conflist  10-flannel.conflist
    root@ubuntu:~# 
    root@ubuntu:~# cat /etc/cni/net.d/10-flannel.conflist 
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }
    root@ubuntu:~# ip a sh cbr0
    Device "cbr0" does not exist.
    root@ubuntu:~# cat /etc/cni/net.d/10-antrea.conflist
    {
        "cniVersion":"0.3.0",
        "name": "antrea",
        "plugins": [
            {
                "type": "antrea",
                "ipam": {
                    "type": "host-local"
                }
            },
            {
                "type": "portmap",
                "capabilities": {"portMappings": true}
            },
            {
                "type": "bandwidth",
                "capabilities": {"bandwidth": true}
            }
        ]
    }

    CNI的调用方式是通过一个可执行文件进行的。这里以calico为例,说明CNI插件的调用方式。

    首先,calico进行插件注册

    mkdir -p /etc/cni/net.d
    cat >/etc/cni/net.d/10-calico.conf <<EOF { "name": "calico-k8s-network", "type": "calico", "etcd_authority": "<ETCD_IP>:<ETCD_PORT>", "log_level": "info", "ipam": { "type": "calico-ipam" }, "policy": { "type": "k8s" } } EOF

    k8s的DefaultCNIDir/opt/cni/bin。因为注册的typecalico,所以k8s会从/opt/cni/bin中搜索一个calico的可执行文件,然后进行执行。

    执行的时候传递参数有两种方式,一种是通过环境变量进行传递,比如上文中的Version、Container ID等;另外一种是通过执行calico作为执行的参数传进去,这个主要就是Network configuration的部分,通过json将其打包传入。

    同样判断是否执行成功,是通过执行文件的返回值获取的。0为成功,1为版本版本不匹配,2为存在不符合的字段。如果执行成功,返回值将通过stdout返回。

     CNI与dockershim

    CRI(Container Runtime Interface,容器运行时接口)实现容器网络相关的逻辑,对应docker项目为dockershim来实现

    dockershim处理过程
    1. dockershim在处理容器网络时,加载/etc/cni/net.d内的文件,并且把plugins字段中的第一个插件作为默认插件
    2. 后面的执行过程中,flannel和portmap会按照定义顺序被调用,从而依次完成“配置容器网络”和“配置端口映射”这两步操作
    CNI插件的工作原理
    1. kubelet创建pod时,首先通过dockershim会先调用docker api创建并启动Infra容器,然后执行SetUpPod方法,作用为:为CNI插件准备参数,然后调用CNI插件为Infra容器配置网络
      • 将容器添加到CNI网络中,即通过容器以Veth Pair方式插到CNI网桥上
      • /run/flannel/subnet.env为宿主机生成的flannel配置文件
      • /var/lib/cni/flannel 为flannel cni插件把delegate字段以json文件的方式保存下来
    2. CNI bridge插件调用CNI ipam插件,为容器分配可用ip地址,同时为容器设置默认路由
    3. CNI插件会把容器的ip地址等信息返回给dockershim,然后被kubelet添加到Pod的Status字段中

     Flannel CNI

    CNI——容器网络是如何打通的

  • 相关阅读:
    《Java基础知识》Java继承的概念和实现
    《Java基础知识》Java包装类,拆箱和装箱
    《Java基础知识》Java方法重载和重写
    《Java基础知识》Java this关键字详解
    《Java基础知识》Java变量作用域
    51nod 1080:两个数的平方和
    51nod 1013:3的幂的和 快速幂
    POJ 1019:Number Sequence 二分查找
    51nod 1393:0和1相等串
    51nod 1267:4个数和为0 哈希
  • 原文地址:https://www.cnblogs.com/dream397/p/14838714.html
Copyright © 2020-2023  润新知