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

研究原因: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.mzph.cn/news/776592.shtml

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

相关文章

MySql实战--事务到底是隔离的还是不隔离的

第3篇文章和你讲事务隔离级别的时候提到过,如果是可重复读隔离级别,事务T启动的时候会创建一个视图read-view,之后事务T执行期间,即使有其他事务修改了数据,事务T看到的仍然跟在启动时看到的一样。也就是说&#xff0c…

外贸资讯 | 你看不上的邻居1-2月从中国进口额猛增

你看不上的邻居1-2月进口额猛增 被你猜对了,是印度 先是在俄罗斯最近的新闻报道里说,1月份中国成为印度主要贸易伙伴:两国贸易额增长16%,达到105亿美元。 然后去查了印度海关数据,也是中国排在第一,有意…

Stable Diffusion XL之核心基础内容

Stable Diffusion XL之核心基础内容 一. Stable Diffusion XL核心基础内容1.1 Stable Diffusion XL的主要优化1.2 SDXL整体架构初识1.3 VAE模型1.VAE基本介绍2. VAE基本模型结构3.VAE的训练 1.4 U-Net模型(Base部分)1. 十四个基本模块概述2. SDXL_Spatia…

SwiftUI Release 引入的辅助焦点管理

文章目录 前言使用 FocusState 属性包装器高级技巧:专用辅助技术可聚焦字段的高级用法优化体验运行截图总结 前言 SwiftUI Release 引入了强大的新功能,其中之一是辅助焦点管理。 这个新功能使得在SwiftUI中处理辅助技术(如 VoiceOver 和 S…

百度谷歌301强引蜘蛛池效果怎么样

301强引蜘蛛池效果怎么样 本文 虚良SEO 原创,转载保留链接!网址:百度谷歌301强引蜘蛛池效果怎么样 - 虚良SEO 随着搜索引擎优化(SEO)技术的发展,越来越多的网站开始采用蜘蛛池技术来提高网站的排名和流量。…

关于Kubernetes-v1.23.6-资源调度-StatefulSet-OnDelete当删除的时候才更新

前面提到的普通的滚动更新,都是修改完sts立即就会发生更新操作 而还有一种更新的策略为, OnDelete,即只有在 pod 被删除时会进行更新操作 还是先看一下web这个sts的当前更新策略如下: 这里我们修改,更新策略&#xf…

【创作纪念日】1024回忆录

不知不觉中,从创作第一篇文章到现在,已经1024天了,两年多的时间里,已经从硕士到博士了,1024,对于程序员来说,是个特别的数字吧,在此回忆与记录一下这些美好的经历吧。 缘起 很早以前…

UE5C++学习(四)--- SaveGame类存储和加载数据

上一篇说到使用数据表读取数据,如果我开始玩游戏之后,被怪物打了失去了一部分血量,这个时候我想退出游戏,当我再次进入的时候,希望仍然保持被怪物打之后的血量,而不是重新读取了数据表,这个时候…

【动态规划】【数学方法】Leetcode 343. 整数拆分

【动态规划】【数学方法】Leetcode 343. 整数拆分 解法 动态规划解法 数学 每次拆成n个3,如果剩下是4,则保留4,然后相乘 ---------------🎈🎈343. 整数拆分 题目链接🎈🎈------------------- …

重构销售话术和知识库,容联云找到了大模型的“钉子”

科技云报道原创。 从ChatGPT诞生起,大模型在营销、客服等场景的落地就被予以众望。然而在经历了一年多的“百模大战”洗礼之后,人们发现无论是算力成本还是内容生成的安全合规问题,都让大模型很难直接应用于机器与人对话的实际业务中。 这其…

常用的苹果应用商店上架工具推荐

摘要 移动应用app上架是开发者关注的重要环节,但常常会面临审核不通过等问题。为帮助开发者顺利完成上架工作,各种辅助工具应运而生。本文探讨移动应用app上架原理、常见辅助工具功能及其作用,最终指出合理使用工具的重要性。 引言 移动应…

牛客题霸-SQL篇(刷题记录三)

本文基于前段时间学习总结的 MySQL 相关的查询语法,在牛客网找了相应的 MySQL 题目进行练习,以便加强对于 MySQL 查询语法的理解和应用。 由于涉及到的数据库表较多,因此本文不再展示,只提供 MySQL 代码与示例输出。 以下内容是…

git stash代码pop stash后误删找回

如题,git stash了代码,点了pop stash后,revert了改动。是可以找回的。 操作步骤: 使用 git stash pop 其实并没有真正地将文件删掉的,而是删除引用而已,因此我们可以使用 git fsck 命令进行找回&#xff…

php 快速入门(一)

一、配置系统环境 1.1 安装软件 1、安装php的开发软件:phpstorm 在这个软件中写代码 2、安装php的运行软件:phpstduy 写好的php程序需要放到phpstduy中,用户才能访问和测试 安装过程注意事项:安装的路径中不能有空格和中文字符&…

彻底理解 IO 多路复用!

在讲解该技术之前,我们需要预习一下文件以及文件描述符。 什么是文件 程序员使用I/O最终都逃不过文件这个概念。 在Linux世界中文件是一个很简单的概念,作为程序员我们只需要将其理解为一个N byte的序列就可以了: b1, b2, b3, b4, ......…

基于视图能力的县域治理视频基座数字化、智慧化解决方案

一、方案背景 县域治理方案是我国地方治理体系的重要组成部分,对于促进县域经济社会发展、维护社会稳定、推进全面深化改革具有重要意义。随着科技的不断进步,视频监管已经成为了现代社会治理的重要手段之一。县域治理视频监管方案是通过视频监控、数据…

C语言中常用的文件操作

本文将介绍常用的关于文件操作函数,如fopen,fclose,fread,fwrite,feek,ftell,rewind以及feof和ferror等文件操作操作函数,还介绍一些用于所有输入输出流的函数如fgetc,fputc,fgets,fputs,fprintf,fscanf等函数,还介绍了sscanf,sprintf函数,fe…

【Java扫盲篇】String、String Buffer和String Builder的区别

你在面试时,面试官让你讲讲String String Buffer String Builder的区别,你是否能流畅的、完整的叙述出他们三者的区别? ✍先说结论 相同点: 他们的底层都是由char数组实现的。不同点: String对象一旦创建,是不能修…

基于STM32温室智能监测控制系统设计

**单片机设计介绍,基于STM32温室智能监测控制系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于STM32的温室智能监测控制系统设计是一个综合性的项目,旨在实现对温室内环境参数的实时监测和控制…

2024年14款国内外主流低代码开发平台对比:总有一款适合您!

低代码开发平台是一种更偏向于赋能技术人员的工具,它允许开发人员通过将可视代码块拖放到工作流中来创建应用程序,从而以最少的手工编码快速设计应用程序。 市场中有非常多的低代码开发平台,令人眼花缭乱。应当选哪个低代码开发平台&#xf…