Flannel

Flannel通过给每台宿主机分配一个子网的方式为容器提供虚拟网络,它基于Linux TUN/TAP,使用UDP封装IP包来创建overlay网络,并借助etcd维护网络的分配情况。

Flannel原理

控制平面上host本地的flanneld负责从远端的ETCD集群同步本地和其它host上的subnet信息,并为POD分配IP地址。数据平面flannel通过Backend(比如UDP封装)来实现L3 Overlay,既可以选择一般的TUN设备又可以选择VxLAN设备。

  1. {
  2. "Network": "10.0.0.0/8",
  3. "SubnetLen": 20,
  4. "SubnetMin": "10.10.0.0",
  5. "SubnetMax": "10.99.0.0",
  6. "Backend": {
  7. "Type": "udp",
  8. "Port": 7890
  9. }
  10. }

Flannel - 图1

除了UDP,Flannel还支持很多其他的Backend:

  • udp:使用用户态udp封装,默认使用8285端口。由于是在用户态封装和解包,性能上有较大的损失
  • vxlan:vxlan封装,需要配置VNI,Port(默认8472)和GBP
  • host-gw:直接路由的方式,将容器网络的路由信息直接更新到主机的路由表中,仅适用于二层直接可达的网络
  • aws-vpc:使用 Amazon VPC route table 创建路由,适用于AWS上运行的容器
  • gce:使用Google Compute Engine Network创建路由,所有instance需要开启IP forwarding,适用于GCE上运行的容器
  • ali-vpc:使用阿里云VPC route table 创建路由,适用于阿里云上运行的容器

Docker集成

  1. source /run/flannel/subnet.env
  2. docker daemon --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU} &

CNI集成

CNI flannel插件会将flannel网络配置转换为bridge插件配置,并调用bridge插件给容器netns配置网络。比如下面的flannel配置

  1. {
  2. "name": "mynet",
  3. "type": "flannel",
  4. "delegate": {
  5. "bridge": "mynet0",
  6. "mtu": 1400
  7. }
  8. }

会被cni flannel插件转换为

  1. {
  2. "name": "mynet",
  3. "type": "bridge",
  4. "mtu": 1472,
  5. "ipMasq": false,
  6. "isGateway": true,
  7. "ipam": {
  8. "type": "host-local",
  9. "subnet": "10.1.17.0/24"
  10. }
  11. }

Kubernetes集成

使用flannel前需要配置kube-controller-manager --allocate-node-cidrs=true --cluster-cidr=10.244.0.0/16

  1. kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

这会启动flanneld容器,并配置CNI网络插件:

  1. $ ps -ef | grep flannel | grep -v grep
  2. root 3625 3610 0 13:57 ? 00:00:00 /opt/bin/flanneld --ip-masq --kube-subnet-mgr
  3. root 9640 9619 0 13:51 ? 00:00:00 /bin/sh -c set -e -x; cp -f /etc/kube-flannel/cni-conf.json /etc/cni/net.d/10-flannel.conf; while true; do sleep 3600; done
  4. $ cat /etc/cni/net.d/10-flannel.conf
  5. {
  6. "name": "cbr0",
  7. "type": "flannel",
  8. "delegate": {
  9. "isDefaultGateway": true
  10. }
  11. }

Flannel - 图2

flanneld自动连接kubernetes API,根据node.Spec.PodCIDR配置本地的flannel网络子网,并为容器创建vxlan和相关的子网路由。

  1. $ cat /run/flannel/subnet.env
  2. FLANNEL_NETWORK=10.244.0.0/16
  3. FLANNEL_SUBNET=10.244.0.1/24
  4. FLANNEL_MTU=1410
  5. FLANNEL_IPMASQ=true
  6. $ ip -d link show flannel.1
  7. 12: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1410 qdisc noqueue state UNKNOWN mode DEFAULT group default
  8. link/ether 8e:5a:0d:07:0f:0d brd ff:ff:ff:ff:ff:ff promiscuity 0
  9. vxlan id 1 local 10.146.0.2 dev ens4 srcport 0 0 dstport 8472 nolearning ageing 300 udpcsum addrgenmode eui64

Flannel - 图3

优点

  • 配置安装简单,使用方便
  • 与云平台集成较好,VPC的方式没有额外的性能损失

缺点

  • VXLAN模式对zero-downtime restarts支持不好

When running with a backend other than udp, the kernel is providing the data path with flanneld acting as the control plane. As such, flanneld can be restarted (even to do an upgrade) without disturbing existing flows. However in the case of vxlan backend, this needs to be done within a few seconds as ARP entries can start to timeout requiring the flannel daemon to refresh them. Also, to avoid interruptions during restart, the configuration must not be changed (e.g. VNI, —iface values).

参考文档