flannel是由CoreOS研究的一种覆盖网络(overlay network)网络工具,目的是帮助每一个host主机有一个完整的子网;
功能是:让集群中不同节点的主机创建的容器都有一个唯一的虚拟IP
工作原理:将TCP数据包装在另一种网络包里进行路由转发和通信,目前已经支持UDP,Vxlan,AWS,APC和GRE等路由转发的模式。默认节点间通过UDP进行转发
1.安装配置etcd
etcd功能:与consul的功能差不多,维护主机间的路由表,flannel的配置信息全部存放在etcd里面,主要负责给各个主机分配subnet
可以根据官网的方式来搭建:https://github.com/coreos/etcd/releases
1.也可以直接yum install -y etcd
2.更改配置文件:vim /etc/etcd/etcd.conf
ETCD_LISTEN_CLIENT_URLS="http://192.168.7.222:2379" (第九行):监听客户端的请求
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.7.222:2379" (20行):通知客户端的地址
3.保存退出后,设置host主机的subnet
先编辑一个文件:etcd.sh
vim /root/etcd.sh
{“Network”:“10.2.0.0/16”,“SubnetLen”:24,"Backend":{"Type":"vxlan"}}
Network:定义host主机的IP地址池为10.2.0.0/16,注:由于etcd并不是动态保存host上flannel网络的,比如:当有节点被删除后,etcd中的关于这个节点的subnet网络并不会被删除,所以使用10.X.X.X的网络,保证有足够的网络可用
SubnetLen:指定每个主机分配的subnet大小为24位,即10.2.x.0/24
Backend为vxlan,即主机之间通过vxlan通信,我们主要讨论vxlan和host-gw这两种方式
4.将配置保存到etcd
etcdctl --endpoints=http://192.168.7.222:2379 set /usr/local/bin/network/config < /root/etcd.sh
--endpoints=http://192.168.7.222:2379 指定etcd的url
通过 etcdctl get /usr/local/bin/network/config 在etcd本机上获取key
/usr/local/bin/network/config 保存key的地方,flanneld会读取这个配置,保证自己能获取到subnet,这个key可以任意指定,当host主机分配到subnet后,key会修改docker的启动参数
2.安装配置flanneld
1.yum install -y flannel.x86_64
2.修改配置文件:vim /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://192.168.7.222:2379" 连接etcd的地址
LANNEL_ETCD_PREFIX="/usr/local/bin/network" key的地址,注:这个地址一定要写到最后一个目录即可,否则会报错,如下:
3.启动flanneld
可以使用命令 flanneld 也可以systemctl start flanneld
如果启动flanneld时出现一下错误:etcd集群配置错误,拒绝链接
解决办法是:在etcd的服务器上的/etc/etcd/etcd.conf中将集群:ETCD_LISTEN_PEER_URLS="http://localhost:2380"这个注释去掉
4.现在我们可以在host上看见一个flanneld1.1的网络了
可以看到我的doker1和dokcer2各有一个flannel1.1,但不在同一个网段,怎么进行通信呢?
我们来看一下两个host的路由情况:出现了一个flannel1.1的路由
路由都是10.2.0.0的,下面验证一下容器是否可以通信
两个容器使用的是同一个IP,肯定是没法访问对方
下面我们学习配置docker连接flannel
1.编辑docker的配置文件:/etc/systemd/system/docker.service.d/10-machine.conf
添加:--bip= --mtu=
这两个参数要参考/run/flannel/subnet.env,必须与其保持一致
2.重启docker服务
3.查看docker0的变化
docker会将flanneld配置到docker0上,并给docker0添加10.2.48.0的路由
docker1进行同样的配置:
docker1上的flannel也被桥接到docker0上了
验证容器的连通性:
到这里 ,还是ping不通!!!!!
为什么?????
开启了路由转发:echo 1 > /proc/sys/net/ipv4/ip_forward 还是不行
主机防火墙:firewalld和selinux已经关闭!!!!
但是,linux还有底层的iptables,所以在两台主机上分别执行:iptables -P FORWARD ACCEPT后
可以ping通,证明就算两个容器在不通的网段,使用flannel机制,可以使不同subnet的网络互通
通过traceroute来看一下容器走的路径
数据包先到docker0的网关10.2.55.1
根据路由表docker0将数据包转发给flannel1.1
flannel1.1会将数据包封装成Vxlan,通过ens160转发给docker2
docker2收到数据包后进行解包,发现IP 目的IP 是10.2.48.2,根据docker2的路由表将数据包转发给flannel1.1,flannel1.1再将数据包转发给docker2的docker0,到达容器
注:flannel没有DNS服务,容器无法通过hostname通信
flannel网络隔离
flannel为每个主机分配了独立的subnet,但是flannel1.1将这些subnet链接额起来,相互之间可以路由。本质上,flannel将个主机上相互独立的docker0容器网络组成了一个互通的大网络,实现了容器跨主机通信。flannel没有实现隔离
flannel与外网连通性:
因为flannel网络是将flannel1.1桥接到docker0上,所以容器与外部通信的方式与docker0默认的bridge网络一样,即:
1.容器通过NAT连接外网
2.外网通过端口映射的方式访问容器
flannel----host-gw
flannel支持多种backend,什么是backend:指的是host主机之间的通信方式
之前我们在写etcd key的时候定义过backend
之前的试验使用过的是vxlan,flannel支持多种的backend:目前已经支持UDP、VxLAN、AWS VPC和GCE路由等数据转发方式,默认使用的是udp的方式
下面我们讨论host-gw
与vxlan不同,host-gw不会封装数据包,而是在主机的路由表中创建到其他主机的subnet的路由条目,从而实现容器跨主机通信
要使用host-gw首先修改etcd key
重启docker1和docker2上的flanneld服务
可以看到flannel从etcd数据库中检索到docker1的subnet10.2.55.0/24,但是因为其是vxlan,所以立即忽略
我重启了docker1上的flannel后,docker2上的flannel发现subnet10.2.55.0/24将其添加到路由表中
查看docker2的路由表添加了一条到10.2.55.0/24的路由,网关是192.168.7.235
同样的docker1重启flannel后也会发生相应的变化
由于我们更改了flannel的配置,所以docker服务也会受到影响,因为之前我们说过flannel会改变docker的开机自启动,所以我们要根据/run/flanneld/subnet.env
更改 /etc/systemd/system/docker.service.d/10-machine.conf docker 的配置文件
重启docker服务
在docker1上做同样的操作
vxlan和 host-gw的区别;
1.host-gw把每个主机都配置成网关,主机知道其他主机的subnet和转发地址。
vxlan则是在主机之间创建隧道,不同的主机的容器都在一个大的网段内,比如:10.2.0.0/16
2.虽然vxlan与host-gw使用不同的机制,但对于容器之间还是可以相互通信的
3.由于vxlan需要对数据进行打包和拆包,性能可能稍逊于host-gw