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 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.mfbz.cn/a/496164.html

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

相关文章

【2024.3.28练习】砝码称重

题目描述 题目分析 动态规划解决。建立状态&#xff0c;数组元素为0或1&#xff0c;代表只用前个砝码能否称出重量。 设个砝码重量为&#xff0c;则第状态转移方程为&#xff1a; 我的代码 #include <iostream> #include <algorithm> #include <cmath> #i…

武汉星起航:五对一服务体系,引领卖家迅速适应亚马逊市场

在数字化浪潮的推动下&#xff0c;亚马逊跨境电商行业成为了众多创业者和企业家们竞相追逐的热门领域。然而&#xff0c;对于零经验的新手卖家而言&#xff0c;这个看似充满机遇的跨境电商世界实则暗藏无数挑战和未知。在这个关键时刻&#xff0c;武汉星起航公司以其专业的服务…

环信IM集成教程---消息转发合并转发的实现

前言 在发送消息体系中&#xff0c;转发消息是一个重要的环节&#xff0c;可以单条转发也可以合并转发。本文教大家在接入环信IM过程中如何实现单条转发&#xff0c;合并转发消息功能&#xff0c;同时举例一些容易踩坑的位置&#xff0c;以便大家尽快顺利的实现转发消息功能。…

Python实现猜数字游戏:一次编程旅程

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

融合创新!全局注意力+局部注意力,训练成本直降91.6%

全局注意力结合局部注意力可以让模型在处理数据时&#xff0c;既不会丢失重要的局部细节&#xff0c;也能考虑到整个数据集中的全局结构&#xff0c;从而在保持模型计算效率的同时&#xff0c;提高模型的表达能力。 这种策略相较于传统的单一注意力机制&#xff0c;能够更全面…

通用指南-营销和设计中的增强现实(AR)

原文作者&#xff1a;Superside 翻译&#xff1a;数字化营销工兵 --- 经典万字长文&#xff0c;权威解读&#xff0c;分享经典&#xff0c;预计阅读完需要30分钟&#xff0c;建议收藏&#xff01; 目录 一、引言 为什么要尝试AR AR到底是什么&#xff1f;营销人员和创意人…

巨控NET400网关:工业通讯的未来之门

描述&#xff1a;在数字化时代&#xff0c;工业通讯作为智能制造的核心&#xff0c;承载着数据交换、设备控制等关键任务。巨控NET400以其独特的优势&#xff0c;为各行各业的智能转型提供了强大的技术支持。本文深入探讨NET400的核心功能与主要优势&#xff0c;展望其在工业通…

T1 神奇苹果桶 (25分) - 小米前端笔试编程题解

考试平台&#xff1a; 赛码 题目类型&#xff1a; 20道选择 2道编程题 考试时间&#xff1a; 2024-03-23 &#xff08;两小时&#xff09; 题目描述 小希在森林冒险的时候发现一个神奇的木桶&#xff0c;某些时会凭空出现一些苹果&#xff0c;小希很解地大家分享了这一个神奇…

Markdown 编辑器使用

CSDN 在博客开头加上 [TOC](你的目录标题)就可以根据博客内容自动生成如下所示的目录&#xff1a; 你的目录标题 Markdown 编辑器功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表无序列表…

1.java openCV4.x 入门-环境搭建

专栏简介 &#x1f492;个人主页 &#x1f4d6;心灵鸡汤&#x1f4d6;大家 &#x1f4f0;专栏目录 点击上方查看更多内容 环境搭建 一、开发环境二、环境搭建1.openCV安装1.下载程序包 2.程序包安装3.搭建项目 三、非必要资源1.扩展库2.cmake 一、开发环境 开发工具 i…

structured bindings is supported from c++17

完整示例&#xff1a; #include <iostream> #include <format> #include <iomanip>void test_00(){struct Box{int width_;int height_;std::string name_;};Box box{3,4,"amazing"};auto [w, h, name]{box};//auto [w, h, name] box;std::cout …

openwrt在校园网环境下开启nat6 (ipv6 nat)

如果将路由器接入校园网&#xff0c;我们只能获得一个128位掩码的ipv6地址。这个地址仅供路由器本身使用&#xff0c;而路由器后的设备无法获取到ipv6地址&#xff0c;因此我们可以利用网络地址转换&#xff08;NAT&#xff09;为这些设备分配本地ipv6地址。 下面是openwrt开启…

TSINGSEE青犀推出县域治理视频基座数字化、智慧化解决方案

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

高效 CUDA 调试:将 NVIDIA Compute Sanitizer 与 NVIDIA 工具扩展结合使用并创建自定义工具

高效 CUDA 调试&#xff1a;将 NVIDIA Compute Sanitizer 与 NVIDIA 工具扩展结合使用并创建自定义工具 NVIDIA Compute Sanitizer 是一款功能强大的工具&#xff0c;可以节省您的时间和精力&#xff0c;同时提高 CUDA 应用程序的可靠性和性能。 在 CUDA 环境中调试代码既具有挑…

C#全新一代医院手术麻醉系统围术期全流程源码

目录 一、麻醉学科的起源 二、麻醉前访视与评估记录单 患者基本信息 临床诊断 患者重要器官功能及疾病情况 病人体格情况分级 手术麻醉风险评估 拟施麻醉方法及辅助措施 其他需要说明的情况 访视麻醉医师签名 访视时间 与麻醉相关的检查结果 三、手术麻醉信息系统…

Laravel扩展包的开发

扩展包的开发 1. 创建一个新项目&#xff0c;初始化扩展包配置 首先创建一个全新的Laravel项目&#xff1a; composer create-project --prefer-dist laravel/laravel laravelPkg 接下来&#xff0c;在项目中创建目录package/{your_name}/{your_package_name} mkdir -p pa…

STM32硬件I2C通信外设

文章目录 前言I2C硬件介绍10 位地址模式硬件I2C的引脚定义I2C框图主机发送序列图主机接收序列图 硬件I2C读写MPU6050总结 前言 本文主要介绍stm32自带的I2C通信外设&#xff0c;对比与软件模拟I2C&#xff0c;硬件I2C可以自动生成时序&#xff0c;时序的操作更加及时规范&…

什么是网页抓取 Web Scraping?如何进行网页抓取?

现在&#xff0c;不论是个人开发者还是庞大的企业都需要从互联网抓取大量数据&#xff0c;而网页抓取&#xff08;Web Scraping&#xff09;技术正是获取互联网上无尽信息宝库的一把钥匙。通过网页抓取工具&#xff0c;我们可以快速收集产品价格、市场趋势、用户评论等关键数据…

uniapp h5 touch事件踩坑记录

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