Flannel配置详解

  1. 简介
    Flannel是一种基于overlay网络的跨主机容器网络解决方案,也就是将TCP数据包封装在另一种网络包里面进行路由转发和通信,Flannel是CoreOS开发,专门用于docker多机互联的一个工具,让集群中的不同节点主机创建的容器都具有全集群唯一的虚拟ip地址Flannel使用go语言编写

  2. Flannel实现原理
    Flannel为每个host分配一个subnet,容器从这个subnet中分配IP,这些IP可以在host间路由,容器间无需使用nat和端口映射即可实现跨主机通信

    每个subnet都是从一个更大的IP池中划分的,flannel会在每个主机上运行一个叫 flanneld的agent,其职责就是从池子中分配subnetFlannel使用etcd存放网络配置、已分配 的subnet、host的IP等信息 Flannel数据包在主机间转发是由backend实现的,目前已经支持UDP、VxLAN、host-gw、AWS VPC和GCE路由等多种backend
    数据转发流程
    ubuntu18.04安装flannel
    容器直接使用目标容器的ip访问,默认通过容器内部的eth0发送出去。

    报文通过veth pair被发送到vethXXX。

    vethXXX是直接连接到虚拟交换机docker0的,报文通过虚拟bridge docker0发送出去。

    查找路由表,外部容器ip的报文都会转发到flannel0虚拟网卡,这是一个P2P的虚拟网卡,然后报文就被转发到监听在另一端的flanneld。

    flanneld通过etcd维护了各个节点之间的路由表,把原来的报文UDP封装一层,通过配置的iface发送出去。

    报文通过主机之间的网络找到目标主机。

    报文继续往上,到传输层,交给监听在8285端口的flanneld程序处理。

    数据被解包,然后发送给flannel0虚拟网卡。

    查找路由表,发现对应容器的报文要交给docker0。

    docker0找到连到自己的容器,把报文发送过去。

  3. Flannel安装配置
    环境准备
    docker1 :10.10.10.141 docker flannel etcd
    docker2 :10.10.1.0142 docker flannel etcd
    3.1安装etcd
    etcd下载地址:https://github.com/coreos/etcd/releases

    启动命令:

    etcd -name etcd1 -data-dir /var/lib/etcd --advertise-client-urls 				http://10.10.10.141:2379,http://127.0.0.1:2379 --listen-client-urls http://10.10.10.141:2379,http://127.0.0.1:2379 &
    

    3.2安装Flannel
    flannel下载地址:https://github.com/coreos/flannel/releases

    添加flannel网络配置信息到etcd:

    etcdctl --endpoints http://127.0.0.1:2379 set /coreos.com/network/config ‘{“Network”: “10.0.0.0/16”, “SubnetLen”: 24, “SubnetMin”: “10.0.1.0”,“SubnetMax”: “10.0.20.0”, “Backend”: {“Type”: “vxlan”}}’

    Network:用于指定Flannel地址池
    SubnetLen:用于指定分配给单个宿主机的docker0的ip段的子网掩码的长度
    SubnetMin:用于指定最小能够分配的ip段
    SudbnetMax:用于指定最大能够分配的ip段,在上面的示例中,表示每个宿主机可以分配一个24位掩码长度的子网,可以分配的子网从10.0.1.0/24到10.0.20.0/24,也就意味着在这个网段中,最多只能有20台宿主机
    Backend:用于指定数据包以什么方式转发,默认为udp模式,host-gw模式性能最好,但不能跨宿主机网络
    3.3启动Flannel
    # cat /etc/systemd/system/flanneld.service

    [Unit]
    Description=Flanneld
    Documentation=https://github.com/coreos/flannel
    After=network.target
    Before=docker.service

    [Service]
    User=root
    ExecStartPost=/usr/local/bin/mk-docker-opts.sh
    ExecStart=/usr/local/bin/flanneld
    –etcd-endpoints=“http://10.10.10.141:2379
    –iface=10.10.10.141
    –ip-masq=true
    –etcd-prefix=/coreos.com/network
    Restart=on-failure
    Type=notify
    LimitNOFILE=65536

    [Install]
    WantedBy=multi-user.target

    # systemctl daemon-reload
    # systemctl start flanneld
    

3.4验证Flannel网络
查看etcd中的数据:

# etcdctl ls /coreos.com/network/subnets
/coreos.com/network/subnets/10.0.18.0-24

查看docker1的flannel网卡信息:

38: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default 
link/ether 1a:8e:8b:09:d6:d4 brd ff:ff:ff:ff:ff:ff
inet 10.0.18.0/32 scope global flannel.1
   valid_lft forever preferred_lft forever
inet6 fe80::188e:8bff:fe09:d6d4/64 scope link 
   valid_lft forever preferred_lft forever

可以看到flannel0网卡的地址和etcd存储的地址一样,这样flannel网络配置完成
3.5配置Docker
Docker安装完成以后,需要修改其启动参数以使其能够使用flannel进行IP分配,以及网络通讯

在Flannel运行之后,会生成一个环境变量文件,包含了当前主机要使用flannel通讯的相关参数,如下:

# cat /run/flannel/subnet.env 

	FLANNEL_NETWORK=10.0.0.0/16
	FLANNEL_SUBNET=10.0.18.1/24
	FLANNEL_MTU=1450
	FLANNEL_IPMASQ=true

可以使用flannel提供的脚本将subnet.env转写成Docker启动参数,创建好的启动参数默认生成在/run/docker_opts.env文件中:

# /opt/flannel/mk-docker-opts.sh -c

# cat /run/docker_opts.env
DOCKER_OPTS=" --bip=10.0.18.1/24 --ip-masq=false --mtu=1450"

修改docker的服务启动文件如下:

# vim /lib/systemd/system/docker.service

EnvironmentFile=/run/docker_opts.env
ExecStart=/usr/bin/dockerd $DOCKER_OPTS -H fd://

重启docker:

systemctl daemon-reload
systemctl restart docker

这时可以看到docker0的ip已经位于flannel网卡的网段之中:
3.6验证容器互通

相关文章: