Shan

Docker跨主机网络[2]-Flannel
一、环境说明 虚拟环境:VMware Workstation 14 Pro 系统环境:CentOS7.5 主机地...
扫描右侧二维码阅读全文
05
2018/11

Docker跨主机网络[2]-Flannel

一、环境说明


虚拟环境:VMware Workstation 14 Pro
系统环境:CentOS7.5
主机地址:etcd 192.168.5.128
host1 192.168.5.129
host2 192.168.5.130

二、Flannel概述


flannel是CoreOS开发的多主机容器通信解决方案。它使用Kubernetes API或etcd数据库来存储集群网络信息,主要是存储一个大的IP地址池、已分配的子网(subnet)、主机的IP等信息,flannel在每个主机上运行一个flanneld的agent用来分配子网(subnet),这个子网就是从IP地址池中划分出来的。
数据包在主机之间的转发是由backend实现的。并且flannel提供了多种backend,最常用的是vxlan和host-gw。
那么,数据包是怎么进行传递的呢?下面是Flannel的数据包传输流程图
docker_flannel原理.png

我们来解释一下:

  1. 数据包从源容器发出之后,由docker0网卡转发给flannel0(一个虚拟网卡)
  2. flanneld对数据包进行UDP封装,通过匹配etcd中存储的路由表来发送到目标容器所在主机
  3. 目标容器所在主机接收到数据包后,flanneld对其进行解包进入flannel0网卡
  4. 目标容器所在主机的flannel0网卡将其转发给dokcer0,通过路由到达目标容器

三、环境配置(vxlan)

3.1、安装etcd


在etcd主机上:

下载并解压etcd
# wget https://github.com/etcd-io/etcd/releases/download/v3.3.12/etcd-v3.3.12-linux-amd64.tar.gz
# tar zxvf etcd-v3.3.12-linux-amd64.tar.gz
主要文件有:Documentation(文档目录)  etcd(服务端二进制文件)  etcdctl(客户端二进制文件)

复制二进制文件到系统PATH路径下
# cp etcd-v3.3.12-linux-amd64/etcd* /usr/bin

启动etcd
# nohup etcd --listen-client-urls http://192.168.5.128:2379 \
  --advertise-client-urls http://192.168.5.128:2379 &

3.2、安装flannel


在host1和host2主机上:

下载flanneld安装包
# wget https://github.com/coreos/flannel/releases/download/v0.11.0/flannel-v0.11.0-linux-amd64.tar.gz
# tar xf flannel-v0.11.0-linux-amd64.tar.gz
主要文件有:flanneld(主程序执行文件) mk-docker-opts.sh(用于生成docker启动参数的脚本)

复制二进制文件到系统PATH路径下
# cp flanneld /usr/bin/

3.3、配置etcd


在etcd主机上:
由于flannel需要依赖etcd来保证集群的IP地址分配,所以需要先在etcd中添加flannel分配的网络地址段。

# etcdctl --endpoints=http://192.168.5.128:2379 set /flannel-test/network/config \
  '{ "Network": "10.1.0.0/16", "SubnetLen": 24, "Backend": { "Type": "vxlan" } }'
(1)Network定义flannel网络的IP池为10.1.0.0/16
(2)SubnetLen指分配到每台容器宿主机的subnet大小为24位,即10.1.X.0/24
(3)Backend类型为vxlan,稍后会继续测试host-gw

3.4、启动flannel


在host1和host2上:

# nohup flanneld --etcd-endpoints=http://192.168.5.128:2379 \
  --iface=ens33 \
  --etcd-prefix=/flannel-test/network &
(1)--etcd-endpoints指定etcd的url
(2)--iface绑定指定的网卡,进行数据传输
(3)--etcd-prefix指定etcd存放flannel网络信息的key


之后host1和host2主机上会多出一块flannel.1网卡,如下图所示(仅展示host1):

flannel-1.png

flannel运行后会生成一个环境变量文件,包含了当前主机要使用flannel通讯的相关参数。存放路径为:/run/flannel/subnet.env。
查看flannel分配的网络参数:

# cat /run/flannel/subnet.env 
FLANNEL_NETWORK=10.1.0.0/16
FLANNEL_SUBNET=10.1.7.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=false

3.5、配置Docker连接flannel


在host1和host2上,使用mk-docker-opts.sh脚本将flannel生成的网络参数转换成docker的启动参数:

# ./mk-docker-opts.sh -d docker_opts.env -c
# cat docker_opts.env 
DOCKER_OPTS=" --bip=10.1.7.1/24 --ip-masq=true --mtu=1450"


修改docker的启动参数:

# vim /etc/systemd/system/docker.service.d/10-machine.conf
在ExecStart处添加DOCKER_OPTS变量的值
比如host1要添加: --bip=10.1.7.1/24 --ip-masq=true --mtu=1450


修改完成后如下图所示:

flannel-2.png
重载并重启Docker Daemon:

# systemctl daemon-reload;systemctl restart docker


Docker会将flannel分配到主机的网段配置到docker0上,如下图:

flannel-3.png
flannel--4.png

由上面的路由信息,我们可以看出,flannel并没有创建新的网络,而是直接使用Docker默认的bridge网络。同宿主机上的容器通过docker0通信,不同宿主机上的容器通过flannel.1进行转发实现通信。

四、验证


在host1上创建test_host1容器,在host2上创建test_host2容器:

host1:
创建容器
# docker run -d --name test_host1 busybox sh -c "while true;do sleep 3600;done"
查看网络信息
# docker exec test_host1 ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:0A:01:07:02  
          inet addr:10.1.7.2  Bcast:10.1.7.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
          RX packets:16 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1312 (1.2 KiB)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

host2:
创建容器
# docker run -d --name test_host2 busybox sh -c "while true;do sleep 3600;done"
查看网络信息
# docker exec test_host2 ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:0A:01:07:02  
          inet addr:10.1.61.2  Bcast:10.1.7.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
          RX packets:16 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1312 (1.2 KiB)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)


进行测试(在host2上):

# docker exec test_host2 sh -c 'ping -c 3 10.1.7.2'
PING 10.1.7.2 (10.1.7.2): 56 data bytes
64 bytes from 10.1.7.2: seq=0 ttl=62 time=3.799 ms
64 bytes from 10.1.7.2: seq=1 ttl=62 time=1.422 ms
64 bytes from 10.1.7.2: seq=2 ttl=62 time=0.745 ms

--- 10.1.7.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.745/1.988/3.799 ms

五、环境配置(host-gw)


将vxlan backend切换为host-gw非常简单,只需要将 3.3、配置etcd 中的"Type": "vxlan"改为"Type": "host-gw"然后按照步骤重启flanneld即可

# etcdctl --endpoints=http://192.168.5.128:2379 set /flannel-test/network/config \
  '{ "Network": "10.1.0.0/16", "SubnetLen": 24, "Backend": { "Type": "host-gw" } }'


切换为host-gw模式后的路由信息:

flannel-5.png
flannel-6.png

六、小结

  1. host-gw把每台宿主机都设置成网关,每台宿主机都能与其他宿主机直接通信。vxlan是在宿主机之间建立隧道,不同的宿主机都在同一个大的网段内(本文中host1为10.1.7.0/24,host2为10.1.61.0/24,它们都在设置的10.1.0.0/16这个大网段内)
  2. host-gw和vxlan都不会创建新的网络,而是使用docker默认的bridge网络
  3. vxlan需要对数据进行UDP封装和解封装,所以传输效率会略逊于host-gw
Last modification:February 13th, 2019 at 02:16 pm

Leave a Comment