阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Flannel入门介绍

159次阅读
没有评论

共计 4213 个字符,预计需要花费 11 分钟才能阅读完成。

Flannel 是 CoreOS 团队针对 Kubernetes 设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的 Docker 容器都具有全集群唯一的虚拟 IP 地址。

在 Kubernetes 的网络模型中,假设了每个物理节点应该具备一段“属于同一个内网 IP 段内”的“专用的子网 IP”。例如:

 节点 A:10.0.1.0/24
节点 B:10.0.2.0/24
节点 C:10.0.3.0/24

但在默认的 Docker 配置中,每个节点上的 Docker 服务会分别负责所在节点容器的 IP 分配。这样导致的一个问题是,不同节点上容器可能获得相同的内外 IP 地址。并使这些容器之间能够之间通过 IP 地址相互找到,也就是相互 ping 通。
Flannel 的设计目的就是为集群中的所有节点重新规划 IP 地址的使用规则,从而使得不同节点上的容器能够获得“同属一个内网”且”不重复的”IP 地址,并让属于不同节点上的容器能够直接通过内网 IP 通信。

2Flannel 的工作原理

Flannel 实质上是一种“覆盖网络 (overlay network)”,也就是将 TCP 数据包装在另一种网络包里面进行路由转发和通信,目前已经支持 UDP、VxLAN、AWS VPC 和 GCE 路由等数据转发方式。

默认的节点间数据通信方式是 UDP 转发,在 Flannel 的 GitHub 页面有如下的一张原理图:

Flannel 入门介绍

这张图的信息量很全,下面简单的解读一下。
数据从源容器中发出后,经由所在主机的 docker0 虚拟网卡转发到 flannel0 虚拟网卡,这是个 P2P 的虚拟网卡,flanneld 服务监听在网卡的另外一端。
Flannel 通过 Etcd 服务维护了一张节点间的路由表,在稍后的配置部分我们会介绍其中的内容。
源主机的 flanneld 服务将原本的数据内容 UDP 封装后根据自己的路由表投递给目的节点的 flanneld 服务,数据到达以后被解包,然后直 接进入目的节点的 flannel0 虚拟网卡,然后被转发到目的主机的 docker0 虚拟网卡,最后就像本机容器通信一下的有 docker0 路由到达目标容器。
这样整个数据包的传递就完成了,这里需要解释三个问题。

第一个问题,UDP 封装是怎么一回事?

我们来看下面这个图,这是在其中一个通信节点上抓取到的 ping 命令通信数据包。可以看到在 UDP 的数据内容部分其实是另一个 ICMP(也就是 ping 命令)的数据包。

Flannel 入门介绍

原始数据是在起始节点的 Flannel 服务上进行 UDP 封装的,投递到目的节点后就被另一端的 Flannel 服务还原成了原始的数据包,两边的 Docker 服务都感觉不到这个过程的存在。

第二个问题,为什么每个节点上的 Docker 会使用不同的 IP 地址段?

这个事情看起来很诡异,但真相十分简单。其实只是单纯的因为 Flannel 通过 Etcd 分配了每个节点可用的 IP 地址段后,偷偷的修改了 Docker 的启动参数,见下图。

Flannel 入门介绍

这个是在运行了 Flannel 服务的节点上查看到的 Docker 服务进程运行参数。

注意其中的“–bip=172.17.18.1/24”这个参数,它限制了所在节点容器获得的 IP 范围。

这个 IP 范围是由 Flannel 自动分配的,由 Flannel 通过保存在 Etcd 服务中的记录确保它们不会重复。

第三个问题,为什么在发送节点上的数据会从 docker0 路由到 flannel0 虚拟网卡,在目的节点会从 flannel0 路由到 docker0 虚拟网卡?

我们来看一眼安装了 Flannel 的节点上的路由表。下面是数据发送节点的路由表:

Flannel 入门介绍

这个是数据接收节点的路由表:

Flannel 入门介绍

例如现在有一个数据包要从 IP 为 172.17.18.2 的容器发到 IP 为 172.17.46.2 的容器。根据数据发送节点的路由表,它只与 172.17.0.0/16 匹配这条记录匹配,因此数据从 docker0 出来以后就被投递到了 flannel0。同理在目标节点,由于投递的地址是一个容 器,因此目的地址一定会落在 docker0 对于的 172.17.46.0/24 这个记录上,自然的被投递到了 docker0 网卡。

回到顶部

 

3Flannel 的安装和配置

Flannel 是 Golang 编写的程序,因此的安装十分简单。
从 https://github.com/coreos/flannel/releases 和 https://github.com/coreos/etcd/releases 分别下载 Flannel 和 Etcd 的最新版本二进制包。
解压后将 Flannel 的二进制文件“flanneld”和脚本文件“mk-docker-opts.sh”、以及 Etcd 的二进制文件“etcd”和“etcdctl”放到系统的 PATH 目录下面安装就算完成了。
配置部分要复杂一些。
首先启动 Etcd,参考 https://github.com/coreos/etcd … overy。
访问这个地址:https://discovery.etcd.io/new?size=3 获得一个“Discovery 地址”
在每个节点上运行以下启动命令:
etcd -initial-advertise-peer-urls http://< 当前节点 IP>:2380 -listen-peer-urls http://< 当前节点 IP>:2380 -listen-client-urlshttp://< 当前节点 IP>:2379,http://< 当前节点 IP>:2379 -advertise-client-urls http://< 当前节点 IP>:2379 -discovery < 刚刚获得的 Discovery 地址 > & 
启动完 Etcd 以后,就可以配置 Flannel 了。

Flannel 的配置信息全部在 Etcd 里面记录,往 Etcd 里面写入下面这个最简单的配置,只指定 Flannel 能用来分配给每个 Docker 节点的拟 IP 地址段:

etcdctl set /coreos.com/network/config '{"Network":"172.17.0.0/16"}'

然后在每个节点分别启动 Flannel:

flanneld &

最后需要给 Docker 动一点手脚,修改它的启动参数和 docker0 地址。

在每个节点上执行:

sudo mk-docker-opts.sh -i
source /run/flannel/subnet.env
sudo rm /var/run/docker.pid
sudo ifconfig docker0 ${FLANNEL_SUBNET}

重启动一次 Docker,这样配置就完成了。

现在在两个节点分别启动一个 Docker 容器,它们之间已经通过 IP 地址直接相互 ping 通了。

到此,整个 Flannel 集群也就正常运行了。

最后,前面反复提到过 Flannel 有一个保存在 Etcd 的路由表,可以在 Etcd 数据中找到这些路由记录,如下图。

Flannel 入门介绍

Q&A

问:数据从源容器中发出后,经由所在主机的 docker0 虚拟网卡转发到 flannel0 虚拟网卡,这种 P2P 实际生产中是否存在丢包,或者此机制有高可用保障么?
答:只是本机的 P2P 网卡,没有经过外部网络,应该还比较稳定。但我这里没有具体数据。

问:UDP 数据封装,转发的形式也是 UDP 么?我们一般知道 UDP 发送数据是无状态的,可靠么?
答:转发的是 UDP,高并发数据流时候也许会有问题,我这里同样没有数据。

问:实际上,kubernates 是淡化了容器 ip,外围用户只需关注所调用的服务,并不关心具体的 ip,这里 fannel 将 IP 分开且唯一,这样做有什么好处?有实际应用的业务场景么?
答:IP 唯一是 Kubernetes 能够组网的条件之一,不把网络拉通后面的事情都不好整。

问:Flannel 通过 Etcd 分配了每个节点可用的 IP 地址段后,偷偷的修改了 Docker 的启动参数:那么如果增加节点,或删除节点,这些地址段(ETCD 上)会动态变化么?如果不是动态变化,会造成 IP 地址的浪费么?
答会造成一些浪费,一般使用 10.x.x.x 的 IP 段。

问:sudo mk-docker-opts.sh -i 这个命令具体干什么了?非 coreos 上使用 flannel 有什么不同?
答:生成了一个 Docker 启动的环境变量文件,里面给 Docker 增加了启动参数。
没有什么不同,只是 CoreOS 集成了 Flannel,在 CoreOS 上面启动 Flannel 只是一行命令:systemctl start flanneld。

问:容器 IP 都是固定的吗?外网与物理主机能 ping 通,也能 ping 通所有 Docker 集群的容器 IP?
答:不是固定的,IP 分配还是 Docker 在做,Flannel 只是分配了子网。

问:Flannel 的能否实现 VPN?你们有没有研究过?
答:应该不能,它要求这些容器本来就在一个内网里面。

问:Flannl 是谁开发的?全是对 k8s 的二次开发吗?
答:CoreOS 公司,不是 k8s 的二次开发,独立的开源项目,给 k8s 提供基础网络环境。

问:Flannel 支持非封包的纯转发吗?这样性能就不会有损失了?
答:非封装怎样路由呢?发出来的 TCP 包本身并没有在网络间路由的信息,别忘了,两个 Flannel 不是直连的,隔着普通的局域网络。

问:Flanel 现在到哪个版本了,后续版本有什么侧重点?性能优化,还是功能扩展?
答:还没到 1.0,在 GitHub 上面有他们的发展计划,性能是很大的一部分。

问:就是在 CoreOS 中,客户还需要安装 Flannel 吗?
答:不需要,在启动的 Cloudinit 配置里面给 Etcd 写入 Flannel 配置,然后加上 flanneld.service command: start 就可以了,启动完直接可用,文档连接我不找了,有这段配置,现成的。

问:可不可以直接用命令指定每个主机的 ip 范围,然后做 gre 隧道实现节点之间的通信?这样也可以实现不同主机上的容器 ip 不同且可以相互通信吧?
答:还不支持指定哪个节点用那段 IP,不过貌似可以在 Etcd 手改。

问:Flannel 只是负责通信服务,那是不是还要安装 k8s?
答:是的,k8s 是单独的。

问:现在 Docker 的网络组件还有什么可以选择或者推荐的? 
答:Overlay 网络的常用就是 Flannel 和 Weave,其他 OVS 之类的另说了。

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-21发表,共计4213字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中