Flannel 网络 安装配置(docker容器互通)

一 简介

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

二 Flannel实现原理

2.1 原理说明

  • Flannel为每一个host分配一个subnet,容器从这个subnet中分配IP,这些IP可以在host间路由,容器间无需使用nat和端口映射即可实现跨主机通信
  • 每个subnet都是从一个更大的IP地址池划分的,flannel会在每个主机上运行一个叫flanneld的agent,其职责介绍从池子中分配subnet
  • Flannle使用etcd存放网络配置,已分配的subnet,host的ip地址等信息
  • Flannel数据包在主机间转发是由backend实现的,目前已经支持UDP,VxLAN,host-gw,AWS VPC和GCE路由等多种backend

2.2 Flannel网络结构图

 多了一层封装,进行流量劫持

2.3 数据转发流程

  1. 容器直接使用目标容器的ip 访问,默认通过容器内部的eth0发送出去
  2. 报文通过veth pair 被发送到 veth XXX
  3. veth XXX 是周几连接到虚拟交换机dokcer0的,报文通过虚拟bridge dokcer0发送出去
  4. 查找路由表,外部容器ip的报文都会转发到flannel0虚拟网卡,这是一个P2P的虚拟网卡,然后报文就被转发到监听在另一端的flanneld
  5. flanneld通过etcd维护了各个节点之间的路由表,把原来的报文UDP封装一层,通过配置的iface发送出去。
  6. 报文通过主机之间的网络找到目标主机
  7. 报文继续往上,到传输层,交给监听在8285端口的flanneld程序处理
  8. 数据被解包,然后发送给flannel0虚拟忘记。
  9. 查找路由表,发现对应容器的报文要交给docker0
  10. dokcer0找到连到自己的容器,包报文发送过去

三 安装配置

3.1 环境准备

节点名称       IP地址安装软件
dokcer-server1192.168.132.131 etcd ,flannel ,docker
dokcer-server2    192.168.132.132  flannel,dokcer

删除节点的所有容器

[root@docker-server1 ~]# docker ps -aq|xargs docker rm 
[root@docker-server2 ~]# docker ps -aq|xargs docker rm 

3.2 安装tecd

eetcd下载地址:https://github.com/coreos/etcd/releass

下载

[root@docker-server1 ~]# wget https://github.com/coreos/etcd/releases/download/v3.3.10/etcd-v3.3.10-linux-amd64.tar.gz
[root@docker-server2 ~]# wget https://github.com/coreos/etcd/releases/download/v3.3.10/etcd-v3.3.10-linux-amd64.tar.gz

在131上安装etcd和Flannel

[root@docker-server1 ~]# tar -xf etcd-v3.3.10-linux-amd64.tar.gz
[root@docker-server1 ~]# cd etcd-v3.3.10-linux-amd64
[root@docker-server1 etcd-v3.3.10-linux-amd64]# ll
total 33992
drwxr-xr-x 11 joy joy     4096 Jul 24  2018 
Documentation-rwxr-xr-x  1 joy joy 18934016 Jul 24  2018 
etcd-rwxr-xr-x  1 joy joy 15809280 Jul 24  2018 
etcdctl-rw-r--r--  1 joy joy    38864 Jul 24  2018 
README-etcdctl.md-rw-r--r--  1 joy joy     7262 Jul 24  2018 
README.md-rw-r--r--  1 joy joy     7855 Jul 24  2018 
READMEv2-etcdctl.md
[root@docker-server1 etcd-v3.3.10-linux-amd64]# cp etcd*  /usr/bin/

启动命令:

[root@docker-server1 ~]# etcd --name etcd-131 -data-dir /var/lib/etcd --advertise-client-urls http://192.168.132.131:2379,http://127.0.0.1:2379 --listen-client-urls http://192.168.132.131:2379,http://127.0.0.1:2379 

--name:etc  #取名

--data-dir:定义数据路径

--advertise-client-urls:建议使用的用户客户端通信url,该值用于etcd代理和etcd成员与etcd节点通信,即服务的url

--listen-client-urls:监听的用于客户端通信的url,对外提供服务的地址,客户端会连接到这里和etcd交互,同样可以监听多个。

[root@docker-server1 ~]# ps -ef|grep etcd
root      85130  84636  2 14:12 pts/4    00:00:01 etcd -name etcd-131 -data-dir /var/lib/etcd --advertise-client-urls http://192.168.132.131:2379,http://127.0.0.1:2379 --listen-client-urls http://192.168.132.131:2379,http://127.0.0.1:2379

etcdctl是一个客户的连接工具

[root@docker-server1 ~]# etcdctl  member list
8e9e05c52164694d: name=etcd-131 peerURLs=http://localhost:2380 clientURLs=http://127.0.0.1:2379,http://192.168.132.131:2379 isLeader=true

使用etcdctl连接数据库,检查etcd的连通性

[root@docker-server1 ~]# etcdctl  --endpoints http://127.0.0.1:2379 member list
8e9e05c52164694d: name=etcd-131 peerURLs=http://localhost:2380 clientURLs=http://127.0.0.1:2379,http://192.168.132.131:2379 isLeader=true

查看etcdctl版本

[root@docker-server1 ~]# etcdctl --version
etcdctl version: 3.3.10
API version: 2
[root@docker-server1 ~]# etcdctl --help

更新etxdctl版本

[root@docker-server1 ~]#  export ETCDCTL_API=3
[root@docker-server1 ~]# etcdctl --help

 指令已经反生变化

3.3 安装Flannel

flannel下载地址:https://github.com/coreos/flannel/releases

下载

[root@docker-server1 ~]# wget https://github.com/coreos/flannel/releases/download/v0.11.0/flannel-v0.11.0-linux-amd64.tar.gz
[root@docker-server2 ~]# wget https://github.com/coreos/flannel/releases/download/v0.11.0/flannel-v0.11.0-linux-amd64.tar.gz
[root@docker-server1 ~]# tar -xf flannel-v0.11.0-linux-amd64.tar.gz 
[root@docker-server1 ~]# cp flanneld /usr/bin/
[root@docker-server1 ~]# cp mk-docker-opts.sh /usr/bin/

2. 版本etcdctl使用

添加flannel网络配置信息到etcd: 是一个键值对

[root@docker-server1 ~]# etcdctl 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"}}'

如果不是本机可以加参数: --endpoints http://IP:2379

{"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段,在上面的示例中,表示每个宿主机可以分配U一个24为掩码长度的子网,可以分配的子网从10.0.1.0、24到10.0.20.0/24,也就意味着在这个网段中,最多只能有20台宿主机

Backend:  用于指定数据包以什么方式转发,默认为udp模式,host-gw模式性能最好,但不能跨宿主机网络

[root@docker-server1 ~]# etcdctl get /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"}}

上面的操作时,时etcdctl的API版本是2可以使用,当升级到3版本后会报错

[root@docker-server1 ~]# etcdctl 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"}}'

3版本用法

[root@docker-server1 ~]# etcdctl --endpoints http://127.0.0.1:2379  put  /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"}}'

ok

[root@docker-server1 ~]# etcdctl get /coreos.com/network/config
/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"}}

下面的操作都是使用etcdctl V2版本

3.4 启动Flannel

[root@docker-server1 ~]# /usr/bin/flanneld --etcd-endpoints="http://192.168.132.131:2379" --iface=192.168.132.131 --etcd-prefix=/coreos.com/network &
[root@docker-server1 ~]# ip addr
[root@docker-server1 ~]# ps -ef |grep flan
root      86107  84636  0 15:02 pts/4    00:00:00 /usr/bin/flanneld --etcd-endpoints=http://192.168.132.131:2379 --iface=192.168.132.131 --etcd-prefix=/coreos.com/network

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

[root@docker-server1 ~]# mk-docker-opts.sh 
[root@docker-server1 ~]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=10.0.0.0/16
FLANNEL_SUBNET=10.0.8.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=false
[root@docker-server1 ~]# cat /run/docker_opts.env
DOCKER_OPT_BIP="--bip=10.0.4.1/24"
DOCKER_OPT_IPMASQ="--ip-masq=true"
DOCKER_OPT_MTU="--mtu=1450"
DOCKER_OPTS=" --bip=10.0.4.1/24 --ip-masq=true --mtu=1450"

需要把这个文件加到docker的启动项

[root@docker-server1 ~]# vi /usr/lib/systemd/system/docker.service
EnvironmentFile=/run/docker_opts.env
ExecStart=/usr/bin/dockerd  $DOCKER_OPTS  -H fd:// --containerd=/run/containerd/containerd.sock

启动dokcer

[root@docker-server1 ~]# systemctl daemon-reload
[root@docker-server1 ~]# systemctl restart docker

报错

[root@docker-server1 ~]# journalctl -xe -u docker
Nov 09 15:13:52 docker-server1 dockerd[86540]: unable to configure the Docker daemon with file /etc/docker/daemon.json: the following 
Nov 09 15:13:52 docker-server1 systemd[1]: docker.service: main process exited, code=exited, status=1/FAILURE

删除/etc/docker/daemon.json里的bip配置

[root@docker-server1 ~]# systemctl restart docker
To force a start use "systemctl reset-failed docker.service" followed by "systemctl start docker.service" again.
[root@docker-server1 ~]# systemctl restart docker
[root@docker-server1 ~]# ip addr
docker0的IP是10.0.4.1
[root@docker-server1 ~]#  etcdctl ls /coreos.com/network/
/coreos.com/network/subnets
/coreos.com/network/config

可以看到flannel0网卡的地址和etcd存储地址一样,这样flannel网络配置完成

Flannel启动过程解析

  1. 从etcd中获取network的配置xinx
  2. 划分subnet,并在etcd中进行注册
  3. 将子网信息记录到/run/flannel/subent.env中
  4. Flannel必须先于Docker启动

3.5 验证Flannel网络

查看etcd中的数据:

[root@docker-server1 ~]# etcdctl ls /coreos.com/network/subnets
/coreos.com/network/subnets/10.0.4.0-24

3.6 配置docker

Dokcer安装完成以后,需要修改其启动参数以使其能够使用flannel进行IP分配,以及网络通讯

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

[root@docker-server1 ~]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=10.0.0.0/16
FLANNEL_SUBNET=10.0.4.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=false

dokcer-server相同操作配置flannel.不用安装etcd

[root@docker-server2 ~]# tar -xf flannel-v0.11.0-linux-amd64.tar.gz
[root@docker-server2 ~]# mv flanneld /usr/bin/
[root@docker-server2 ~]# mv mk-docker-opts.sh /usr/bin/
[root@docker-server2 ~]# /usr/bin/flanneld --etcd-endpoints="http://192.168.132.131:2379" --iface=192.168.132.132 --etcd-prefix=/coreos.com/network &
[root@docker-server2 ~]# mk-docker-opts.sh -c
[root@docker-server2 ~]# cat /run/docker_opts.env 

修改dokcer启动文件,删除daemon.json的bip配置

[root@docker-server2 ~]# systemctl daemon-reload
[root@docker-server2 ~]# systemctl restart docker
[root@docker-server2 ~]# ip addr
[root@docker-server1 ~]#  etcdctl ls /coreos.com/network/subnets
/coreos.com/network/subnets/10.0.8.0-24
/coreos.com/network/subnets/10.0.18.0-24

两台主机的subnet网段

[root@docker-server1 ~]#  etcdctl get  /coreos.com/network/subnets/10.0.18.0-24
{"PublicIP":"192.168.132.132","BackendType":"vxlan","BackendData":{"VtepMAC":"62:b9:76:44:bf:32"}}
[root@docker-server1 ~]#  etcdctl get  /coreos.com/network/subnets/10.0.8.0-24
{"PublicIP":"192.168.132.131","BackendType":"vxlan","BackendData":{"VtepMAC":"62:93:c1:0f:b9:b0"}}

3.7 验证容器互通

[root@docker-server1 ~]# docker run -it busybox
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
124: eth0@if125: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue 
    link/ether 02:42:0a:00:04:02 brd ff:ff:ff:ff:ff:ff
    inet 10.0.4.2/24 brd 10.0.4.255 scope global eth0
       valid_lft forever preferred_lft forever
[root@docker-server2 ~]# docker run -it busybox
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
15: eth0@if16: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue 
    link/ether 02:42:0a:00:12:02 brd ff:ff:ff:ff:ff:ff
    inet 10.0.18.2/24 brd 10.0.18.255 scope global eth0
       valid_lft forever preferred_lft forever


#互ping
#192.168.132.131容器/ # ping 10.0.18.2
PING 10.0.18.2 (10.0.18.2): 56 data bytes64 bytes from 10.0.18.2: 
seq=0 ttl=62 time=2.517 ms64 bytes from 10.0.18.2: 
seq=1 ttl=62 time=1.058 ms64 bytes from 10.0.18.2: 
seq=2 ttl=62 time=1.676 ms192.168.132.132容器
PING 10.0.4.2 (10.0.4.2): 56 data bytes64 bytes from 10.0.4.2: 
seq=0 ttl=62 time=2.606 ms64 bytes from 10.0.4.2: 
seq=1 ttl=62 time=1.727 ms

两主机的容器可以互通

此时的网络数据包流向如图:

  1. 在dokcer-server1的busybox容器中查看路由表

    

    2. 回到dokcer-server1真机上,查看路由条目

    

    3. 查看arp列表

     

      C :  arp的缓存条目

      CM: arp的静态条目

     4. 查看mac地址 ce:2a:b6:dd:d6:3d的数据流向

[root@docker-server1 ~]# bridge fdb show

    

 

可以看到,如果是发向ce:2a:b6:dd:d6:3a的地址,则目标机器在192.168.100.208机器上。则数据就会流转到192.168.100.208上了。经过vxlan封包后的数据包就会经过eth0设备发向到192.168.100.208上。

3.8 配置backend为host-gw

host-gw bakcend是flannel的另一个backend。与vxlan不同,host-gw不会封装数据包,而是在主机的路由表中创建到其他主机的subnet的路由条目,从而实现容器网络跨主机通信。需要说明的是,host-gw不能跨宿主机网络通信,或者说跨宿主机网络通信需要物理路由支持。性能最好
修改etcd如下:

[root@docker-server1 ~]# 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": "host-gw"}}'
{"Network": "10.0.0.0/16", "SubnetLen": 24, "SubnetMin": "10.0.1.0","SubnetMax": "10.0.20.0", "Backend": {"Type": "host-gw"}

重启flanneld与docker:

root@docker-server1 ~]# kill -9 86780
[root@docker-server1 ~]#  /usr/bin/flanneld --etcd-endpoints="http://192.168.132.131:2379" --iface=192.168.132.131 --etcd-prefix=/coreos.com/network &
[root@docker-server1 ~]# systemctl restart docker
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:3e:dd:55:81 brd ff:ff:ff:ff:ff:ff
    inet 10.0.4.1/24 brd 10.0.4.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:3eff:fedd:5581/64 scope link 
       valid_lft forever preferred_lft forever
123: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default 
    link/ether 8e:b1:37:26:b0:59 brd ff:ff:ff:ff:ff:ff
    inet 10.0.4.0/32 scope global flannel.1
       valid_lft forever preferred_lft forever
    inet6 fe80::8cb1:37ff:fe26:b059/64 scope link 
       valid_lft forever preferred_lft forever

[root@docker-server2 ~]# kill -9 74050
[root@docker-server2 ~]# /usr/bin/flanneld --etcd-endpoints="http://192.168.132.131:2379" --iface=192.168.132.132 --etcd-prefix=/coreos.com/network &
[root@docker-server2 ~]# systemctl restart docker
[root@docker-server2 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:63:fd:11 brd ff:ff:ff:ff:ff:ff
    inet 192.168.132.132/24 brd 192.168.132.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::6a92:62ba:1b33:c93d/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:50:67:ff:90 brd ff:ff:ff:ff:ff:ff
    inet 10.0.18.1/24 brd 10.0.18.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:50ff:fe67:ff90/64 scope link 
       valid_lft forever preferred_lft forever
14: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default 
    link/ether 62:b9:76:44:bf:32 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::60b9:76ff:fe44:bf32/64 scope link 
       valid_lft forever preferred_lft forever

可以在宿主机上查看到路由条目

[root@docker-server1 ~]# ip route
default via 192.168.132.2 dev ens33 proto static metric 100 
10.0.0.0/16 dev flannel.1 
10.0.4.0/24 dev docker0 proto kernel scope link src 10.0.4.1 
10.0.18.0/24 via 192.168.132.132 dev ens33 
172.17.0.0/16 dev br-b1c2d9c1e522 proto kernel scope link src 172.17.0.1 
172.18.0.0/16 dev br-ec4a8380b2d3 proto kernel scope link src 172.18.0.1 
172.22.16.0/24 dev br-f42e46889a2a proto kernel scope link src 172.22.16.1 
192.168.132.0/24 dev ens33 proto kernel scope link src 192.168.132.131 metric 100

扩展

calico网络

  • bgp转发:相当于host-gw转发。不能跨网段进行转发
  • ipip转发:相当于vxlan转发模式

cailco优势:

  • 同时开启了两种转发模式,但是flannel只能开启其中一种转发模式
  • 自动判断,如果宿主机跨网段,就是用ipip的方式转发,如果没有跨网段,就使用bgp方式转发
  • 有流量策略管理,控制流量

ovs:openvswitch,openshift使用的网络

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值