k8s的pod和svc相互访问时网络链路解析

k8s的pod和svc相互访问时网络链路解析

  • 1. k8s环境中pod相互访问
    • 1.1. k8s中pod相互访问的整体流程
    • 1.2. k8s的相同机器的不同pod相互访问
    • 1.3. k8s的不同机器的不同pod相互访问
  • 3. k8s访问svc
    • 3.1 nat操作
    • 3.2 流量进入到后端pod
  • 4. 疑问和思考
    • 4.1 访问pod相互访问为什么不用做nat?
    • 4.2 访问svc时为什么需要做nat?
  • 5. 参考文档

在常用的k8s环境中,通常会面临同机器pod的相互访问、跨机器之间的pod访问以及通过svc访问相互,这几种模式下,k8s底层网络的访问规则不同。本文希望针对这几种场景下的流量访问链路和访问规则,从而探索k8s针对网络层面的设计逻辑。k8s层面svc访问的详细规则可以参考k8s的svc流量通过iptables和ipvs转发到pod的流程解析


1. k8s环境中pod相互访问

1.1. k8s中pod相互访问的整体流程

k8s内部pod相互之间的访问架构如下,我们使用一个相互新的网络架构,进行整体网络解析。
在这里插入图片描述

这个架构使用的cilium进行作为网络插件提供网络服务。在基于 vxlan 的 overlay 组网情况下,主机上的网络发生了以下变化:在主机的 root 命名空间,新增了如下图所示的四个虚拟网络接口

  • cilium_vxlan 主要是对数据包进行 vxlan 封装和解封装操作;
  • cilium_net 和 cilium_host 是一对 veth-pair,cilium_host 作为该节点所管理的 Cluster IP 子网的网关
  • lxc_health,用于节点之间的健康检测。

在每个主机上,可以进入 Cilium Agent,能够记录pod-host之间的网络关系,能够通过pod找到对应的机器host,并为对应的机器创建隧道列表。 比如进入主机 easyk8s1 上的 Cilium Agent,运行 cilium bpf tunnel list,可以看到

  • 其为集群中的另一台主机 easyk8s2 上的虚拟网络 10.244.1.0 创建了一个隧道
  • 同样在 easyk8s1 上也有一条这样的隧道配置。
    在这里插入图片描述

每台服务器也将为每台node、pod、svc创建相关的路由表,当相关流量到达cilium_host后,会通过进一步访问的目的地址查找和匹配的路由表,从而决定下一跳的访问流量。
在这里插入图片描述

k8s之间的pod访问就是通过veth-pair、路由表从而决定整体的转发策略。

1.2. k8s的相同机器的不同pod相互访问

以 busybox1 ping busybox2 为例

在这里插入图片描述
busybox1 的 IP 地址为 10.244.2.96/32,busybox2 的 IP 地址为 10.244.2.21/32,掩码均为 32 位。

  1. 当 busybox1 准备发送 ping 包时,数据包逐层封装,网络层 (3 层) 源 IP 为 10.244.2.96/32,目的 IP 为 10.244.2.21/32,其通过路由表(注:每个 Node 上所有的容器路由表一样)查询到下一跳为 10.244.2.35

  2. 数据链路层 (2 层) 源 MAC 地址为 0a:c5:89:f9:04:84,目的 MAC 地址因初始状态下 Pod 内的 ARP 表为空,busybox1 需发送 ARP 请求目的 MAC 地址

    [root@easyk8s1 ~]# kubectl  exec -ti busybox1 -- route -n 
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    0.0.0.0         10.244.2.35     0.0.0.0         UG    0      0        0 eth0
    10.244.2.35     0.0.0.0         255.255.255.255 UH    0      0        0 eth0
    [root@easyk8s1 ~]# kubectl  exec -ti busybox1 -- arp
    

    如上busybox1中的路由表,busybox1出去的流量目标地址是10.244.2.35 ,会通过eth0端口出来流量。busybox1的 eth0 网卡是一对 veth-pair 设备,另一端 ifindex 为 16 的 lxca60338c921d9 在 Node 节点 easyk8s1 上,从而busybox1的流量就会转发到easyk8s1上。lxca60338c921d9 绑定在cilium_host(类似网桥),可以根据路由表进一步决定流量的去向。

  3. lxca60338c921d9 网卡收到 ARP 请求包,内核处理 ARP 请求,发现地址就在本机,但是地址所属网卡 cilium_host 为 NOARP 状态,根据 Cilium Agent 挂载的 eBPF 程序实现,将使用接收 ARP 请求包的 lxca60338c921d9 网卡的 MAC 地址进行响应。(分别在网卡 cilium_host 和 lxca60338c921d9 抓取 MAC 报文,后者收到报文。报文中 MAC 回包的 mac 地址是 lxca60338c921d9 的 MAC 地址 e2:d8:51:8b:44:d4)

    [root@easyk8s1 ~]# ip addr show
    ...
    6: cilium_net@cilium_host: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000link/ether d6:99:91:04:02:a5 brd ff:ff:ff:ff:ff:ffinet6 fe80::d499:91ff:fe04:2a5/64 scope link valid_lft forever preferred_lft forever
    7: cilium_host@cilium_net: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000link/ether 6e:5e:1e:d7:c2:07 brd ff:ff:ff:ff:ff:ffinet 10.244.2.35/32 scope link cilium_hostvalid_lft forever preferred_lft foreverinet6 fe80::6c5e:1eff:fed7:c207/64 scope link valid_lft forever preferred_lft forever[root@easyk8s1 ~]# tcpdump -nnn -vvv -i lxca60338c921d9 arp 
    tcpdump: listening on lxca60338c921d9, link-type EN10MB (Ethernet), capture size 262144 bytes
    15:29:03.640538 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.244.2.35 tell 10.244.2.96, length 28
    15:29:03.640654 ARP, Ethernet (len 6), IPv4 (len 4), Reply 10.244.2.35 is-at e2:d8:51:8b:44:d4, length 28
    
  4. busybox1 收到 ARP 应答后,获取到目的 MAC 地址并缓存,然后组装 ICMP REQUEST 包并发送

    [root@easyk8s1 ~]# kubectl  exec -ti busybox1 -- ip neigh
    10.244.2.35 dev eth0 lladdr e2:d8:51:8b:44:d4 used 0/0/0 probes 1 STALE
    
  5. lxca60338c921d9 网卡收到 ICMP REQUEST 报文,解封装,发现二层目的 MAC 地址是自身,继续解分装,发现三层目的 IP 地址是 10.244.2.21/32,查询路由表(所有主机的路由表 podsubnet 网段内的路由都指向 cilium_host),路由表指向cilium_host(cilium_host 是 eBPF 埋钩子的地方,eBPF 进行 ingress 方向的转发逻辑,包括 prefilter、解密、L3/L4 负载均衡、L7 Policy 等)
    在这里插入图片描述

  6. cilium_host进一步通过的Cilium Agent cilium bpf endpoint list 的相关转发规则,重新对数据包进行封装,发送给 busybox2 容器的 veth-pair 接口 lxc021c0c8b5d94

    [root@easyk8s1 ~]# kubectl exec -ti cilium-wtdbp -n kube-system -- cilium bpf endpoint list
    IP ADDRESS       LOCAL ENDPOINT INFO
    10.244.2.21:0    id=6     flags=0x0000 ifindex=18  mac=2E:5A:9A:9E:01:00 nodemac=36:33:68:68:1F:DD   
    10.244.2.96:0    id=890   flags=0x0000 ifindex=16  mac=0A:C5:89:F9:04:84 nodemac=E2:D8:51:8B:44:D4   
    10.211.55.10:0   (localhost)                                                                         
    10.211.55.7:0    (localhost)                                                                         
    10.244.2.35:0    (localhost)                                                                         
    10.244.2.172:0   id=109   flags=0x0000 ifindex=10  mac=22:4F:87:F3:0C:94 nodemac=C6:F5:CD:16:6D:E2
  7. busybox2 收到 ICMP REQUEST 包并处理,回应 ICMP REPLY 包,回包过程与上面过程相反,此处不再赘述

1.3. k8s的不同机器的不同pod相互访问

在这里插入图片描述
整体流程跟相同节点的不同pod之间访问类似,前面5个步骤相同。从第6步 开始,有差异

  1. cilium_host根据隧道转发规则去往 10.244.1.0/24 网段的流量将发送给 10.211.55.8,也就是 easyk8s2 节点。于是将 ICMP REQUEST 包重新封装发送给 easyk8s1 的 cilium_vxlan 网卡。cilium_vxlan 网卡会进行 VXLAN 封装(Cilium 默认使用 UDP 8472 端口),通过 underlay 层路由,由物理网卡 eth0 发送给 10.211.55.8,即 easyk8s2 节点

    [root@easyk8s1 ~]# kubectl exec -ti cilium-wtdbp -n kube-system -- cilium bpf tunnel list
    TUNNEL         VALUE
    10.244.1.0:0   10.211.55.8:0
    
  2. asyk8s2 节点的 eth0 网卡收到报文以后,发现是 VXLAN 报文,便发给 cilium_vxlan 进行解封装,并根据内部目的地址路由。
    在这里插入图片描述

  3. 路由表同样指向 easyk8s2 节点的 cilium_host 网卡,eBPF 进行 ingress 方向的转发逻辑(包括 prefilter、解密、L3/L4 负载均衡、L7 Policy 等)。进入 easyk8s2 节点的 Cilium Agent 通过 cilium bpf endpoint list 可以查询其转发规则。根据规则将数据包发送给 busybox3 容器的 veth-pair 接口 lxcdf85c99387b7

    [root@easyk8s1 ~]# kubectl exec -ti cilium-l2wpw -n kube-system -- cilium bpf endpoint list            
    IP ADDRESS       LOCAL ENDPOINT INFO
    10.244.1.2:0     (localhost)                                                                         
    10.211.55.8:0    (localhost)                                                                         
    10.244.1.253:0   id=959   flags=0x0000 ifindex=10  mac=EA:1F:11:A8:CF:0D nodemac=DE:44:26:5F:50:CC   
    10.244.1.223:0   id=1419  flags=0x0000 ifindex=22  mac=C2:11:E1:7D:27:30 nodemac=92:C7:C1:10:8D:7C   
    10.244.1.152:0   id=3207  flags=0x0000 ifindex=20  mac=62:1B:E4:C9:4D:44 nodemac=EA:60:B5:7D:42:32
    
  4. busybox3 收到 ICMP REQUEST 包并处理,回应 ICMP REPLY 包,回包过程与上面过程相反,此处不再赘述

从如上流程可以看出,pod之间的相互访问主要依赖 eth-pair、cilium_host(对应其他网络插件的网桥)、以及路由表,进行路由转发。并不需要针对pod进行nat操作,因此也不涉及iptables等相关规则。

3. k8s访问svc

3.1 nat操作

客户端访问(k8s的pod或者node)访问svc时,虽然实际上是访问svc后端的pod(实际的服务提供方),但是由于svc的存在,使得能够完全屏蔽svc后端的相关配置。对于客户端而言,并不感知svc后端的相关服务情况。

如果客户端正好是k8s的pod或者node时,当流量从node的网卡出包时,会被iptables进行nat操作,将客户端ip进行snat成node的ip。而当流量从svc返回客户端时,会进行逆向转换将node进行dnat解析成客户端ip。

该nat操作时通过iptables KUBE-MARK-MASQ规则实现的,具体的实现方式可以参考 k8s的svc流量通过iptables和ipvs转发到pod的流程解析

每台k8s服务器都会配置KUBE-MARK-MASQ相关规则,因此当pod流量出服务器网卡时,就会自动完成转换。
在这里插入图片描述

3.2 流量进入到后端pod

svc能够通过负载均衡配置,将相关的流量分权重,转换到后端pod,具体可以参考 k8s的svc流量通过iptables和ipvs转发到pod的流程解析

当访问流量完成nat,进入到目标pod后,相关的流程跟pod访问流程类似,不在继续复述

4. 疑问和思考

4.1 访问pod相互访问为什么不用做nat?

不需要进行nat。

因为pod到pod时相同的网段,每个pod都被分配ip,并且在k8s环境中,每个node有对应的pod cidrs,因此针对每个pod而言,能够清晰的构建每个podip对应的转发路由表,因此不需要进行nat。网访问客户端的pod出流量进入到网桥(cilium_host)后,能够通过本地的路由表查找到目标pod所在的下一条地址。只需要做简单封装后,就能够进行流量之间的相互访问。

4.2 访问svc时为什么需要做nat?

在 Kubernetes 中,Service 是一种抽象层,用于将一组 Pod 暴露给其他 Pod 或外部网络。当一个外部客户端尝试访问 Service 时,请求首先到达集群的节点。这时候,由于 Service 的 IP 地址是虚拟的,它不属于任何节点的 IP 地址范围,因此node节点无法直接识别该请求应该转发给哪个具体的 Pod

为了解决这个问题,Kubernetes 使用了网络地址转换(Network Address Translation,NAT)技术。当一个请求到达节点时,节点会使用 NAT 将请求的目标 IP 地址转换为 Service 对应 Pod 的 IP 地址,然后将请求转发给该 Pod。

通过使用 NAT,Kubernetes 可以将 Service 的虚拟 IP 地址与实际运行的 Pod 关联起来,从而实现请求的转发和负载均衡。同时,这也使得 Service 的 IP 地址可以根据需要动态变化,而不会影响到外部客户端的访问。

5. 参考文档

暂无

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/740413.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

保研复习数据结构记(9)--基数排序

基数排序的过程&#xff1f;首先设置r个&#xff08;r&#xff1a;每个关键字位可以对应多少取值&#xff09;空队列&#xff0c;&#xff0c;按照各个关键字位权重递增的次序&#xff08;个、十、百&#xff09;&#xff0c;将d个元素&#xff08;关键字可以被拆分成d个部分&a…

金枪鱼群优化算法TSO优化BiLSTM-ATTENTION实现风力发电功率预测(matlab)

金枪鱼群优化算法TSO优化BiLSTM-ATTENTION实现风力发电功率预测&#xff08;matlab&#xff09; TSO-BiLSTM-Attention金枪鱼群算法优化长短期记忆神经网络结合注意力机制的数据回归预测 Matlab语言。 金枪鱼群优化算法&#xff08;Tuna Swarm Optimization&#xff0c;TSO)是一…

生成式人工智能服务安全基本要求实务解析

本文尝试明晰《基本要求》的出台背景与实践定位&#xff0c;梳理《基本要求》所涉的各类安全要求&#xff0c;以便为相关企业遵循执行《基本要求》提供抓手。 引言 自2022年初以来&#xff0c;我国陆续发布算法推荐、深度合成与生成式人工智能服务相关的规范文件&#xff0c;…

丘一丘正则表达式

正则表达式(regular expression,regex,RE) 正则表达式是一种用来简洁表达一组字符串的表达式正则表达式是一种通用的字符串表达框架正则表达式是一种针对字符串表达“简洁”和“特征”思想的工具正则表达式可以用来判断某字符串的特征归属 正则表达式常用操作符 操作符说明实…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Search)

搜索框组件&#xff0c;适用于浏览器的搜索内容输入框等应用场景。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口 Search(options?: { value?: string, placeholder?: Reso…

混合云构建-VPN打通阿里云和Azure云

要在阿里云和Azure云之间通过VPN打通网络,您需要在两边分别设置VPN网关,并配置相应的连接和路由规则以确保两个云环境之间的网络流量可以互通。以下是一个基本的步骤指南: 为了更具体地说明如何在阿里云和Azure之间通过VPN打通网络,我们将通过一个简化的示例来演示整个过程…

ArcGIS JSAPI 学习教程 - ArcGIS Maps SDK for JavaScript 不同版本4.8-4.28(最新版)离线部署

ArcGIS JSAPI 学习教程 - ArcGIS Maps SDK for JavaScript 不同版本4.8-4.28&#xff08;最新版&#xff09;SDK离线部署 测试资源4.18 以及之前版本4.19 以及之后版本 接触一段时间 ArcGIS JSAPI 之后&#xff0c;整体感觉还好&#xff0c;后来需要解决不同版本问题&#xff0…

redis中通用命令以及key过期策略

通用命令 exists 判断某个key是否存在。 exists key时间复杂度&#xff1a;O(1) 返回值&#xff1a;key 存在的个数。 del 删除指定的 key&#xff0c;可以一次删除一个或者多个。 del key时间复杂度&#xff1a;O(1) 返回值&#xff1a;删除掉的 key 的个数。 expire…

数据结构·复杂度

目录 1 时间复杂度 2 大O渐进表示法 举例子&#xff08;计算时间复杂度为多少&#xff09; 3 空间复杂度 前言&#xff1a;复杂度分为时间复杂度和空间复杂度&#xff0c;两者是不同维度的&#xff0c;所以比较不会放在一起比较&#xff0c;但是时间复杂度和空间复杂度是用…

汉服|高校汉服租赁网站|基于Springboot的高校汉服租赁网站设计与实现(源码+数据库+文档)

高校汉服租赁网站目录 目录 基于Springboot的高校汉服租赁网站设计与实现 一、前言 二、系统设计 三、系统功能设计 1、汉服信息管理 2、汉服租赁管理 3、公告管理 4、公告类型管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选…

SQL Server错误:15404

执行维护计划失败&#xff0c;提示SQL Server Error 15404 无法获取有关... 异常如下图&#xff1a; 原因&#xff1a;数据库用户名与计算机名称不一致 解决办法&#xff1a;1.重名称数据库用户名 将前缀改成计算机名 2.重启SQL Server代理

【数据挖掘】实验1:R入门(内含详细R和RStudio安装教程)

实验1&#xff1a;R入门 一&#xff1a;实验目的与要求 1&#xff1a;根据上课PPT内容&#xff0c;掌握课堂知识并进行代码练习操作&#xff0c;提供练习过程和结果。 2&#xff1a;可COPY代码运行结果直接提交&#xff0c;如涉及到输出图等可截图。 二&#xff1a;实验内容 …

免费搭建导航网站教程带免费空间域名源码

使用免费空间和免费域名免费搭建一个导航网站 手把手视频教程 https://pan.xunlei.com/s/VNsoMehs7RCjz3IClV6h2vNMA1?pwdq596#

中国首个基于区块链的分布式算力网络上线

随着美国人工智能公司OpenAI近期发布的Sora视频模型&#xff0c;全球对高性能算力的需求突破了历史新高。Sora的创新在于它能够以超长生成时间、多角度镜头捕捉&#xff0c;理解物理世界的能力&#xff0c;这不仅是技术的一大突破&#xff0c;更是对算力需求的一大挑战。在这样…

使用npm版本管理工具解决npm 的EACCES permissions errors when installing packages globally错误

EACCES错误通常表示“权限被拒绝”&#xff0c;意味着您没有足够的权限来执行某个操作。在计算机领域&#xff0c;尤其是在文件系统和程序安装中&#xff0c;这个错误很常见。以下是可能导致EACCES错误的原因以及相应的解决方法&#xff1a; 文件系统权限&#xff1a;当您尝试…

【开源】SpringBoot框架开发智慧社区业务综合平台

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 业务类型模块2.2 基础业务模块2.3 预约业务模块2.4 反馈管理模块2.5 社区新闻模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 业务类型表3.2.2 基础业务表3.2.3 预约业务表3.2.4 反馈表3.2.5 社区新闻表 四、系统展…

【机器学习300问】34、决策树对于数值型特征如果确定阈值?

还是用之前的猫狗二分类任务举例&#xff08;这个例子出现在【机器学习300问】第33问中&#xff09;&#xff0c;我们新增一个数值型特征&#xff08;体重&#xff09;&#xff0c;下表是数据集的详情。如果想了解更多决策树的知识可以看看我之前的两篇文章&#xff1a; 【机器…

按键+串口发送实验

摸鱼记录 Day_15 &#xff5e;(&#xffe3;▽&#xffe3;&#xff5e;)(&#xff5e;&#xffe3;▽&#xffe3;)&#xff5e; review 前边已经学习了&#xff1a; 串口发送Vivado 串口通信(UART)------串口发送-CSDN博客 按键基于状态机的按键消抖实现-CSDN博客 1. …

STM32外设分类--学习笔记

简介: 本文在于根据自己的理解&#xff0c;将stm32f103外设按照功能分个类别&#xff0c;便于记忆。下面的几张图一定要熟悉&#xff0c;后期编写代码时能够快速找到想要的功能和对应的引脚。 我使用的工具链是&#xff1a;使用CubeMX完成keil5工程搭建和引脚初始化功能,然后用…

Grafana

介绍 官网&#xff1a;https://grafana.com/ Grafana 是一个开源的指标分析和可视化工具&#xff0c;它被广泛用于展示和监控云基础设施和应用程序的实时数据。Grafana 提供了一个强大且易于使用的界面&#xff0c;允许用户创建各种图表、图形和仪表盘&#xff0c;以直观地展…