github编辑

9.5 外部访问容器

容器运行在自己的隔离网络环境中 (通常是 Bridge 模式)。为了让外部网络访问容器内的服务,我们需要将容器的端口映射到宿主机的端口。

9.6.1 为什么要映射端口

容器的网络访问规则如下:

  • 容器之间:可以通过 IP 或容器名 (自定义网络) 互通。

  • 宿主机访问容器:可以通过容器 IP 访问。

  • 外部网络访问容器:❌ 默认无法直接访问。

为了让外部 (如你的浏览器、其他局域网机器) 访问容器内的服务,我们需要将容器的端口 映射 到宿主机的端口。

spinner

9.6.2 端口映射方式

Docker 提供了多种方式来指定端口映射。

1. 指定映射

使用 -p <宿主机端口>:<容器端口> 格式:

## 将宿主机的 8080 端口映射到容器的 80 端口

$ docker run -d -p 8080:80 nginx

此时访问 http://localhost:8080 即可看到 Nginx 页面。

多种格式

格式
含义
示例

ip:hostPort:containerPort

绑定指定 IP 的特定端口

-p 127.0.0.1:8080:80 (仅本机访问)

ip::containerPort

绑定指定 IP 的随机端口

-p 127.0.0.1::80

hostPort:containerPort

绑定所有 IP (0.0.0.0) 的特定端口

-p 8080:80 (默认)

containerPort

绑定所有 IP 的随机端口

-p 80

2. 随机映射

如果不关心宿主机使用哪个端口,可以使用随机映射。使用 -P (大写) 参数,Docker 会随机映射 Dockerfile 中 EXPOSE 指令暴露的所有端口到宿主机的高端口 (49000-49900)。

查看映射结果:

此时 Nginx 被映射到了宿主机的 49153 端口。


9.6.3 查看端口映射

可以使用以下命令查看容器的端口映射:

docker port

运行 docker port 可以查看到指定容器的端口映射情况:

docker ps

运行 docker ps 可以查看到所有容器的端口映射列表:


9.6.4 最佳实践与安全

在配置端口映射时,需要注意以下安全事项:

1. 限制监听 IP

默认情况下,-p 8080:80 会监听 0.0.0.0:8080,这意味着任何人只要能连接你的宿主机 IP,就能访问该服务。

如果不希望对外暴露 (例如数据库服务),应绑定到 127.0.0.1

2. 避免端口冲突

如果宿主机 8080 已经被占用了,容器将无法启动。

解决

  • 更换宿主机端口:-p 8081:80

  • 让 Docker 自动分配:-p 80

3. UDP 映射

默认是 TCP 协议。如果要映射 UDP 服务 (如 DNS,Syslog):


9.6.5 实现原理

Docker 使用 docker-proxy 进程 (用户态) 或 iptables DNAT 规则 (内核态) 来实现端口转发。

当流量到达宿主机端口时,iptables 规则将其目标地址修改为容器 IP 并转发:

这也是为什么你在容器内部看到的访问来源 IP 通常是网关 IP (如 172.17.0.1),而不是真实的外部 Client IP (除非使用 host 网络模式)。


最后更新于