15.6.4 端口映射与访问控制

端口映射与访问控制#

端口映射将容器内部端口发布到宿主机或外网,是容器服务对外提供能力的关键。需要在可用性与最小暴露之间取得平衡,并配合防火墙与访问控制策略。

1. 原理草图(NAT 转发与访问控制)

文章图片

2. 基础命令与参数解释
- -p 主机端口:容器端口:固定映射
- -p 主机IP:主机端口:容器端口:绑定指定网卡
- -P:自动映射到随机高位端口

# 2.1 运行并映射端口(宿主机任意IP)
docker run -d --name web1 -p 8080:80 nginx

# 2.2 仅绑定本机回环,外网不可访问
docker run -d --name web2 -p 127.0.0.1:8081:80 nginx

# 2.3 随机映射(查看实际端口)
docker run -d --name web3 -P nginx
docker port web3
# 预期输出示例:80/tcp -> 0.0.0.0:49153

3. 安装与验证示例(含命令解释)

# 3.1 安装(Ubuntu)
sudo apt update
sudo apt install -y docker.io
sudo systemctl enable --now docker

# 3.2 拉取镜像并启动
docker pull nginx:latest
docker run -d --name web -p 8080:80 nginx

# 3.3 验证宿主机监听
ss -lntp | grep 8080
# 预期:LISTEN 0 4096 0.0.0.0:8080 ...

# 3.4 访问测试(本机)
curl -I http://127.0.0.1:8080
# 预期:HTTP/1.1 200 OK

4. 访问控制与防火墙联动

# 4.1 使用iptables限制仅允许 10.0.0.0/24 访问8080
sudo iptables -I INPUT -p tcp --dport 8080 -s 10.0.0.0/24 -j ACCEPT
sudo iptables -I INPUT -p tcp --dport 8080 -j DROP

# 4.2 使用firewalld(CentOS/RHEL)
sudo firewall-cmd --add-port=8080/tcp --permanent
sudo firewall-cmd --reload

5. 常见配置模式示例
- 本地开发:绑定回环

docker run -d --name dev -p 127.0.0.1:3000:3000 node:18-alpine
  • 生产反向代理入口:仅暴露 Nginx,后端容器走内部网络
docker network create app-net
docker run -d --name api --network app-net -p 127.0.0.1:5000:5000 myapi:latest
docker run -d --name nginx --network app-net -p 80:80 nginx

6. 排错流程与命令清单(含解释)

# 6.1 查看容器映射信息
docker ps --format "table {{.Names}}\t{{.Ports}}"
docker port web

# 6.2 检查容器服务监听地址
docker exec -it web ss -lntp
# 若只监听 127.0.0.1,外部无法访问,需改为 0.0.0.0

# 6.3 验证NAT规则(Docker自动生成)
sudo iptables -t nat -L -n | grep 8080

# 6.4 宿主机与外部连通性
curl -I http://宿主机IP:8080
nc -zv 宿主机IP 8080

常见问题与定位
- 访问超时:检查防火墙/安全组是否放行端口。
- 连接被拒绝:容器内服务未启动或只监听 127.0.0.1。
- 端口占用:宿主机已有服务占用该端口,改用其它端口或停止冲突服务。

7. 练习
1. 启动一个 Nginx 容器,将 80 映射到宿主机 18080,仅允许 192.168.1.0/24 访问。
2. 使用 -P 随机映射启动容器,写出实际映射端口并访问成功。
3. 将容器内应用改为监听 0.0.0.0,验证外部访问由失败变成功的过程。