Docker 端口映射原理

news2025/7/14 18:38:41

在 Docker 中,默认情况下容器无法直接与外部网络通信。 为了使外部网络能够访问容器内的服务,Docker 提供了端口映射功能,通过将宿主机的端口映射到容器内的端口,外部可以通过宿主机的IP和端口访问容器内的服务

以下通过动手演示, 安装一个Flask容器, 解释端口映射从外部访问容器的原理

安装一个Flask容器

文件结构

.
├── Dockerfile
└── app.py

Dockerfile

FROM rockylinux:9.3

RUN dnf update -y && \
    dnf install -y python3 python3-pip && \
    dnf clean all

WORKDIR /app

COPY app.py /app/app.py

RUN pip3 install --no-cache-dir flask

EXPOSE 5000

CMD ["python3", "app.py"]

app.py

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return "Hello"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

构建镜像

docker build -t flask-app:1.0 .

启动容器, 进行端口映射

docker run -d -p 80:5000 flask-app:1.0

从外部访问 (192.168.52.203是我的虚拟机IP)

# curl 192.168.52.203
Hello

端口映射原理

当执行docker run -d -p 80:5000 flask-app:1.0时, Docker会配置iptables规则来实现端口映射, 流程如下:

1. iptables PREROUTING 链处理, 做DNAT转换

外部请求到达宿主机时, iptables的PREROUTING链处理该请求, 根据DNAT规则将目标IP和端口(192.168.52.203:5000)替换为容器的IP和端口(172.17.0.2:5000)

# iptables -t nat -L PREROUTING
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
DOCKER     all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL

# iptables -t nat -L DOCKER
Chain DOCKER (2 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere
DNAT       tcp  --  anywhere             anywhere             tcp dpt:http to:172.17.0.2:5000

2. DNAT转换后的数据包转发到容器

经过DNAT转换后的数据包会发送到虚拟网桥docker0, 再通过veth设备转发到容器的虚拟网络接口(eth0)

宿主机的路由表
# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.52.2    0.0.0.0         UG    100    0        0 ens160
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.52.0    0.0.0.0         255.255.255.0   U     100    0        0 ens160

3. 容器接受请求并返回响应, 响应报文通过iptables POSTROUTING链处理, 做SNAT转换

容器接受请求并返回响应,响应报文先发送到 docker0, 再通过 SNAT(MASQUERADE)规则,将源IP和端口(172.17.0.2:5000)替换为宿主机的IP和端口,最后发送回客户端

# iptables -t nat -L POSTROUTING -v
Chain POSTROUTING (policy ACCEPT 2387 packets, 151K bytes)
 pkts bytes target     prot opt in     out     source               destination
   89  5558 MASQUERADE  all  --  any    !docker0  172.17.0.0/16        anywhere

附: wireshark抓包结果

  • 客户端IP: 192.168.52.202
  • 运行容器的宿主机IP: 192.168.52.203
  • 容器IP: 172.17.0.2

抓宿主机网卡的包

tcpdump -i ens160 -nn tcp and not port 22 -w ens160.pcap

请添加图片描述
抓docker0的包

tcpdump -i docker0 -nn tcp -w docker0.pcap

请添加图片描述

参考

Docker 容器如何访问外部网络

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

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

相关文章

SDL —— 将sdl渲染画面嵌入Qt窗口显示(附:源码)

🔔 SDL/SDL2 相关技术、疑难杂症文章合集(掌握后可自封大侠 ⓿_⓿)(记得收藏,持续更新中…) 效果 使用QWidget加载了SDL的窗口,渲染器使用硬件加速跑GPU的。支持Qt窗口缩放或显示隐藏均不影响SDL的图像刷新。   操作步骤 1、在创建C++空工程时加入SDL,引入头文件时需…

算法每日一练 (23)

💢欢迎来到张翊尘的技术站 💥技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 算法每日一练 (23)最大正方形题目描述解题思路解题代码…

UE5学习笔记 FPS游戏制作28 显式玩家子弹数

文章目录 添加变量修改ShootOnce方法,设计时减少子弹,没有子弹不能开枪在UI上显示 添加变量 在Gun类中添加BulletNum和ClipSize两个参数 BulletNum是当前还有多少子弹,ClipSize是一个弹匣多少子弹 Rifle的ClipSzie设置为30,Laun…

《构建有效的AI代理》学习笔记

原文链接:https://www.anthropic.com/engineering/building-effective-agents 《构建有效的AI代理》学习笔记 一、概述 核心结论 • 成功的AI代理系统往往基于简单、可组合的模式,而非复杂框架。 • 需在性能、成本与延迟之间权衡,仅在必要时增加复杂度…

数据处理专题(四)

目标 使用 Matplotlib 进行基本的数据可视化。‍ 学习内容 绘制折线图 绘制散点图 绘制柱状图‍ 代码示例 1. 导入必要的库 import matplotlib.pyplot as pltimport numpy as npimport pandas as pd 2. 创建示例数据集 # 创建示例数据集data { 月份: [1月, 2月, 3…

【目标检测】【深度学习】【Pytorch版本】YOLOV1模型算法详解

【目标检测】【深度学习】【Pytorch版本】YOLOV1模型算法详解 文章目录 【目标检测】【深度学习】【Pytorch版本】YOLOV1模型算法详解前言YOLOV1的模型结构YOLOV1模型的基本执行流程YOLOV1模型的网络参数YOLOV1模型的训练方式 YOLOV1的核心思想前向传播阶段网格单元(grid cell)…

云钥科技多通道工业相机解决方案设计

项目应用场景分析与需求挑战 1. 应用场景 ‌目标领域‌:工业自动化检测(如精密零件尺寸测量、表面缺陷检测)、3D立体视觉(如物体建模、位姿识别)、动态运动追踪(如高速生产线监控)等。 ‌核心…

从零到一:ESP32与豆包大模型的RTC连续对话实现指南

一、对话效果演示 ESP32与豆包大模型的RTC连续对话 二、ESP-ADF 介绍 乐鑫 ESP-ADF(Espressif Audio Development Framework)是乐鑫科技(Espressif Systems)专为 ESP32 系列芯片开发的一款音频开发框架。它旨在简化基于 ESP32 芯…

【深度学习与实战】2.3、线性回归模型与梯度下降法先导案例--最小二乘法(向量形式求解)

为了求解损失函数 对 的导数,并利用最小二乘法向量形式求解 的值‌ 这是‌线性回归‌的平方误差损失函数,目标是最小化预测值 与真实值 之间的差距。 ‌损失函数‌: 考虑多个样本的情况,损失函数为所有样本的平方误差之和&a…

【Django】教程-2-前端-目录结构介绍

【Django】教程-1-安装创建项目目录结构介绍 3. 前端文件配置 3.1 目录介绍 在app下创建static文件夹, 是根据setting中的配置来的 STATIC_URL ‘static/’ templates目录,编写HTML模板(含有模板语法,继承,{% static ‘xx’ …

详解list容器

1.list的介绍 list的底层结构是双向带头循环链表,允许随机的插入和删除,但其内存空间不是连续的。随机访问空间能力差,需要从头到尾遍历节点,不像vector一样高效支持 2.list的使用 构造函数 1.默认构造函数:创建一个…

leetcode_977. 有序数组的平方_java

977. 有序数组的平方https://leetcode.cn/problems/squares-of-a-sorted-array/ 1.题目 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 示例 1: 输入:nums [-4,-1…

网络探索之旅:网络原理(第二弹)

上篇文章,小编分享了应用层和传输层深入的一点的知识,那么接下来,这篇文章,继续分享网络层和数据链路层。 网络层 了解这个网络层,那么其实就是重点来了解下IP这个协议 对于这个协议呢,其实也是和前面的…

深入剖析 JVM:从组成原理到调优实践

深入剖析 JVM:从组成原理到调优实践 深入剖析 JVM:从组成原理到调优实践一、JVM 组成架构:运行 Java 程序的 “幕后引擎”1.1 内存结构:数据存储的 “分区管理”1.2 执行引擎:字节码的 “翻译官”1.3 本地方法接口&…

阿里云下一代可观测时序引擎-MetricStore 2.0

作者:徐昊(博澍) 背景 作为可观测场景使用频度最高的数据类型,Metrics 时序数据在可观测领域一直占有着重要地位,无论是从全局视角来观测系统整体状态,还是从大范围数据中定位某一个异常的位置&#xff0…

从入门到精通【 MySQL】 数据库约束与设计

文章目录 📕1. 数据库约束✏️1.1 NOT NULL 非空约束✏️1.2 DEFAULT 默认值约束✏️1.3 UNIQUE 唯一约束✏️1.4 PRIMARY KEY 主键约束✏️1.5 FOREIGN KEY 外键约束✏️1.6 CHECK 约束 📕2. 数据库设计✏️2.1 第一范式✏️2.2 第二范式✏️2.3 第三范…

Dubbo 通信流程 - 服务的调用

Dubbo 客户端的使用 在 Dubbo 应用中,往类成员注解 DubboReference,服务启动后便可以调用到远端: Component public class InvokeDemoFacade {AutowiredDubboReferenceprivate DemoFacade demoFacade;public String hello(String name){// …

【数据结构】哈夫曼树

哈夫曼树 在学习哈夫曼树之前,先了解以下几个概念: 一:**路径长度:**在一棵树中,从一个节点到另一个节点所经过的“边”的数量,被我们称为两个节点之间的路径长度。 二:**树的路径长度&#xf…

HCIP(TCP)(2)

1. TCP三次握手 SYN (同步序列编号) 报文: 客户端发送 SYN 报文,开始建立连接,并初始化序列号。 SYN-ACK (同步序列编号-确认) 报文: 服务器收到 SYN 报文后,回复 SYN-ACK 报文,确认连接请求,并初始化自己的序列号和确…

基于Web的交互式智能成绩管理系统设计

目录 摘要 绪论 一、应用背景 二、行业发展现状 三、程序开发的重要意义 四、结语 1 代码 2 数据初始化模块 3 界面布局模块 4 核心功能模块 5 可视化子系统 6 扩展功能模块 7 架构设计亮点 功能总结 一、核心数据管理 二、智能分析体系 三、可视化系统 四、扩…