Flannel 技术调研,固定主机和容器IP的方法

简介

Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址。但在默认的Docker配置中, 每个节点上的Docker服务会分别负责所在节点容器的IP分配。这样导致的一个问题是,不同节点上容器可能获得相同的内外IP地址。并使这些容器之间能够之间通过IP地址相互找到,也就是相 互ping通。

Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得"同属一个内网"且"不重复的"IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。

Flannel实质上是一种"覆盖网络(overlay network)",即表示运行在一个网上的网(应用层网络),并不依靠ip地址来传递消息,而是采用一种映射机制,把ip地址和identifiers做映射来资源定位。也就 是将TCP数据包装在另一种网络包里面进行路由转发和通信,目前已经支持UDP、VxLAN、AWS VPC和GCE路由等数据转发方式。

原理是每个主机配置一个ip段和子网个数。例如,可以配置一个覆盖网络使用 10.100.0.0/16段,每个主机/24个子网。因此主机a可以接受10.100.5.0/24,主机B可以接受10.100.18.0/24的包。flannel使用etcd来维护分配的子网到实际的ip地址之间的映射。对于数据路径,flannel 使用udp来封装ip数据报,转发到远程主机。选择UDP作为转发协议是因为他能穿透防火墙。例如,AWS Classic无法转发IPoIP or GRE 网络包,是因为它的安全组仅仅支持TCP/UDP/ICMP。

flannel 使用etcd存储配置数据和子网分配信息。flannel 启动之后,后台进程首先检索配置和正在使用的子网列表,然后选择一个可用的子网,然后尝试去注册它。 etcd也存储这个每个主机对应的ip。flannel 使用etcd的watch机制监视/coreos.com/network/subnets下面所有元素的变化信息,并且根据他来维护一个路由表。为了提高性能,flannel优化了Universal TAP/TUN设备,对TUN和UDP之间的ip分片做了代理。

另外,flannel是没有DNS服务的,容器无法通过hostname通信。

安装

需要先安装etcd,之后可以使用yum方式安装flannel

复制代码
yum install -y flannel

首先使用etcdctl命令在etcd服务中写入flannel需要用到的配置,注意set之后的路径前缀需要和flannel的配置文件中的FLANNEL_ETCD_PREFIX一致

swift 复制代码
etcdctl set /zkxl_flannel/network/config '{"Network": "10.0.0.0/16", "SubnetLen": 24, "SubnetMin": "10.0.0.0","SubnetMax": "10.0.199.0", "Backend": {"Type": "vxlan"}}'

Network:用于指定Flannel地址池

SubnetLen:用于指定分配给单个宿主机的docker0的ip段的子网掩码的长度

SubnetMin:用于指定最小能够分配的ip段

SudbnetMax:用于指定最大能够分配的ip段,在上面的示例中,表示每个宿主机可以分配一个24位掩码长度的子网,可以分配的子网从10.0.0.0/24到10.0.199.0/24,也就意味着在这个网段中,最多只能有200台宿主机

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

修改flannel配置文件,注意其中的FLANNEL_ETCD_PREFIX 要和之前设置到etcd中的路径前缀一致

bash 复制代码
vim /etc/sysconfig/flanneld
bash 复制代码
# Flanneld configuration options  

# etcd url location.  Point this to the server where etcd runs
FLANNEL_ETCD_ENDPOINTS="http://127.0.0.1:2379"

# etcd config key.  This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_PREFIX="/zkxl_flannel/network"

# Any additional options that you want to pass
#FLANNEL_OPTIONS=""

启动flanneld

bash 复制代码
systemctl start flanneld
systemctl status flanneld

启动 flanneld 后,会有一张 flannel0 网卡产生:而且还生成了配置文件 /run/flannel/subnet.env,此网卡的地址就是之前在etcd中定义的网段地址。

这样则会生成/run/flannel/docker文件, 在这个文件中一般会给docker提供一个设定参数DOCKER_NETWORK_OPTIONS,DOCKER_NETWORK_OPTIONS中会包含如下设定信息:

--bip

--ip-masq

--mtu

而在docker的systemd的service中,只需要将DOCKER_NETWORK_OPTIONS传递给dockerd即可。

bash 复制代码
vim /usr/lib/systemd/system/docker.service

# 然后在ExecStart中添加$DOCKER_NETWORK_OPTIONS,如下所示
ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS -H fd:// --containerd=/run/containerd/containerd.sock

然后重启docker,这样Flannel配置分配的ip才能生效,即docker0虚拟网卡的ip会变成上面flannel设定的ip段。

bash 复制代码
systemctl daemon-reload
systemctl restart docker

# 之后查看docker进程的启动,应该能看到相关的参数了

ps -ef | grep docker

root     18793     1  0 17:08 ?        00:00:00 /usr/bin/dockerd --bip=10.0.26.1/24 --ip-masq=true --mtu=1450 -H fd:// --containerd=/run/containerd/containerd.sock
root     18931 18741  0 17:09 pts/2    00:00:00 grep --color=auto docker

方案

如何固定某个主机的IP配置

参考官方文档中的介绍 flannel/reservations.md at master · flannel-io/flannel · GitHub

ini 复制代码
# 先看下在当前配置中本机分配到的IP地址段
cat /run/flannel/subnet.env

FLANNEL_NETWORK=10.0.0.0/16
FLANNEL_SUBNET=10.0.76.1/24  # 这里就是在当前配置下分配到的网段
FLANNEL_MTU=1450
FLANNEL_IPMASQ=false

# 先关掉flannel服务,防止修改过程中会更新还未修改完的配置
systemctl stop flanneld

# 查看当前etcd中存储的相关网段配置
etcdctl ls /zkxl_flannel/network/subnets

/zkxl_flannel/network/subnets/10.0.76.0-24     # 这一行就是当前主机的配置,我们要复制一份
/zkxl_flannel/network/subnets/10.0.84.0-24

# 以下命令复制了一份现在的配置,但是会把新的IP段设置到10.0.0.0-24这个网段,并且把ttl过期时间设置成0,这样这个配置就会变成永久的预留
etcdctl set -ttl 0 /zkxl_flannel/network/subnets/10.0.0.0-24 $(etcdctl get /zkxl_flannel/network/subnets/10.0.76.0-24)

# 删除原来的
etcdctl rm /zkxl_flannel/network/subnets/10.0.76.0-24

# 之后修改本机的subnet.env
vim /run/flannel/subnet.env

FLANNEL_NETWORK=10.0.0.0/16
FLANNEL_SUBNET=10.0.0.1/24  # 这里修改成想要调整到的网段
FLANNEL_MTU=1450
FLANNEL_IPMASQ=false

# 重新启动flannel服务
systemctl start flanneld

# 最后要重启docker服务
systemctl restart docker

如何固定某个容器的IP

flannel会给每个物理机的docker添加一个默认的网桥,通过这个网桥各个容器都是互通的,但是我们这里还有一个需求,就是怎么固定住其中的容器的IP?这个暂时没有找到有效的解决方法,使用docker-compose配置时只能使用自定义的网桥网络时才能指定IP,而flannel这个对于docker属于external网络,这时候就不能自己指定IP了。

Static ip · Issue #167 · flannel-io/flannel · GitHub在这个issue中,最后tomdee的回答如下,他提供了一种固定某个主机的IP配置的方式,也就是上面的章节中我们提到的方式,但是tomdee认为固定容器IP的方式不属于flannel应该解决的问题。

Static subnet reservation for a host can be done following this doc I added github.com/coreos/flan...

Static IP addresses for individual containers/pods is not something to flannel manages.

参考文档

相关推荐
蓝纹绿茶3 小时前
【Mac】实现Docker下载安装【正在逐步完善】
macos·docker·容器
2401_861615283 小时前
跨平台的ARM 和 x86 Docker 镜像:汇编语言实验环境搭建
linux·汇编·ubuntu·docker·容器
INFINI Labs5 小时前
搭建持久化的 INFINI Console 与 Easysearch 容器环境
docker·easysearch·console
生活爱好者!6 小时前
NAS 部署白板工具,实现思维导图/画板/流程图自由
运维·docker·容器
乌鸦不像写字台12 小时前
【docker部署】在服务器上使用docker
服务器·docker·容器
艾伦_耶格宇16 小时前
【docker】-1 docker简介
运维·docker·容器
IvanCodes17 小时前
二、Docker安装部署教程
docker·容器
保持学习ing1 天前
day1--项目搭建and内容管理模块
java·数据库·后端·docker·虚拟机
susu10830189111 天前
Debian 11 Bullseye 在线安装docker
运维·docker·debian
love530love1 天前
Docker 稳定运行与存储优化全攻略(含可视化指南)
运维·人工智能·windows·docker·容器