主要内容
简介
flannel是第三方跨主机容器网络,是CoreOS团队专门为Kubernetes开发的,但Docker也可以轻松地使用flannel网络。
flannel在每个主机上运行一个flanneld客户端程序,负责子网IP的分配,另外一些资料例如子网信息,已分配的IP地址池等则依赖etcd
来保存。flannel本身不负责主机间的流量转发,这些工作都是通过后端处理,flannel支持多种后端,常用的有VXLAN和host-gw,官方建议使用VXLAN。
环境准备
- 两台Docker Host,IP地址为192.168.0.202和192.168.0.212,需要安装flannel
- 一台主机(nas-share)用于安装etcd数据库 ,IP地址为192.168.0.222
安装etcd
etcd目前托管在github上面,最新的二进制安装包版本为3.3.9.
下载并解压软件包
1 2 3 4 5 |
root@nas-share:~# wget https://github.com/etcd-io/etcd/releases/download/v3.3.9/etcd-v3.3.9-linux-amd64.tar.gz root@nas-share:~# tar -zxvf etcd-v3.3.9-linux-amd64.tar.gz lroot@nas-share:~# ls etcd-v3.3.9-linux-amd64 Documentation etcd etcdctl README-etcdctl.md README.md READMEv2-etcdctl.md |
解压后我们只需要etcd和etcdclt两个可执行文件,可以把它们复制到/usr/bin/目录下,方便执行
1 2 |
root@nas-share:~/etcd-v3.3.9-linux-amd64# cp etcd* /usr/bin/ |
测试etcd
先启动etcd服务
1 2 |
etcd --listen-client-urls=http://0.0.0.0:2379 --advertise-client-urls=http://0.0.0.0:2379 |
etcd默认监听127.0.0.1,无法对外提供服务,因此要显式设置监听的网卡。
- –listen-client-urls 指定接收客户端数据的网卡
- –advertise-client-urls 指定由哪个网卡通告集群中的成员列表
etcd默认启动为前台进程,因此会占用一个终端,启动成功后另开一个终端测试,使用etcdctl命令向etcd添加一个键值对。
1 2 3 4 5 |
[root@centos7-server ~]# etcdctl set foo bar # 添加一个键foo bar [root@centos7-server ~]# etcdctl get foo # 获取foo的值 bar |
如果没有错误,说明etcd成功运行。由于etcdctl和etcd运行在同一台服务器上,因此不需要设置endpoints参数,否则需要明确指出:
1 2 3 4 5 |
[root@centos7-server ~]# etcdctl --endpoints=http://192.168.0.222:2379 set foo bar # 添加一个键foo bar [root@centos7-server ~]# etcdctl --endpoints=http://192.168.0.222:2379 get foo # 获取foo的值 bar |
安装flannel
flannel同样托管在github,现在已经提供二进制安装包,一般不用自己编译。
1 2 3 4 |
wget https://github.com/coreos/flannel/releases/download/v0.10.0/flannel-v0.10.0-linux-amd64.tar.gz tar -zxvf flannel-v0.10.0-linux-amd64.tar.gz mv flanneld /usr/bin |
配置flannel
flannel默认会读取etcd数据库上key为/coreos.com/network/config
的值,也可以通过--etcd-prefix
指定key。该key保存的是一个json配置,支持的选项有:
Network
(string):CIDR形式的网络地址。必须设置SubnetLen
(integer):子网尺寸,默认为24。可选项SubnetMin
(string):开始分配的最小子网。可选项SubnetMax
(string):可分配的最大子网。可选项Backend
(dictionary):指定数据转发的后端。
配置文件示例:
1 2 3 4 5 6 7 8 9 10 11 |
{ "Network": "10.0.0.0/8", "SubnetLen": 20, "SubnetMin": "10.10.0.0", "SubnetMax": "10.99.0.0", "Backend": { "Type": "udp", "Port": 7890 } } |
保存数据到etcd
假设网络为10.10.0.0,使用VXLAN作为后端,我们先创建好配置文件
1 2 3 4 5 6 7 8 9 10 |
[root@nas-share ~]# touch config.json [root@nas-share ~]# vim config.json { "Network": "10.10.0.0/16", "SubnetLen": 24, "Backend": { "Type": "vxlan" } } |
然后使用etcdctl上传配置到etcd
1 2 3 4 5 6 7 8 9 |
root@nas-share:~# etcdctl --endpoints=http://192.168.0.222:2379 set /flannel/network/config < config.json { "Network": "10.10.0.0/16", "SubnetLen": 24, "Backend": { "Type": "vxlan" } } |
启动flanneld
配置准备完毕就可以启动flanneld,两台服务器都需要启动flanneld,默认启动为前台进程。
1 2 |
[root@centos7-server ~]# flanneld --etcd-endpoints=http://192.168.0.222:2379 --etcd-prefix=/flannel/network/ |
注意–etcd-prefix的值是/flannel/network/,而不是/flannel/network/config,如果设置了后者,启动的时候就会出现如下错误:
1 2 |
Couldn't fetch network config: 104: Not a directory (/flannel/network/config) |
一旦flanneld启动之后,它会确保主机有一个租赁网络,如果没有则分配一个,租赁网络可以通过下面命令查看:
1 2 3 |
root@nas-share:~# etcdctl ls /flannel/network/subnets /flannel/network/subnets/10.10.83.0-24 |
详细的信息可以如下查看:
1 2 3 4 5 6 7 8 9 |
root@nas-share:~# etcdctl -o extended get /flannel/network/subnets/10.10.83.0-24 Key: /flannel/network/subnets/10.10.83.0-24 Created-Index: 7 Modified-Index: 7 TTL: 86137 Index: 7 {"PublicIP":"192.168.0.202","BackendType":"vxlan","BackendData":{"VtepMAC":"06:27:65:ff:1d:26"}} |
另外,flannel还会把一些环境变量保存到/var/run/flannel/subnet.env
文件中,里面包括子网信息和支持它支持的MTU值
1 2 3 4 5 6 |
[root@centos7-server ~]# cat /var/run/flannel/subnet.env FLANNEL_NETWORK=10.10.0.0/16 FLANNEL_SUBNET=10.10.83.1/24 FLANNEL_MTU=1450 FLANNEL_IPMASQ=false |
最后,flannel会添加一个名为flannel.1
的虚拟设备
1 2 3 4 5 6 7 8 9 10 |
[root@centos7-server ~]# ifconfig flannel.1 flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.10.83.0 netmask 255.255.255.255 broadcast 0.0.0.0 inet6 fe80::427:65ff:feff:1d26 prefixlen 64 scopeid 0x20<link> ether 06:27:65:ff:1d:26 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 8 overruns 0 carrier 0 collisions 0 |
Docker中使用flannel
修改docker守护进程的启动参数
1 2 3 4 5 |
vim /usr/lib/systemd/system/docker.service [Service] .... ExecStart=/usr/bin/dockerd --bip=10.10.83.1/24 --mtu=1450 |
添加--bip
和--mtu
选项,它们的值对应/var/run/flannel/subnet.env中的FLANNEL_SUBNET和FLANNEL_MTU。
然后重启docker
1 2 3 |
systemctl daemon-reload systemctl restart docker |
实际上,现在新创建的容器默认就使用flannel提供的网络,因为我们已经指定了docker进程使用的子网。
创建容器
主机1
1 2 3 4 5 6 7 8 9 10 11 12 |
[root@centos7-server ~]# docker run --name busybox1 -itd busybox [root@centos7-server ~]# docker exec -it busybox1 /bin/sh / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:0A:0A:53:02 inet addr:10.10.83.2 Bcast:10.10.83.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:1296 (1.2 KiB) TX bytes:0 (0.0 B) ..... |
可见IP地址对应的就是flannel的网络。
主机2
1 2 3 4 5 6 7 8 9 10 11 12 |
[root@dellcentos7 ~]# docker run --name busybox2 -itd busybox [root@dellcentos7 ~]# docker exec -it busybox2 /bin/sh / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:0A:0A:29:02 inet addr:10.10.41.2 Bcast:10.10.41.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1 RX packets:8 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:648 (648.0 B) TX bytes:0 (0.0 B) .... |
测试网络通讯
进入主机1的busybox1,ping主机2的busybox2
1 2 3 4 5 6 7 8 9 10 |
[root@centos7-server ~]# docker exec -it busybox1 /bin/sh / # ping 10.10.41.2 -c 2 PING 10.10.41.2 (10.10.41.2): 56 data bytes 64 bytes from 10.10.41.2: seq=0 ttl=62 time=0.541 ms 64 bytes from 10.10.41.2: seq=1 ttl=62 time=0.421 ms --- 10.10.41.2 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.421/0.481/0.541 ms |
busybox1顺利和busybox2通讯,实际上,两个容器不属于同一个子网,它们是如何通讯的呢?答案是通过主机的路由。
我们先查看主机1的路由配置:
任何发往10.10.41.0的数据都由flannel.1设备处理,另外,本地docker的网络实际上绑定到docker0上,brctl命令可以证实:
1 2 3 4 |
[root@centos7-server ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242eb4eca24 no veth677efe0 |
veth677efe0
设备在busybox1运行之前是不存在的。
主机2上也存在相似的路由表:
最终的网络结构如下
转载请注明:Pure nonsense » Docker容器之flannel网络