flannel简介

我们在部署 Kubernetes 的时候,有一个步骤是安装 kubernetes-cni 包,它的目的就是在宿主机上安装CNI 插件所需的基础可执行文件

在安装完成后,你可以在宿主机的 /opt/cni/bin 目录下看到它们,如下所示:

[root@k8s-master01 ~]# cd /opt/cni/bin/
[root@k8s-master01 bin]# ll
总用量 56484
-rwxr-xr-x 1 root root 3254624 9月  10 2020 bandwidth
-rwxr-xr-x 1 root root 3581192 9月  10 2020 bridge
-rwxr-xr-x 1 root root 9837552 9月  10 2020 dhcp
-rwxr-xr-x 1 root root 4699824 9月  10 2020 firewall
-rwxr-xr-x 1 root root 2650368 9月  10 2020 flannel
-rwxr-xr-x 1 root root 3274160 9月  10 2020 host-device
-rwxr-xr-x 1 root root 2847152 9月  10 2020 host-local
-rwxr-xr-x 1 root root 3377272 9月  10 2020 ipvlan
-rwxr-xr-x 1 root root 2715600 9月  10 2020 loopback
-rwxr-xr-x 1 root root 3440168 9月  10 2020 macvlan
-rwxr-xr-x 1 root root 3048528 9月  10 2020 portmap
-rwxr-xr-x 1 root root 3528800 9月  10 2020 ptp
-rwxr-xr-x 1 root root 2849328 9月  10 2020 sbr
-rwxr-xr-x 1 root root 2503512 9月  10 2020 static
-rwxr-xr-x 1 root root 2820128 9月  10 2020 tuning
-rwxr-xr-x 1 root root 3377120 9月  10 2020 vlan

按照功能可以分为三类:

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

我在前面提到过的 Flannel、Weave 等项目,都属于“网桥”类型的 CNI 插件。所以在具体的实现中,它们往往会调用 bridge 这个二进制文件。这个流程,我马上就会详细介绍到。

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

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

以 Flannel 项目为例:

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

这个 CNI 配置文件的内容如下所示:

# cat /etc/cni/net.d/10-flannel.conflist 
{
  "name": "cbr0",
  "plugins": [
    {
      "type": "flannel",
      "delegate": {
        "hairpinMode": true,
        "isDefaultGateway": true
      }
    },
    {
      "type": "portmap",
      "capabilities": {
        "portMappings": true
      }
    }
  ]
}

经过 Flannel CNI 插件补充后的、完整的 delegate 字段如下所示:

{
    "hairpinMode":true,
    "ipMasq":false,
    "ipam":{
        "routes":[
            {
                "dst":"10.244.0.0/16"
            }
        ],
        "subnet":"10.244.1.0/24",
        "type":"host-local"
    },
    "isDefaultGateway":true,
    "isGateway":true,
    "mtu":1410,
    "name":"cbr0",
    "type":"bridge"
}

其中,ipam 字段里的信息,比如 10.244.1.0/24,读取自 Flannel 在宿主机上生成的 Flannel 配置文件,即:宿主机上的 /run/flannel/subnet.env 文件。

# cat /run/flannel/subnet.env
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true

CNI 插件还会把 Delegate 字段以 JSON 文件的方式,保存在 /var/lib/cni/flannel 目录下。这是为了给后面删除容器调用 DEL 操作时使用的。

# cd /var/lib/cni/flannel
[root@k8s-master01 flannel]# ll
总用量 48
-rw------- 1 root root 227 6月  21 14:39 0b1428fdc7d4497176821cc4f4a513f4d4f8bed3108b4d54c5ff2a4332765b80
-rw------- 1 root root 227 3月   3 2022 2575f4f84e2de6379d543bb332635444ff38fd779a34ecf2a53c05ac0dd99a12
-rw------- 1 root root 227 3月  11 2022 264813c8af2a30b6b65d81f889535677c0cfc8abfa2dd918282108752d30666a
-rw------- 1 root root 227 6月  21 14:39 293b0f67469654539d332d50b5fa25b2ab8cc7051523554b4d52b4dabc5b6c86
-rw------- 1 root root 227 2月  25 2022 4b72c12d8dbc01e1943f233435b7d768ec772deb6f8ed2a0539821cf81a9fdb7
-rw------- 1 root root 227 6月  21 14:39 4cdf79ff3cccfe7e0bae3d148c1fc71a4b7c9912c8129fd8599bd5de2fc3728b
-rw------- 1 root root 227 2月  25 2022 5d0269ed15c1064c27adfbcfd1bd8364191d972f324491e2e5cb24fcbc9bd8b5
-rw------- 1 root root 227 3月   3 2022 8b1024dfd38f04ebf07ed1e37c3d6ffe78cbb71e4c860120ebb62ca4c742d02c
-rw------- 1 root root 227 3月  16 2022 bd369ff42f9b83312de31f4270bd6adf3cd9416a0dd21b8747b69681f044807e
-rw------- 1 root root 227 3月   3 2022 c09d2b4d2e88708aee890781251134977b143508068cac7802b55e7cdfd62b1e
-rw------- 1 root root 227 3月  11 2022 e78a0045ba7631f7fab87ce1a5eaf03e834561e87f05d4961d0bfb247e1410e9
-rw------- 1 root root 227 6月  21 14:39 ed2f3dbc765ba66388753b8f0aacd3eadecb05f36e35491c909e40634879edbf

其中,使用的ip记录在 /var/lib/cni/networks/cbr0

# cd /var/lib/cni/networks/cbr0
[root@k8s-master01 cbr0]# ll
总用量 20
-rw-r--r-- 1 root root 70 6月  21 14:39 10.244.0.95
-rw-r--r-- 1 root root 70 6月  21 14:39 10.244.0.96
-rw-r--r-- 1 root root 70 6月  21 14:39 10.244.0.97
-rw-r--r-- 1 root root 70 6月  21 14:39 10.244.0.98
-rw-r--r-- 1 root root 11 6月  21 14:39 last_reserved_ip.0
-rwxr-x--- 1 root root  0 10月 29 2020 lock
# cat 10.244.0.95 
293b0f67469654539d332d50b5fa25b2ab8cc7051523554b4d52b4dabc5b6c86

 

flannel的configmap配置文件

[root@master ~]# kubectl get configmap -n kube-system |grep flannel
NAME                                 DATA      AGE
kube-flannel-cfg                     2         22d

xvlan(默认)

[root@master flannel]# kubectl edit configmap kube-flannel-cfg -n kube-system
{
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }

host-gw

[root@master flannel]# kubectl edit configmap kube-flannel-cfg -n kube-system
{
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "host-gw"
      }
    }

[root@master flannel]# reboot (需要重启,否则flannel.1的网卡一直存在)

xvlan-Directrouting

[root@master flannel]# kubectl edit configmap kube-flannel-cfg -n kube-system
{
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan", ### 注意 ,逗号
        "Directrouting": true #### 加一行这个
      }
    }