千家信息网

Flannel-UDP在kubernetes中如何工作

发表于:2025-01-23 作者:千家信息网编辑
千家信息网最后更新 2025年01月23日,Flannel-UDP在kubernetes中如何工作,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Kubernetes是用于大规模管理
千家信息网最后更新 2025年01月23日Flannel-UDP在kubernetes中如何工作

Flannel-UDP在kubernetes中如何工作,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

Kubernetes是用于大规模管理容器化应用程序出色的编排工具。但是,您可能知道,使用kubernetes并非易事,尤其是后端网络实现。我在网络中遇到了许多问题,花了我很多时间弄清楚它是如何工作的。

我想以最简单的实现为例,来解释kubernetes的网络工作。

Kubernetes网络模型

下图显示了kubernetes集群的简单图像:

kubernetes中的pod

Kubernetes管理Linux机器集群(可能是ECS之类的云VM或物理服务器),在每台主机上,kubernetes运行任意数量的Pod,在每个Pod中可以有任意数量的容器。用户的应用程序正在这些容器之一中运行。

对于kubernetes,Pod是最小的管理单元,并且一个Pod中的所有容器共享相同的网络名称空间,这意味着它们具有相同的网络接口并且可以使用*localhost*相互连接

在官方文件说kubernetes网络模式要求:

  • 所有容器无需NAT即可与所有其他容器通信
  • 所有节点都可以与所有容器通信(反之亦然),而无需NAT
  • 容器所看到的IP其他人所看到的IP一样

我们可以按照上述要求将所有容器替换为Pod,因为容器与Pod网络共享。

基本上,这意味着所有Pod都应该能够与群集中的其他Pod自由通信,即使它们位于不同的主机中,并且它们也使用自己的IP地址相互识别,就像基础主机不存在一样。此外,主机也应该能够使用自己的IP地址与任何Pod通信,而无需任何地址转换。

Kubernetes不提供任何默认的网络实现,而是仅定义模型,并由其他工具来实现。如今有很多实现,Flannel是其中之一,也是最简单的之一。在以下各节中,我将解释Flannel的UDP模式实现。

The Overlay Network

Flannel是由CoreOS创建的,用于Kubernetes网络,也可以用作其他目的的通用软件定义网络解决方案。

为了满足kubernetes的网络要求,flannel的想法很简单:创建另一个在主机网络之上运行的扁平网络,这就是所谓的覆盖网络overlay network。在此覆盖网络中,所有容器(Pod)将被分配一个IP地址,它们通过直接调用彼此的IP地址来相互通信。

为了帮助解释,我在AWS上使用了一个小型的测试kubernetes集群,该集群中有3个Kubernetes节点。网络如下所示:

flannel network

此群集中有三个网络:

AWS VPC网络:所有实例都在一个VPC子网中172.20.32.0/19。它们已经在此范围内分配了ip地址,所有主机都可以彼此连接,因为它们位于同一LAN中。

Flannel overlay network:flannel创建了另一个网络100.96.0.0/16,它是一个更大的网络,可以容纳65536个地址,并且遍及所有kubernetes节点,将在此范围内为每个Pod分配一个地址,稍后我们将看到flannel如何实现此目的。

主机内docker网络:在每个主机内部,flannel为该主机中的所有pod分配了一个网络100.96.x.0/24,它可以容纳256地址。docker桥接接口docker0将使用此网络创建新容器。

通过这种设计,每个容器都有其自己的IP地址,都属于覆盖子网100.96.0.0/16。同一主机内的容器可以通过docker bridge网络接口Docker0相互通信,这很简单,因此在本文中我将跳过。为了在主机上与覆盖网络中的其他容器进行跨主机通信,flannel使用内核路由表和UDP封装来实现该功能,以下各节对此进行了说明。

跨主机容器通信

假设具有IP地址的节点1中的容器(我们将其称为容器1)100.96.1.2要使用IP地址连接到节点2中的容器(我们将其称为容器2)100.96.2.3,让我们看看覆盖网络如何启用数据包通过。

跨主机通信

第一个container-1使用创建一个IP数据包src: 100.96.1.2 -> dst: 100.96.2.3,该数据包将作为容器的网关进入docker0网桥。

在每个主机中,flannel运行一个名为的守护进程flanneld,它在内核的路由表中创建一些路由规则,这是节点1的路由表的样子:

admin@ip-172-20-33-102:~$ ip route
default via 172.20.32.1 dev eth0
100.96.0.0/16 dev flannel0 proto kernel scope link src 100.96.1.0
100.96.1.0/24 dev docker0 proto kernel scope link src 100.96.1.1
172.20.32.0/19 dev eth0 proto kernel scope link src 172.20.33.102

如我们所见,数据包的目标地址100.96.2.3位于更大的覆盖网络中100.96.0.0/16,因此它与第二条规则匹配,现在内核知道应该将数据包发送到flannel0

flannel0TUN是由我们的flanneld守护进程创建的TUN设备,TUN是在Linux内核中实现的软件接口,它可以在用户程序和内核之间传递原始ip数据包。它在两个方向上起作用:

  • 将IP数据包写入 flannel0设备时,该数据包将直接发送到内核,内核将根据其路由表对数据包进行路由
  • 当IP数据包到达内核,并且路由表说应该将其路由到 flannel0设备时,内核会将数据包直接发送到创建该设备的 flanneld进程,该进程是守护进程。

当内核将数据包发送到TUN设备时,它将直接进入flanneld进程,它看到目标地址为100.96.2.3,尽管从图中可以看出该地址属于在Node 2上运行的容器,但是如何flanneld知道呢?

Flannel碰巧将某些信息存储在名为etcd的键值存储服务中,如果您知道kubernetes,则不应感到惊讶。在flannel,我们可以将其视为常规键值存储。

Flannel将子网映射信息存储到etcd服务中,我们可以使用以下etcdctl命令查看它:

admin@ip-172-20-33-102:~$ etcdctl ls /coreos.com/network/subnets
/coreos.com/network/subnets/100.96.1.0-24
/coreos.com/network/subnets/100.96.2.0-24
/coreos.com/network/subnets/100.96.3.0-24
admin@ip-172-20-33-102:~$ etcdctl get /coreos.com/network/subnets/100.96.2.0-24
{"PublicIP":"172.20.54.98"}

因此,每个flanneld进程查询etcd都知道每个子网属于哪个主机,并将目标ip地址与etcd中存储的所有子网密钥进行比较。在本例中,该地址100.96.2.3将与子网匹配100.96.2.0-24,并且如我们所见,存储在此键中的值表示Node ip为172.20.54.98

现在flanneld知道了目的地址,然后将原始IP数据包包装到UDP数据包中,以其自己的主机ip作为源地址,而目标主机的IP作为目的地址。在每个主机中,该flanneld进程将侦听默认的UDP端口:8285。因此,只需要将UDP数据包的目标端口设置为8285,然后通过网络发送它。

UDP数据包到达目标主机后,内核的IP堆栈会将数据包发送到flanneld进程,因为那是用户进程在UDP端口上侦听:8285。然后flanneld将获得UDP数据包的有效负载,该数据包是由原始容器生成的原始IP数据包,只需将其写入TUN设备flannel0,然后该数据包将直接传递到内核,这就是TUN的工作方式。

与节点1相同,路由表将决定此数据包的去向,让我们看一下节点2的路由表:

admin@ip-172-20-54-98:~$ ip route
default via 172.20.32.1 dev eth0
100.96.0.0/16 dev flannel0 proto kernel scope link src 100.96.2.0
100.96.2.0/24 dev docker0 proto kernel scope link src 100.96.2.1
172.20.32.0/19 dev eth0 proto kernel scope link src 172.20.54.98

IP数据包的目标地址是100.96.2.3,内核将采用最精确的匹配,这是第三条规则。数据包将发送到docker0设备。就像docker0桥接设备一样,此主机中的所有容器都连接到该桥接器,最终目的地容器2将看到并接收到该数据包。

最终,我们的数据包完成了一种传递到目标的方式,当contianer-2将数据包发送回容器1时,反向路由将以完全相同的方式工作。这就是跨主机容器通信的工作方式。

使用Docker网络进行配置

在以上解释中,我们遗漏了一点。这就是我们如何配置docker使用较小的子网100.96.x.0/24

碰巧flanneld会将其子网信息写入主机中的文件中:

admin@ip-172-20-33-102:~$ cat /run/flannel/subnet.env
FLANNEL_NETWORK=100.96.0.0/16
FLANNEL_SUBNET=100.96.1.1/24
FLANNEL_MTU=8973
FLANNEL_IPMASQ=true

该信息将用于配置docker守护程序的选项,因此docker可以将FLANNEL_SUBNET用作其桥接网络,然后主机容器网络将起作用:

dockerd --bip = $ FLANNEL_SUBNET --mtu = $ FLANNEL_MTU

数据包复制和性能

较新版本的flannel不建议将UDP封装用于生产,它表示仅应将其用于调试和测试目的。原因之一是性能。

尽管flannel0TUN设备提供了一种通过内核获取和发送数据包的简单方法,但它会降低性能:必须将数据包从用户空间来回复制到内核空间:

封包复制

如上所述,必须从原始容器进程发送数据包,然后在用户空间和内核空间之间复制3次,这将显着增加网络开销,因此,如果可以的话,应避免在生产中使用UDP。

Flannel是kubernetes网络模型的最简单实现之一。它使用现有的Docker网络和带有守护进程的额外Tun设备进行UDP封装。我解释了核心部分的详细信息:跨主机容器通信,并简要提到了性能损失。

看完上述内容,你们掌握Flannel-UDP在kubernetes中如何工作的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

网络 数据 容器 主机 地址 内核 进程 路由 通信 设备 目标 节点 工作 子网 目的 存储 原始 信息 用户 空间 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 专业联想服务器厂家直供 常州构建智慧园区软件开发 城市大脑与网络安全 求生之路2服务器怎么升技能 服务器宣传视频具体怎么搞 delphine数据库建设 网络技术跟物联网 服务器繁忙与优化 一般游戏公司的服务器都放在哪里 相城区好服务器高质量的选择 你画我猜为啥一直连接不上服务器 淄博党建设计软件开发公司 与计算机网络技术有关的爱好 hp服务器进bios 数据库课程设计陈根才 赛季服骨镰服务器取消了么 网络安全的手抄报8开纸 亿清网络技术有限公司 电话 耗电 媒体服务器 服务器攻击流量测试 特大城市数据库 传达意识形态暨网络安全会议 嫌疑人是否入数据库 网络技术优质专业建设 数据库中创建登录用户的待遇 服务器经常自动崩溃 维拓科技互联网平台 静安区第三方软件开发专业服务 雨花区软件开发公司有哪些 青浦区参考网络技术创新服务
0