iptables添加端口映射,k8s主机查询不到端口但能访问。

news/2024/5/9 17:18:12/文章来源:https://blog.csdn.net/lswzw/article/details/137117600

研究原因:k8s内一台主机使用命令查询没有80端口。但通过浏览器访问又能访问到服务。

查询了资料是使用了hostport方式暴露pod端口。cni调用iptables增加了DNAT规则。访问时流量先经过iptables直接被NAT到具体服务去了。

链接: K8s罪魁祸首之"HostPort劫持了我的流量"


疑问hostport方式为iptables转发,docker 默认也用iptables转发。为什么docker能在主机上看到端口。

解惑: 这里就又牵扯到docker的网络实现。docker会有一个 docker-proxy来管理docker的网络。当使用 -p时 docker-proxy会默认绑定主机0.0.0.0:port。 还会创建iptables规则。这里主机上看到的端口是docker-proxy生成的。
这使得请求就有多种可能性。下面是可能性截图。

在这里插入图片描述
详细链接: docker-proxy存在合理性分析

做个小实验

# 查看默认的iptables规则
[root@localhost ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCALChain INPUT (policy ACCEPT)
target     prot opt source               destination         Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCALChain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0           Chain DOCKER (2 references)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0      #启动一个容器
[root@localhost ~]# docker run -d -p 8080:80 nginx
2ba5b9d4cb5407c96e0b999eee0c01afc4ce6e5d379cc1bd9c1614743e0ea48e
[root@localhost ~]# ss -ntl            
State      Recv-Q Send-Q                        Local Address:Port                                       Peer Address:Port              
LISTEN     0      128                                       *:8080                                                  *:*                                                               [::]:*                 
# 外部电脑请求, 这时能访问通。
xxx@xxx ~> curl 192.168.44.44:8080 -I
HTTP/1.1 200 OK
Server: nginx/1.25.4
Date: Thu, 28 Mar 2024 09:21:37 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Wed, 14 Feb 2024 16:03:00 GMT
Connection: keep-alive
ETag: "65cce434-267"
Accept-Ranges: bytes
# 查看现在的iptables规则
[root@localhost ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCALChain INPUT (policy ACCEPT)
target     prot opt source               destination         Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCALChain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0           
MASQUERADE  tcp  --  172.17.0.2           172.17.0.2           tcp dpt:80Chain DOCKER (2 references)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 to:172.17.0.2:80# 多了2条规则  POSTROUTING 2    DOCKER  2
# 这时外部请求直接使用的iptables规则DNAT到服务。
# 手工删除上面新增规则
[root@localhost ~]# iptables -t nat -D DOCKER 2
[root@localhost ~]# iptables -t nat -D POSTROUTING 2

这时外部访问还是能通。 访问的就是docker-proxy绑定的8080端口。

另类用法

链接: 对已经运行的容器映射主机端口发布服务
验证实验:

[root@localhost ~]# docker run -d nginx
fe78d8a1ba1c5477a0ff89e5627812e215286a242cc06bb18ec651c49c9afa0c
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
fe78d8a1ba1c   nginx     "/docker-entrypoint.…"   3 seconds ago   Up 2 seconds   80/tcp    competent_napier
[root@localhost ~]# docker inspect fe7 | grep IPAddress  "SecondaryIPAddresses": null,"IPAddress": "172.17.0.2","IPAddress": "172.17.0.2",
[root@localhost ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCALChain INPUT (policy ACCEPT)
target     prot opt source               destination         Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCALChain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0           Chain DOCKER (2 references)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           

现在启动了一个容器,容器的内网ip为172.17.0.2。iptables没有新增加规则。
手工添加一个DNAT规则:

[root@localhost ~]# iptables -t nat -A  DOCKER -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80
[root@localhost ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCALChain INPUT (policy ACCEPT)
target     prot opt source               destination         Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCALChain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0           Chain DOCKER (2 references)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 to:172.17.0.2:80

现在从外部访问服务:

xxx@xxx ~> curl 192.168.44.44:8080 -I

发现访问不通一直接卡着。失败了?别急。这里就又牵扯一个网络转发内核
net.ipv4.ip_forward = 1
这个网络转发默认是不开启的。

[root@localhost ~]# echo net.ipv4.ip_forward = 1 >> /etc/sysctl.conf       
[root@localhost ~]# sysctl -p
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv4.ip_forward = 1

是不是觉得已经可以访问到了? 从外部主机验证下就知道了。还是不通?????????
单纯的sysctl -p加载对forward不生效。重启下机器就好了。 reboot

重启后把容器启动。添加规则。

[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                      PORTS     NAMES
fe78d8a1ba1c   nginx     "/docker-entrypoint.…"   10 minutes ago   Exited (0) 17 seconds ago             competent_napier
[root@localhost ~]# docker start fe7
fe7
[root@localhost ~]# iptables -t nat -A  DOCKER -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80
[root@localhost ~]# ss -ntl
State      Recv-Q Send-Q                        Local Address:Port                                       Peer Address:Port              
LISTEN     0      128                                       *:22                                                    *:*                  
LISTEN     0      128                                    [::]:22                                                 [::]:*                  
[root@localhost ~]# iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N DOCKER
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A DOCKER -i docker0 -j RETURN
-A DOCKER -p tcp -m tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80

现在再从外部电脑就能通过8080端口访问到服务了。
现在用ss命令是查不到端口的。
iptables规则里面就只用多一条DNAT。
iptables规则只是临时的,重启了服务器就会失效。

灵魂拷问:刚刚第2个小实验结论是对的吗?

内核都没有开网络转发。之前的请求应该都是通过docker-proxy绑定的端口访问的。 这就是docker-proxy绑定端口存在的意义。

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

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

相关文章

单例模式如何保证实例的唯一性

前言 什么是单例模式 指一个类只有一个实例,且该类能自行创建这个实例的一种创建型设计模式。使用目的:确保在整个系统中只能出现类的一个实例,即一个类只有一个对象。对于频繁使用的对象,“忽略”创建时的开销。特点&#xff1a…

快速上手Spring Cloud 七:事件驱动架构与Spring Cloud

快速上手Spring Cloud 一:Spring Cloud 简介 快速上手Spring Cloud 二:核心组件解析 快速上手Spring Cloud 三:API网关深入探索与实战应用 快速上手Spring Cloud 四:微服务治理与安全 快速上手Spring Cloud 五:Spring …

基于PaddleNLP的深度学习对文本自动添加标点符号(二)

前言 基于PaddleNLP的深度学习对文本自动添加标点符号的源码版来了,本篇文章主要讲解如何文本自动添加标点符号的原理和相关训练方法,前一篇文章讲解的是使用paddlepaddle已经训练好的一些模型,在一些简单场景下可以通过这些模型进行预测&…

【Unity】调整Player Settings的Resolution设置无效

【背景】 Build时修改了Player Settings下的Resolution设置,但是再次Building时仍然不生效。 【分析】 明显是沿用了之前的分辨率设定,所以盲猜解决办法是Build相关的缓存文件,或者修改打包名称。 【解决】 实测修改版本号无效&#xf…

指针数组的有趣程序【C语言】

文章目录 指针数组的有趣程序指针数组是什么?指针数组的魅力指针数组的应用示例:命令行计算器有趣的颜色打印 结语 指针数组的有趣程序 在C语言的世界里,指针是一种强大的工具,它不仅能够指向变量,还能指向数组&#…

[机缘参悟-162/管理者与领导者-151] :受害者心态与受害者思维模式,如何克服受害者思维模式,管理者如何管理这种思维模式的人?

目录 一、受害者心态概述 1.1 什么是受害者心态 1.2 受害者心态的表现形式 1.3 受害者心态在职场上的表现 1.4 受害者思维模式 1.5 受害者心态的危害 二、受害者心态的成因 2.1 概述 2.2 神经网络与受害者心态 三、如何克服受害者心态 3.1 概述 3.2 职场 3.3 家庭…

verilog 从入门到看得懂---verilog 的基本语法各种语句

本篇文章主要介绍verilog里面常用的语句, 包括条件语句、循环语句块语句和生成语句。出了块语句和生成语句,其他的基本和c语言或者m语言一致。 1,if 语句,在需要判断逻辑的时候可以使用if语句,如 从输入a,…

《QT实用小工具·二》图片文字转base64编码

1、概述 源码放在文章末尾 base64编码转换类 图片转base64字符串。base64字符串转图片。字符转base64字符串。base64字符串转字符。后期增加数据压缩。Qt6对base64编码转换进行了重写效率提升至少200%。 下面是demo演示: 项目部分代码如下所示: #ifn…

解决npm init vue@latest证书过期问题:npm ERR! code CERT_HAS_EXPIRED

目录 一. 问题背景 二. 错误信息 三. 解决方案 3.1 临时解决办法 3.2 安全性考量 一. 问题背景 我在试图创建一个新的Vue.js项目时遇到了一个问题:npm init vuelatest命令出现了证书过期的错误。不过这是一个常见的问题,解决起来也简单。 二. 错误…

【aws】架构图工具推荐

碎碎念 以前以为日本冰箱论是个梗,结果居然是真的。用光盘传真其实还能理解(毕竟我也喜欢电子古董2333),但是画架构图居然用的是excel+截图!啊苍天呐,然后看到隔壁工位用excel画web原型又感觉释…

Python 从0开始 一步步基于Django创建项目(13)将数据关联到用户

在city_infos应用程序中,每个城市信息条目是关联到城市的,所以只需要将城市条目关联到用户即可。 将数据关联到用户,就是把‘顶层’数据关联到用户。 设计思路: 1、修改顶层数据模型,向其中添加‘用户’属性 2、根…

kubernetes K8s的监控系统Prometheus升级Grafana,来一个酷炫的Node监控界面(二)

上一篇文章《kubernetes K8s的监控系统Prometheus安装使用(一)》中使用的监控界面总感觉监控的节点数据太少,不能快算精准的判断出数据节点运行的状况。 今天我找一款非常酷炫的多维度数据监控界面,能够非常有把握的了解到各节点的数据,以及运…

「DevExpress中文教程」如何将DevExtreme JS HTML编辑器集成到WinForms应用

在本文中我们将演示一个混合实现:如何将web UI工具集成到WinForms桌面应用程序中。具体来说,我们将把DevExtreme JavaScript WYSIWYG HTML编辑器(作为DevExtreme UI组件套件的一部分发布的组件)集成到Windows Forms应用程序中。 获取DevExtreme v23.2正式…

数据分析之Power BI

POWER QUERY 获取清洗 POWER PIVOT建模分析 如何加载power pivot 文件-选项-加载项-com加载项-转到 POWER VIEW 可视呈现 如何加载power view 文件-选项-自定义功能区-不在功能区中的命令-新建组-power view-添加-确定 POWER MAP可视地图

2.4 比较检验 机器学习

目录 常见比较检验方法 总述 2.4.1 假设检验 2.4.2 交叉验证T检验 2.4.3 McNemar 检验 接我们的上一篇《性能度量》,那么我们在某种度量下取得评估结果后,是否可以直接比较以评判优劣呢?实际上是不可以的。因为我们第一,测试…

uniapp h5 touch事件踩坑记录

场景:悬浮球功能 当我给悬浮球设置了 position: fixed; 然后监听悬浮球的touch事件,从事件对象中拿到clientY和clientX赋值给悬浮球的left和top属性。当直接赋值后效果应该是这样子: 注意鼠标相对悬浮球的位置,应该就是左上角&a…

在 Windows 11 上安装 MongoDB

MongoDB 是一个流行的 NoSQL 数据库,它提供了灵活的数据存储方案,而 MongoDB Compass 则是一个可视化管理工具,可以更轻松地与 MongoDB 数据库交互和管理。在本文中,我们将介绍如何在 Windows 11 上安装 MongoDB,并配置…

Radio Silence for mac 好用的防火墙软件

Radio Silence for Mac是一款功能强大的网络防火墙软件,专为Mac用户设计,旨在保护用户的隐私和网络安全。它具备实时网络监视和控制功能,可以精确显示每个网络连接的状态,让用户轻松掌握网络活动情况。 软件下载:Radio…

B2902A是德科技B2902A精密型电源

181/2461/8938产品概述: Agilent B2902A 精密源/测量单元 (SMU) 是一款 2 通道、紧凑且经济高效的台式 SMU,能够源和测量电压和电流。它用途广泛,可以轻松、高精度地执行 I/V(电流与电压)测量。4 象限源和测量功能的集…

基于SpringCloud+Hadoop+Vue实现的企业级网盘系统实现

编程语言:Java、Mybatis、Spring、SpringBoot、SpringCloud、Node、Vue 开发环境:Windows 10 Mysql 开发工具:WebStorm、IDEA编译器、Git、Maven 应用部署服务器:SpringBoot内置Tomcat插件 Node服务器:Node v10.1…