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

news2024/12/22 23:20:28

研究原因: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 LOCAL

Chain 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 LOCAL

Chain 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 LOCAL

Chain 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 LOCAL

Chain 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:80

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

# 多了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 LOCAL

Chain 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 LOCAL

Chain 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 LOCAL

Chain 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 LOCAL

Chain 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.coloradmin.cn/o/1552517.html

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

相关文章

RegSeg 学习笔记(待完善)

论文阅读 解决的问题 引用别的论文的内容 可以用 controlf 寻找想要的内容 PPM 空间金字塔池化改进 SPP / SPPF / SimSPPF / ASPP / RFB / SPPCSPC / SPPFCSPC / SPPELAN  ASPP STDC:short-term dense concatenate module 和 DDRNet SE-ResNeXt …

短视频矩阵系统究竟怎么样,如何实现一站式精准获客?

在数字化时代的浩渺海洋中,短视频如同一股汹涌的浪潮,席卷了众多企业的营销战略。如何在这样的背景下,驾驭这股浪潮,将其转化为获客的强大动力,已成为众多企业家们心中的疑问。而蜘蛛短视频矩阵系统的出现,…

iOS开发进阶(十一):ViewController 控制器详解

文章目录 一、前言二、UIViewController三、UINavigationController四、UITabBarController五、UIPageViewController六、拓展阅读 一、前言 iOS 界面开发最重要的首属ViewController和View,ViewController是View的控制器,也就是一般的页面,…

岭师大数据技术原理与应用-序章-软工版

HeZaoCha-CSDN博客 序章—软工版 一、环境介绍1. VMware Workstation Pro2. CentOS3. Java4. Hadoop5. HBase6. MySQL7. Hive 二、系统安装1. 虚拟网络编辑器2. 操作系统安装 三、结尾 先说说哥们写这系列博客的原因,本来学完咱也没想着再管部署这部分问题的说&…

第二证券今日投资参考:低空经济迎利好 自动驾驶商业化提速

昨日,两市股指盘中弱势震动,午后加快下探,沪指失守3000点大关,深成指、创业板指跌超2%;到收盘,沪指跌1.26%报2993.14点,深成指跌2.4%报9222.47点,创业板指跌2.81%报1789.82点&#x…

目前常见的搜索引擎有哪些?

常见的搜索引擎可以分为两类:全网搜索类和平台内搜索。 全网搜索类是指可以在互联网范围内进行搜索的引擎,它们提供了广泛的搜索结果,包括网页、图片、视频、新闻等各种类型的内容。以下是一些常见的全网搜索引擎: 百度&#xff…

idea类已经存在却报错

一句话导读 在idea中导入新的项目,很多类都飘红报错,mvn compile可以通过,可能是因为idea缓存问题导致。 由于这个项目是由老项目复制过来后,再继续开发新的功能,很多同事导入后,都爆出新的类找不到。而编译…

linux nginx配置ssl, 实现https+ip访问

mkdir sslZhengShu openssl req -newkey rsa:2048 -nodes -keyout ca.key -out ca.csr openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr 和之前输入一样即可 …

反序列化动态调用 [NPUCTF2020]ReadlezPHP1

在源代码上看到提示 访问一下看看 代码审计一下 <?php #error_reporting(0); class HelloPhp {public $a;public $b;public function __construct(){$this->a "Y-m-d h:i:s";$this->b "date";}public function __destruct(){$a $this->a;…

【Go】结构体中Tag标识

https://blog.csdn.net/weixin_45193103/article/details/123876319 https://blog.csdn.net/qq_49723651/article/details/122005291 https://juejin.cn/post/7005465902804123679 学一点&#xff0c;整一点&#xff0c;基本都是综合别人的&#xff0c;弄成我能理解的内容 Tag定…

ubuntu编译OpenCV and seetaFace2

opencv opencv-4.5.2 opencv_contrib-4.5.2 SeetaFace2 SeetaFace2-master https://github.com/seetafaceengine 指定安装目录&#xff0c;和OpenCV放一个目录下了 安装前 安装 安装后 Qt安装 Windows下 Linux下 报错1 原因&#xff1a; 报错…

CMS(内容管理系统)

一、系统的编写可以在开源网站上下载一个相关项目&#xff0c;然后做2次开发 企业建站系统:MetInfo(米拓)、蝉知、SiteServer CMs等; B2C商城系统:商派Shopex、ECshop、HiShop、XpShop等; 门户建站系统:DedeCMS(织梦)、帝国CMS、PHPCMS、动易、CmsTop等; 博客系统:WordPres…

【JavaWeb】Day18.Vue组件库Element

什么是Element Element&#xff1a;是饿了么团队研发的&#xff0c;一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。组件&#xff1a;组成网页的部件&#xff0c;例如 超链接、按钮、图片、表格、表单、分页条等等。官网&#xff1a;Element - The worlds…

Capture One Pro 22 for Mac/win:重塑RAW图像处理的艺术

在数字摄影的世界里&#xff0c;RAW图像处理软件无疑是摄影师们手中的魔法棒&#xff0c;而Capture One Pro 22无疑是这一领域的璀璨明星。这款专为Mac和Windows系统打造的图像处理软件&#xff0c;以其出色的性能、丰富的功能和极致的用户体验&#xff0c;赢得了全球摄影师的广…

C++优先队列——priority_queue,函数对象,labmda表达式,pair等

头文件&#xff1a;#include<queue> 内部使用堆来实现&#xff0c;在需要或得最大的几个值或最小的几个值而不关心整个数组的顺序时非常好用。 用法&#xff1a; priority_queue<int, vector<int>, greater<int>>q; 第一个参数为堆中存储的元素。 …

Rust控制台输出跑马灯效果,实现刷新不换行,实现loading效果

要在 Rust 中实现控制台刷新而不换行&#xff0c;以实现类似 "loading" 状态的效果&#xff0c;你可以使用 \r&#xff08;回车符&#xff09;来覆盖上一行的内容。 use std::io::{self, Write}; use std::thread; use std::time::Duration;fn main() {let loading_…

使用Jenkins打包时执行失败,但手动执行没有问题如ERR_ELECTRON_BUILDER_CANNOT_EXECUTE

具体错误信息如&#xff1a; Error output: Plugin not found, cannot call UAC::_ Error in macro _UAC_MakeLL_Cmp on macroline 2 Error in macro _UAC_IsInnerInstance on macroline 1 Error in macro _If on macroline 9 Error in macro FUNCTION_INSTALL_MODE_PAGE_FUNC…

国外的Java面试题和国内的相比谁更卷

前言 有很多朋友很好奇国外的Java面试题长啥样&#xff0c;今天我们就去找5道国外的面试来和国内的对比一下看看谁难一些&#xff01; 面试题分享 1. Is Java Platform Independent if then how?&#xff08; Java平台是独立的吗&#xff1f;&#xff09; Yes, Java is a…

分享react+three.js展示温湿度采集终端

前言 气象站将采集到的相关气象数据通过GPRS/3G/4G无线网络发送到气象站监测中心&#xff0c;摆脱了地理空间的限制。 前端&#xff1a;气象站主机将采集好的气象数据存储到本地&#xff0c;通过RS485等线路与GPRS/3G/4G无线设备相连。 通信&#xff1a;GPRS/3G/4G无线设备通…

Cocos2dx-lua ScrollView[三]高级篇

一.概述 本文缩写说明&#xff1a;sv ScrollView, cell代表ScrollView的一个子节点 本文介绍sv的一种封装类库&#xff0c;来实现快速创建sv&#xff0c;有如下几个优点&#xff1a; 1.item的位置通过参数控制&#xff0c;提高开发效率 2.免去了调用sv的API&#xff0c;提…