专栏首页菲宇flannel原理简析及安装

flannel原理简析及安装

flannel是CoreOS提供用于解决Dokcer集群跨主机通讯的覆盖网络工具。它的主要思路是:预先留出一个网段,每个主机使用其中一部分,然后每个容器被分配不同的ip;让所有的容器认为大家在同一个直连的网络,底层通过UDP/VxLAN等进行报文的封装和转发。

flannel项目地址:https://github.com/coreos/flannel

flannel架构介绍

flannel默认使用8285端口作为UDP封装报文的端口,VxLan使用8472端口。

那么一条网络报文是怎么从一个容器发送到另外一个容器的呢?

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

flannel安装配置

环境准备

一共三台机器:一个etcd集群,三台机器安装flannel和Docker。

节点名称

IP地址

软件环境

etcd1

192.168.2.210

etcd、flannel、docker

etcd2

192.168.2.211

etcd、flannel、docker

etcd3

192.168.2.212

etcd、flannel、docker

安装etcd

关于etcd的安装使用已经在「etcd使用入门」和「通过静态发现方式部署etcd集群」中做了比较详细的讲解,如果你还不会安装etcd可先阅读下这两篇文章。这里就不再重复讲解了。

安装flannel

三个节点都需安装配置flannel,这里以etcd1节点为例。

flannel和etcd一样,直接从官方下载二进制执行文件就可以用了。当然,你也可以自己编译。

# curl -L https://github.com/coreos/flannel/releases/download/v0.7.0/flannel-v0.7.0-linux-amd64.tar.gz -o flannel.tar.gz

# mkdir -p /opt/flannel
# tar xzf flannel.tar.gz -C /opt/flannel

解压后主要有flanneldmk-docker-opts.sh这两个文件,其中flanneld为主要的执行文件,sh脚本用于生成Docker启动参数。

配置flannel

由于flannel需要依赖etcd来保证集群IP分配不冲突的问题,所以首先要在etcd中设置 flannel节点所使用的IP段。

$ etcdctl --endpoints "http://etcd1.hi-linux.com:2379" \ set /coreos.com/network/config '{"NetWork":"10.0.0.0/16", "SubnetMin": "10.0.1.0", "SubnetMax": "10.0.20.0"}' {"NetWork":"10.0.0.0/16", "SubnetMin": "10.0.1.0", "SubnetMax": "10.0.20.0"}

flannel预设的backend type是udp,如果想要使用vxlan作为backend,可以加上backend参数:

$ etcdctl --endpoints "http://etcd1.hi-linux.com:2379" \ set /coreos.com/network/config '{"NetWork":"10.0.0.0/16", "Backend": {"Type": "vxlan"}}'

flannel backend为vxlan比起预设的udp性能相对好一些。

启动flannel

  • 命令行方式运行

$ /opt/flannel/flanneld --etcd-endpoints="http://etcd1.hi-linux.com:2379" --ip-masq=true >> /var/log/flanneld.log 2>&1 &

  • 后台服务方式运行

给flannel创建一个systemd服务,方便以后管理。创建flannel配置文件:

$ cat <<EOF | sudo tee /etc/systemd/system/flanneld.service [Unit] Description=Flanneld Documentation=https://github.com/coreos/flannel After=network.target Before=docker.service [Service] User=root ExecStart=/opt/flannel/flanneld \ --etcd-endpoints="http://etcd1.hi-linux.com:2379,http://etcd2.hi-linux.com:2379,http://etcd3.hi-linux.com:2379" \ --iface=192.168.2.210 \ --ip-masq Restart=on-failure Type=notify LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF

注意:--iface参数为要绑定的网卡的IP地址,请根据实际情况修改。

启动flannel服务

$ systemctl start flanneld

flannel启动过程解析

flannel服务需要先于Docker启动。flannel服务启动时主要做了以下几步的工作:

  • 从etcd中获取network的配置信息。
  • 划分subnet,并在etcd中进行注册。
  • 将子网信息记录到/run/flannel/subnet.env中。

验证flannel网络

在etcd1节点上看etcd中的内容

$ etcdctl --endpoints "http://etcd1.hi-linux.com:2379" ls /coreos.com/network/subnets /coreos.com/network/subnets/10.0.2.0-24

查看flannel0的网络情况:

$ ifconfig flannel0 flannel0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 inet addr:10.0.2.0 P-t-P:10.0.2.0 Mask:255.255.0.0 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1472 Metric:1 RX packets:85 errors:0 dropped:0 overruns:0 frame:0 TX packets:75 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:500 RX bytes:7140 (7.1 KB) TX bytes:6300 (6.3 KB)

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

配置Docker

在各个节点安装好以后最后要更改Docker的启动参数,使其能够使用flannel进行IP分配,以及网络通讯。

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

  • 查看flannel分配的网络参数

$ cat /run/flannel/subnet.env FLANNEL_NETWORK=10.0.0.0/16 FLANNEL_SUBNET=10.0.2.1/24 FLANNEL_MTU=1472 FLANNEL_IPMASQ=true

  • 创建Docker运行参数

使用flannel提供的脚本将subnet.env转写成Docker启动参数,创建好的启动参数位于/run/docker_opts.env文件中。

$ /opt/flannel/mk-docker-opts.sh -d /run/docker_opts.env -c $ cat /run/docker_opts.env DOCKER_OPTS=" --bip=10.0.2.1/24 --ip-masq=false --mtu=1472"

  • 修改Docker启动参数

修改docker的启动参数,并使其启动后使用由flannel生成的配置参数,修改如下:

# 编辑 systemd service 配置文件 $ vim /lib/systemd/system/docker.service # 在启动时增加flannel提供的启动参数 ExecStart=/usr/bin/dockerd $DOCKER_OPTS # 指定这些启动参数所在的文件位置(这个配置是新增的,同样放在Service标签下) EnvironmentFile=/run/docker_opts.env

然后重新加载systemd配置,并重启Docker即可

$ systemctl daemon-reload $ systemctl restart docker

此时可以看到docker0的网卡ip地址已经处于flannel网卡网段之内。

$ ifconfig flannel0 flannel0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 inet addr:10.0.2.0 P-t-P:10.0.2.0 Mask:255.255.0.0 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1472 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:500 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) $ ifconfig docker0 docker0 Link encap:Ethernet HWaddr 02:42:cf:87:3c:f7 inet addr:10.0.2.1 Bcast:0.0.0.0 Mask:255.255.255.0 UP BROADCAST MULTICAST MTU:1500 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:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

到此节点etcd1的flannel安装配置完成了,其它两节点按以上方法配置完成就行了。

测试flannel

三台机器都配置好了之后,我们在三台机器上分别开启一个docker容器,测试它们的网络是否可相互联通的。

etcd1

$ docker run -it busybox sh # 查看容器IP $ cat /etc/hosts 10.0.2.2 9de86bfde6cc

etcd2

$ docker run -it busybox sh # 查看容器IP $ cat /etc/hosts 10.0.5.2 9ddd4a4e455b

etcd3

$ docker run -it busybox sh # 查看容器IP $ cat /etc/hosts 10.0.6.2 cbb0d891f353

  • 从不同宿主机容器到三台宿主机

/ # ping -c3 192.168.2.210 PING 192.168.2.210 (192.168.2.210): 56 data bytes 64 bytes from 192.168.2.210: seq=0 ttl=64 time=0.089 ms 64 bytes from 192.168.2.210: seq=1 ttl=64 time=0.065 ms / # ping -c5 192.168.2.211 PING 192.168.2.211 (192.168.2.211): 56 data bytes 64 bytes from 192.168.2.211: seq=0 ttl=63 time=1.712 ms 64 bytes from 192.168.2.211: seq=1 ttl=63 time=0.356 ms 64 bytes from 192.168.2.211: seq=2 ttl=63 time=2.201 ms / # ping -c3 192.168.2.212 PING 192.168.2.212 (192.168.2.212): 56 data bytes 64 bytes from 192.168.2.212: seq=0 ttl=63 time=0.467 ms 64 bytes from 192.168.2.212: seq=1 ttl=63 time=0.477 ms 64 bytes from 192.168.2.212: seq=2 ttl=63 time=0.532 ms

  • 从容器到到跨宿主机容器

/ # ping -c3 10.0.5.2 PING 10.0.5.2 (10.0.5.2): 56 data bytes 64 bytes from 10.0.5.2: seq=0 ttl=60 time=0.692 ms 64 bytes from 10.0.5.2: seq=1 ttl=60 time=0.565 ms 64 bytes from 10.0.5.2: seq=2 ttl=60 time=1.135 ms / # ping -c3 10.0.6.2 PING 10.0.6.2 (10.0.6.2): 56 data bytes 64 bytes from 10.0.6.2: seq=0 ttl=60 time=0.678 ms 64 bytes from 10.0.6.2: seq=1 ttl=60 time=0.907 ms 64 bytes from 10.0.6.2: seq=2 ttl=60 time=1.272 ms / # ping -c3 10.0.2.2 PING 10.0.2.2 (10.0.2.2): 56 data bytes 64 bytes from 10.0.2.2: seq=0 ttl=60 time=0.644 ms 64 bytes from 10.0.2.2: seq=1 ttl=60 time=0.915 ms 64 bytes from 10.0.2.2: seq=2 ttl=60 time=1.032 ms

测试容器到到跨宿主机容器遇到一个坑,开始怎么都不通,后找到原因是宿主机iptables给阻挡掉了。附:Ubuntu一键清除iptables规则脚本

$ cat clear_iptables_rule.sh #!/bin/bash iptables -F iptables -X iptables -Z iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT iptables -P FORWARD ACCEPT

参考文档

http://t.cn/RcnGQ02 http://t.cn/RXVHGpI http://t.cn/RXfavPG http://t.cn/RXfEThA http://t.cn/RXfEmS8 http://t.cn/R5Xgfnx

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Kubernetes配置flannel网络

    菲宇
  • diango之基于内置视图CBS编程

    Class-based views是Django为解决建站过程中的常见的呈现模式而建立的。具有如下几个原则:

    菲宇
  • python中eval函数作用

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    菲宇
  • OVN实战三之打通真实网络提供NAT

    概述 上篇文章《OVN实战二之Overlay实现》介绍了OVN中逻辑交换机、逻辑路由器的用法,本章介绍如何让OVN中的虚拟机访问外部网络和面向外部网络提供服务(...

    SDNLAB
  • vue优雅的实现关闭弹框

    假如说,有这样一个页面,一个蒙层,然后上面一个弹框,怎么优雅的去做关闭这个弹框呢?

    brzhang
  • MLSQL如何支持部署SKLearn,Tensorflow,MLLib模型提供API预测服务

    部署成API服务时,除了要把raw数据特征化成向量外,研发还要想着怎么加载模型,产生模型的框架五花八门,比如Tensorflow,SKlearn,Spark M...

    用户2936994
  • LeetCode 122. Best Time to Buy and Sell Stock IISOLUTION

    很简单,既然可以进行任意次的交易,那么我们就将所有前一天比后一天价格低的都进行交易,因为只有这样,才会增加收益,所以我们进行一次遍历之后,就可以求出的最大收益值...

    desperate633
  • 摄像机视频信号如何通过NDI传输到Zoom会议软件

    随着融媒体技术的不断发展,线上网络直播、视频会议、远程医疗等高清视频传输应用已日趋火爆。而NDI作为是一种低延时、高画质的视频传输协议,可与各种软件系统相兼容。...

    千视kiloview
  • 分布式事务 TCC-Transaction 源码分析 —— TCC 实现

    本文主要基于 TCC-Transaction 1.2.3.3 正式版 1. 概述 2. TCC 原理 3. TCC-Transaction 原理 4. 事务与参...

    芋道源码
  • sql server 事务处理

    事物处理 事务是SQL Server中的单个逻辑单元,一个事务内的所有SQL语句作为一个整体执行,要么全部执行,要么都不执行。 事务有4个属性,称为ACID(原...

    欠扁的小篮子

扫码关注云+社区

领取腾讯云代金券