Kubernets(k8s) 网络原理二:Pod访问外网

news2024/9/28 9:33:49

上一篇文章中,我们介绍了pod与宿主机通信,并且通过network namespace模拟了通信过程。回顾整个流程,无非就涉及到两个东西,通信设备和路由规则。

本文要讲的,也离不开这两个东西,只不过需要对容器IP进行额外处理。

pod访问外网

在展开讲述之前,先明确一个问题,外网的范围是什么?

这个外网范围可大可小,可能是同一个局域网的另外一台主机,也可能是局域网外的一台网路设备或主机。

讲到这里,可能会混淆,是不是扯到了集群容器间通信,毕竟集群的容器也是分散在不同主机上的。

因此为了避免混淆,我们这里先对这些主机做两个约定

  1. 两个主机间可以通过物理网络通信。
  2. 仅能修改源主机配置

试想,当我们访问百度时,你肯定只是配置自己的主机,你会去配置百度的网关吗?

好,基于两个约定,展开本文要讨论的话题。

同样,我们还是先建模,网络拓扑图如下:

注:这里用network泛指中间的网路设备

如上图,host A和host B可以通过物理网络连接,并且为host A和host B分配了IP 196.128.1.2和196.128.2.2,并且通过CIDR地址可以看到,他们分别归宿与两个不同的网段。

同时当主机A和主机B通信时,host A先将报文将给默认网关196.128.1.1,默认网关将报文转发至network,最终该报文会被交给196.128.2.1,即host B的默认网关,然后转交给host B。

试想一下,如果主机A上有一个pod-1,其IP为10.10.1.2/24,它的报文可以发送给主机B吗?

当然可以!!!因为pod-1发送的报文的目标IP是host B的IP,这个IP是可以在network中路由的。

那为什么我们说他们之间不能通信呢?

那是因为pod-1能发送报文,但是却收不到响应报文。

那这个响应报文被谁丢了呢?

如果回答是host B的网关,那证明你的基础网络知识还是比较过关,没错这里就是被host B的默认网关把报文丢了。

我们来看看这个过程发生了什么

  1. pod-1发起IP报文,源IP为10.10.1.2,目标IP为196.128.2.2
  2. host A具备转发功能,将报文转发给自己的默认网关196.128.1.1
  3. host A默认网关将报文转发至network
  4. network最终将报文交付给196.128.2.1,即host B的默认网关
  5. host B默认网关将报文转交给host B
  6. host B协议栈处理完报文准备响应
  7. host B将IP调换,发送响应报文,此时,源IP为196.128.2.2,目标IP为10.10.1.2
  8. host B上无10.10.1.2的直接路由,于是将报文交给它的默认网关
  9. host B默认网关收到报文,查找路由信息,发现无任何匹配,丢弃该报文。

最终pod-1无法收到响应报文。

因此在整个过程中,无法发送响应报文的核心的问题是:

host B的网关以及整个network中的网络设备都不认识10.10.1.2

讲到这里,可能你已经想到办法了。

既然不认识,我们让它认识不就完了吗?

确实可以这样做,但是却存在以下两个问题

  • 你需要配置整个网络中参与路由的所有设备
  • 10.10.1.2是我们虚拟的ip,它在我们虚拟的子网10.10.1.0/24这个域内不会产生冲突,但是保不齐其他域中也存在10.10.1.2这个IP。

因为存在这个问题,所以这个方案非常复杂并且几乎不可能实现。

既然中间网络设备不让修改,那我们就只能从IP入手了.

值得庆幸的是,pod-1所在的host A的IP在整个网络中是可以路由的。

即上面流程中第8条,如果host B收到的报文的目标IP是host  A的IP不就可以了吗?

那要如何修改IP呢?答案就是NAT

NAT

顾名思义,NAT就是网络地址转换,简单理解就是一种将私网地址转成公网地址的技术。

关于NAT技术的详情,不在这篇文章的讨论范围,感兴趣的可以自行查阅

既然有了NAT,我们将刚在的网络图改造以下,可以得到:

有了上一篇文章的基础,这张图看起来应该没有压力。

整个传输过程如下:

  1. host A中pod协议栈发起报文,源IP为10.10.1.2,目的IP为196.128.2.2
  2. 报文通过veth pair到达主机协议栈
  3. host A协议栈iptables中存在规则:源地址为10.10.1.2/24的报文需要做nat
  4. host A协议栈将原始报文的源IP替换为主机的IP地址,并记录该报文被snat过
  5. host A将报文从默认网关发出(图中已忽略)
  6. 报文经过网络传输,到达host B的默认网关(图中已忽略)
  7. host B的默认网关将报文转交给host B
  8. host B协议栈处理报文
  9. host B协议栈处理报文完毕将响应报文发送给默认网关
  10. host B默认网关根据规则将报文传输给下一跳
  11. 响应报文通过网络到达host A
  12. host A协议栈发现该报文应该做dnat(过程4中存有记录)
  13. host A将目标IP还原为10.10.1.2,并转发给veth 1
  14. host A中pod协议栈收到响应报文。

其它的流程都很熟悉,我们重点看看第3,4,12。

先看4和12,这里有snat和dnat,即将源地址转换和目标地址转换(上图IP首部)。至于内核转换细节,这里不讨论。

我们再看第3条,iptable规则,是一条什么样的规则完成了这个转换呢?

要回答这个问题,必须要了解iptable的工作原理,因为在后续的文章中,例如分析K8S service时我们会用到这个iptable,所以这里也不展开详细的讲述。

我们通过一个小实验来看看是不是和我们说的一样

实验

在这个实验中,我们仍然以network  namespace代指pod

因为实验环境的主机IP已经配置了,所以下面实验中的IP可能会和上图中分配的IP对不上,不过不影响我们做整个实验

在实验中,我们用192.167.11.126代指上图中host A,用192.167.11.127代指上图中host B

首先我们在host A中创建一个network namespace,并完成相关配置工作,因为这部分在第一篇文章中已经有讲述,所以这里就不展开讲每一条命令的作用

# ip netns add pod-1

# ip link add eth0 type veth peer name veth1

# ip link set eth0 netns pod-1

# ip netns exec pod-1 ip addr add 10.10.1.10 dev eth0

# ip netns exec pod-1 ip link set dev eth0 up

# ip netns exec pod-1 ip route add 169.254.1.1 dev eth0

# ip netns exec pod-1 ip route add default via 169.254.1.1 dev eth0

# ip link set dev veth1 up 

# echo 1 > /proc/sys/net/ipv4/conf/veth1/proxy_arp

# echo 1 > /proc/sys/net/ipv4/ip_forward

此时我们尝试在pod-1中ping host B

# ip netns exec pod-1 ping -c 1 192.168.11.127
PING 192.168.11.127 (192.168.11.127) 56(84) bytes of data.

--- 192.168.11.127 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

不出意外,ping 不通。

我们在host B上抓包看看。

# tcpdump -n -i ens33 -p icmp
05:46:42.231478 IP 10.10.1.10 > 192.168.11.127: ICMP echo request, id 37196, seq 1, length 64
05:46:42.231505 IP 192.168.11.127 > 10.10.1.10: ICMP echo reply, id 37196, seq 1, length 64

可以看到host B是正确响应了报文的,和我们刚才的分析一致

此时,我们在主机上添加iptables规则

 # iptables -A POSTROUTING -t nat -s 10.10.1.0/24  -j MASQUERADE

这个规则的意思是所有来自10.10.1.0/24这个网段的IP做一次snat

配置好规则之后,这时候就可以ping通了,我们再次尝试在host B抓包

# tcpdump -n -i ens33 -p icmp
07:08:51.945389 IP 192.168.11.126 > 192.168.11.127: ICMP echo request, id 59199, seq 1, length 64
07:08:51.945405 IP 192.168.11.127 > 192.168.11.126: ICMP echo reply, id 59199, seq 1, length 64

和刚才抓包的结果对比,你会发现,源IP不再是容器IP,而是host A的IP

如果你的宿主机能访问百度,你这时候在pod-1内访问百度,也是可以的

# ip netns exec pod-1 ping -c 1 www.baidu.com
PING www.a.shifen.com (183.2.172.185) 56(84) bytes of data.
64 bytes from 183.2.172.185 (183.2.172.185): icmp_seq=1 ttl=127 time=36.2 ms

--- www.a.shifen.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 36.291/36.291/36.291/0.000 ms

总结

本文介绍了宿主内的容器,如何访问外网,严格来说,他不是容器组网的关键。因为它解决的不是两个容器相互通信,而是pod访问其他主机这个单点问题。

关于容器组网的内容,将在下一篇文章中分析。

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

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

相关文章

django高校毕业生就业推荐系统-计算机毕业设计源码26096

摘 要 当前就业市场竞争激烈,高校毕业生面临着就业难的问题,同时企业也面临招聘难、选人难的挑战。为了更好地对接高校毕业生和企业之间的需求,为毕业生提供个性化的就业求着信息,开发一套充分利用Django和Python技术实现的毕业生…

arcgis for js 如何自定义绘制仿高德导航线(自定义轨迹路线)

1、arcgis for js vue3 绘制效果图 实现 1、实现上图路线的自定义线条,先拆分线条为三个部分:较宽的暗绿色背景浅绿色背景白色箭头 2、自定义线条的symbol,使用CIMSymbol import CIMSymbol from "arcgis/core/symbols/CIMSymbol&q…

【Python教程】如何使用Jupyter Notebook

Jupyter Notebook 是一个基于 Web 的交互式计算环境,支持 Python、R、Julia 等多种编程语言。它是数据科学家、分析师和研究人员的常用工具。Jupyter Notebook 提供了一个强大的用户界面,可以通过笔记本格式进行代码编写、运行、调试、可视化和文档化。 …

DREAMLLM: SYNERGISTIC MULTIMODALCOMPREHENSION AND CREATION

发表时间:arXiv 2024年5月15日 论文链接:https://arxiv.org/pdf/2309.11499 作者单位:Xi’an Jiaotong University Motivation:本文介绍了 DREAMLLM,这是一个学习框架,首先实现了多功能多模态大型语言模型 …

Java IO.字符集,流,缓冲流 转换流 对象操作流

一.字符集 如果使用字节流 , 把文本文件中的内容读取到内存时, 可能会出现乱码 如果使用字节流 , 把中文写入文本文件中 , 也有可能会出现乱码 读取n.txt"你好" 两个汉字 字节流读中文,每次只能读一部分所以出现了乱码 字符集(Character se…

美股:Nvidia的新一代AI芯片Blackwell或因设计缺陷推迟上市

设计缺陷影响推出时间 据知情人士透露,全球领先的芯片制造商Nvidia计划推出的最新人工智能(AI)芯片Blackwell可能面临长达三个月甚至更长的推迟。这一变动可能会影响到Nvidia的多位重要客户,包括Meta、谷歌和微软等,这些客户已订购了总值数百…

Datawhale AI 夏令营 从零入门 AI for Science(AI + 经济)

1.在TASK3中虽然给出了时间序列挖掘加融合模型的方法预测price,但是并不能识别到负电价的情况。查看TASK3给出的代码的预测结果可以发现模型几乎不会预测出负数,这和实际情况是有差别的。 2.利用爬虫爬取天气信息与风电信息绘制热力图 惊人的发现price和…

【MATLAB源码】数学建模基础教程(2)--层次分析法(评价类算法)

系列文章目录在最后面,各位同仁感兴趣可以看看! 层次分析法 引言一、层次分析法的特点二、模型的建立求解过程 (1)问题的提出:实际问题的转化(2)建立层次结构模型(3)构造判断(成对比较)矩阵(4)一致性检验:三、层次分析法的优点与…

【无所从来,亦无所去】纪念去世的奶奶和外公「纪念网页」

大家好,我是DX3906 🌈 欢迎莅临我的个人主页 👈这里是我静心耕耘大前端领域、真诚分享知识与智慧的小天地!🎇 纪念 2024年 奶奶 85岁、 外公83岁。他们俩分别在今年的2月份和7月份离开了。 时光倒流,奶…

美股:巴菲特减持苹果股份

财报亮点 伯克希尔哈撒韦发布的2024年第二季度财报显示,公司营收达936.53亿美元,略高于市场预期的910.9亿美元。净利润为303.48亿美元,其中投资收益占据一大比例,较去年同期的359.12亿美元有所下降,但远超市场预期的17…

JNPF全新V5.0版本!重磅升级——其他升级优化篇

尊敬的JNPF用户们: 我们非常高兴地宣布,经过团队数月的辛勤努力和不断的技术创新,JNPF快速开发平台终于迎来了里程碑式的全新升级——V5.0版本!这一版本的更新发布,不仅代表着我们技术实力的进一步提升,是…

Golang死锁vs操作系统死锁

目录 一、死锁 二、Golang死锁场景 2.1 重复上锁 2.2 不会减少的 WaitGroup 2.3 空select 2.4 channel 一、死锁 1.golang中死锁的触发条件: 死锁是当 Goroutine 被阻塞而无法解除阻塞时产生的一种状态。 2.操作系统死锁: 发生死锁时,线…

如何在2024年成为PDF合并文件高手?试试这3款软件!

在这个数字化的年代,PDF文件早就成了我们工作学习时的老朋友了。不过,要是碰上一堆PDF文件要合并,是不是觉得挺头疼的?别急,今天我们就来聊聊2024年怎么变成合并PDF的大佬,还给你推荐三款特别实用的软件&am…

【从零开始一步步学习VSOA开发】运行hellovsoa

运行hellovsoa 和所有编程技术的首个程序一样,我们先创建、编译、部署、运行一个最简单的示例程序: hellovsoa。 创建 base 工程 需要先创建一个 workspace 工作目录,然后在 workspace 里先新建 base 工程。 打开 RealEvo-IDE&#xff0c…

BPM(业务流程管理):提升企业效率的关键

在现代企业中,业务流程管理(BPM)已成为提升效率和优化运营的关键工具。随着企业环境的不断变化和竞争的加剧,越来越多的组织开始关注如何通过有效的BPM实践来提升业务表现。本文将探讨BPM的基本概念、实施策略以及如何通过BPM实现…

Java并发中的死锁四大条件与避免策略

Java并发中的死锁四大条件与避免策略 1、死锁是啥?2、死锁的四大条件3、避免死锁的策略 💖The Begin💖点点关注,收藏不迷路💖 1、死锁是啥? 死锁就像是几个朋友在聚会时,每个人都想和别人手里的…

你的财富正在被一个叫做通货膨胀的怪兽给吞噬掉,你却浑然不觉。

据统计,2024年全球总体通货膨胀率预计达到5.8%,这意味着:你的财富正在被一个叫做通货膨胀的怪兽给吞噬掉,你却浑然不觉。 数据来源:国际货币基金组织 如何跑赢通货膨胀? 家庭财富的积累速度,要…

[Git][分支管理][下]详细讲解

目录 1.合并冲突2.分支管理策略3.分支策略1.基本原则2.bug分支3.删除临时分支 1.合并冲突 在实际分⽀合并的时候,有时候可能会遇到代码冲突的问题,例如: dev分支在写一部分代码,而master分支也没闲着,也在写着同一份代…

MATLAB指针读数识别系统

前言 ①经过在工厂的实地测试,图像采集与传输装置可以正常工作,电脑端可以接收到清晰的图像,并且整个系统具有一定的的抗干扰的能力,在嘈杂的环境中亦可以实现其功能。 ②通过matlab可实现图片的预处理以及指针识别读数识别&…

MySQL笔记(三):修改表

##注:需要在cmd管理员命令行链接mysql再打开sqlyog 一、基本介绍 二、CRUD([create][read][update][delete],增删改查)语句 1、insert语句 (添加数据) insert into table_name(第一项,第二项&#xff0…