
211工程院校贵州大学管理学院硕士研究生、全国百强城商行资讯科技部五级专技工程师、互联网金融行业资深DevOps研发工程师、金融科技运维自动化平台研发项目经理。曾在国内多家知名互联网公司 平安科技、微众银行、顺丰科技、魅族任职. 具有多年国内一线互联网公司自动化运维平台设计与开发经验。
1
vxlan介绍

2
vxlan产生背景
2. 网络规模过大导致MAC地址表耗尽
交换机以MAC地址表作为寻址依据完成数据帧转发工作,当数据帧中的目标MAC地址在设备的MAC地址表中,则将数据帧从指定的接口转发出去,若不在则对数据帧做泛洪处理。在虚拟化技术没出现之前,接入层交换机的每个端口仅连接一台物理服务器,并对应一个MAC地址,当虚拟化技术出现后,一台物理服务器虚拟出大量虚拟机,交换机的一个端口虽然还是连接一台物理服务器,但却对应了多个MAC地址,这无疑会造成交换机MAC地址表的膨胀,而交换机的MAC地址表空间是有限的,若发生溢出,就会造成交换机不断的泛洪数据帧,增加了报文处理负担。
3. 虚拟机迁移范围受网络架构限制


3
Flannel vxLAN通信流程
根据如下网络拓扑,分析数据报文是如何从一个容器发送到位于不同宿主机的另外一个容器中的:

step1. WebAppFrontend容器访问BackendService容器,SIP10.1.15.2 DIP 10.1.20.2
step2. 数据报文通过容器网卡接口eth0、经由veth设备发送至docker0
step3. docker0通过匹配主机的路由表,将数据报文发送到 flannel.0 接口
step4. flannel.0是一个VETP(VXLAN Tunnel End Point)设备,对vxlan数据包进行封装和解封装操作,此时会根据flannel.0创建时设置的参数,进行vxlan封包操作
step5. 宿主机A通过物理网卡发送报文至宿主机B
step6. 宿主机B的物理网卡eth0接收报文并解封装,报文四层为UDP协议端口为8472,则将报文转发至VTEP设备flannel.0解封装
step7. 数据报文通过docker0发送至BackendService容器中
4
Flannel vxlan配置
[root@localhost yum.repos.d]# wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
[root@localhost yum.repos.d]# rpm -ivh epel-release-latest-7.noarch.rpm[root@localhost yum.repos.d]# yum -y install etcd
step3. 修改配置文件
单节点部署只保留以下三处配置即可
--name: 节点名
--etcd_data_dir: 数据存储路径
--etcd_listen_client_url: 供外部客户端使用的url
--etcd_advertise_client_urls: 广播给外部客户端使用的地址
[root@localhost etcd]# cat etc/etcd/etcd.conf#[Member]ETCD_DATA_DIR="/var/lib/etcd/default.etcd"ETCD_LISTEN_CLIENT_URLS="http://172.16.70.190:2379"ETCD_NAME="default"ETCD_ADVERTISE_CLIENT_URLS="http://172.16.70.190:2379"
step4: 启动etcd
[root@localhost etcd]# systemctl restart etcd[root@localhost etcd]# systemctl stop firewalld[root@localhost etcd]# systemctl disable firewalldRemoved symlink etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.Removed symlink etc/systemd/system/basic.target.wants/firewalld.service.
step5. 验证集群健康状态
[root@localhost etcd]# etcdctl --endpoint http://172.16.70.190:2379 cluster-healthmember 8e9e05c52164694d is healthy: got healthy result from http://172.16.70.190:2379cluster is healthy
4.2 flannel 配置
step1. 生成配置文件flannel-vxlan.json,在配置文件中定义了,全局Overlay网络为B类的10.2.0.0/16,每一个docker宿主机从B类地址池中获取一个C段地址,并指定了网络类型为vxlan。
{"Network": "10.0.0.0/16","SubnetLen": 24,"Backend": {"Type": "vxlan"}}
step2. 向etcd写入配置
[root@localhost ~]# etcdctl --endpoint http://172.16.70.190:2379 mkdir flannel-vxlan/network[root@localhost ~]# etcdctl --endpoint http://172.16.70.190:2379 set flannel-vxlan/network/config < flannel-vxlan.json{"Network": "10.0.0.0/16","SubnetLen": 24,"Backend": {"Type": "vxlan"}}
step3. 安装Flannel
[root@localhost src]# wget https://github.com/flannel-io/flannel/releases/download/v0.9.1/flannel-v0.9.1-linux-amd64.tar.gz[root@localhost src]# tar -C usr/bin/ -xvf flannel-v0.9.1-linux-amd64.tar.gz
step4. 启动flannel
注意flannel的启动顺序在docker服务之前
[root@localhost ~]# flanneld -etcd-endpoints=http://172.16.70.190:2379 -etcd-prefix=/flannel-vxlan/network --ip-masq=true --iface=172.16.70.191[root@localhost ~]# flanneld -etcd-endpoints=http://172.16.70.190:2379 -etcd-prefix=/flannel-vxlan/network --ip-masq=true --iface=172.16.70.192
step5. 此时docker服务宿主机上将会出现网卡flannel.1


vxlan模型flannel模型监听端口UDP 8472
[root@localhost ~]# netstat -tuan | grep 8472udp 0 0 0.0.0.0:8472 0.0.0.0:*
step6. 验证子网分配
[root@localhost ~]# etcdctl --endpoint http://172.16.70.190:2379 ls flannel-vxlan/network/subnets/flannel-vxlan/network/subnets/10.0.65.0-24/flannel-vxlan/network/subnets/10.0.32.0-24
可见flannel从Etcd中分别申请了两个子网, 子网信息会记录在docker宿主机的/run/flannel/subnet.env文件中;在flannel安装包中,mk-docker-opts.sh中定义了默认的环境变量文件位置。
# docker1[root@localhost ~]# cat run/flannel/subnet.envFLANNEL_NETWORK=10.0.0.0/16FLANNEL_SUBNET=10.0.65.1/24FLANNEL_MTU=1450FLANNEL_IPMASQ=true# docker2[root@localhost ~]# cat run/flannel/subnet.envFLANNEL_NETWORK=10.0.0.0/16FLANNEL_SUBNET=10.0.32.1/24FLANNEL_MTU=1450FLANNEL_IPMASQ=true
step7. 执行脚本mk-docker-opts.sh 生成docker启动参数
DOCKER_OPTS=" --bip=10.0.65.1/24 --ip-masq=false --mtu=1450"
step8. 修改docker启动文件添加参数
# docker1[Service]Type=notify# the default is not to use systemd for cgroups because the delegate issues still# exists and systemd currently does not support the cgroup feature set required# for containers run by dockerExecStart=/usr/bin/dockerd --bip=10.0.65.1/24 --ip-masq=false --mtu=1500 -H fd:// --containerd=/run/containerd/containerd.sockExecReload=/bin/kill -s HUP $MAINPIDTimeoutSec=0RestartSec=2Restart=always# docker2[Service]Type=notify# the default is not to use systemd for cgroups because the delegate issues still# exists and systemd currently does not support the cgroup feature set required# for containers run by dockerExecStart=/usr/bin/dockerd --bip=10.0.32.1/24 --ip-masq=false --mtu=1500 -H fd:// --containerd=/run/containerd/containerd.sockExecReload=/bin/kill -s HUP $MAINPIDTimeoutSec=0RestartSec=2Restart=always
step9. 启动docker验证配置
[root@localhost ~]# systemctl daemon-reload[root@localhost ~]# systemctl restart docker
Step10. 创建容器,验证连通性
在两台docker宿主机上分别创建容器,查看获取的IP地址并验证网络连通性。

综上,工作在vxlan模式下的flannel配置成功。
5
vxlan数据流
下面分析一下vxlan模式下位于不同宿主机上的容器的通信流程,以上文容器10.0.65.2通过ICMP 连接 10.0.32.2为例。
[root@0599f5f991ae /]# ip routedefault via 10.0.65.1 dev eth010.0.65.0/24 dev eth0 proto kernel scope link src 10.0.65.2
step2. 继续查看宿主机路由表,10.0.65.X连接在docker0上,目标网段10.0.32.X在flannel.1上
[root@localhost ~]# ip routedefault via 172.16.70.1 dev eno16777736 proto static metric 10010.0.32.0/24 via 10.0.32.0 dev flannel.1 onlink10.0.65.0/24 dev docker0 proto kernel scope link src 10.0.65.1
step3. 获取vxlan网络对应的宿主机网卡真实IP
由于flannel.1是一个vtep二层设备, 所以需要根据vxlan的协议标准进行二层封装转发,而二层转发的前提是需要获取远程对应IP10.0.32.X 的节点的mac地址, 由于vxlan设备在查询的mac的时候是不会发送arp信息的, 所以这时候flanneld可以从etcd里面获取目的IP所在网段对应的vtep设备的mac地址, 示例如下:
[root@localhost ~]# etcdctl --endpoint http://172.16.70.190:2379 get /flannel-vxlan/network/subnets/10.0.32.0-24{"PublicIP":"172.16.70.192","BackendType":"vxlan","BackendData":{"VtepMAC":"4e:75:5c:b8:d8:8e"}}
可见,想要将数据包传送至10.0.32.X网段的容器,需要将外层数据包的目标IP地址封装为 172.16.70.192。
step4. vxlan转发
在数据包经由vxlan规范封装之后, 内核需要知道将这个vxlan包送到哪个节点去. 所以需要查询本节点上的vxlan fdb(forwarding database)以获得目的端vtep对应的IP地址, 如果未能查询到则flanneld需要向etcd查询并存储到fdb中. 这时候vxlan设备就能准确的将数据包经由UDP协议发送至对端的vxlan设备flannel.1了,查询方式如下:
[root@localhost ~]# bridge fdb show dev flannel.14e:75:5c:b8:d8:8e dst 172.16.70.192 self permanent
6
结束语






