Docker 网络:网络模式与端口映射
Docker 容器默认运行在隔离的网络环境中,但实际开发中常需容器间通信、访问外部服务或对外提供服务。理解 Docker 的网络模式和端口映射机制,是实现这些需求的关键。
一、Docker 的四种内置网络模式
Docker 提供四种主要网络驱动(network driver),通过 --network 参数指定。每种模式决定容器如何联网。
执行以下命令查看本机所有 Docker 网络:
docker network ls
你会看到类似输出,其中 bridge 是默认网络:
NETWORK ID NAME DRIVER SCOPE
abc123def456 bridge bridge local
...
1. bridge 模式(默认)
这是新建容器时未指定网络的默认模式。Docker 会创建一个虚拟网桥(通常叫 docker0),所有 bridge 模式的容器都连接到它,获得私有 IP(如 172.17.x.x),彼此可通,但外部无法直接访问。
启动一个使用默认 bridge 网络的容器:
docker run -d --name web nginx
该容器只能通过 Docker 主机的 IP 和映射端口被外部访问(见下文“端口映射”)。
2. host 模式
容器直接使用 Docker 主机的网络命名空间,共享主机的 IP 和端口。性能高,无网络隔离。
启动一个 host 模式的容器:
docker run -d --network host --name web-host nginx
此时,若主机 IP 是 192.168.1.100,则直接访问 http://192.168.1.100:80 即可看到 Nginx 页面——无需端口映射。
⚠️ 注意:host 模式下
-p端口映射参数无效,因为容器已直接使用主机端口。
3. none 模式
容器拥有自己的网络栈,但不配置任何网络接口(只有 lo 回环)。完全断网,用于高度隔离场景。
启动一个 none 模式的容器:
docker run -d --network none --name offline alpine sleep 3600
进入容器后执行 ip addr,只会看到 127.0.0.1。
4. container 模式
新容器复用另一个已存在容器的网络命名空间,两者共享 IP、端口、路由表等。适用于 sidecar 模式。
先启动一个基础容器:
docker run -d --name main nginx
再启动一个复用其网络的容器:
docker run -it --network container:main --name side alpine sh
此时 side 容器与 main 共享 IP,访问 localhost:80 即可访问 Nginx。
二、自定义 bridge 网络(推荐做法)
Docker 默认的 bridge 网络功能有限(如不支持容器名 DNS 解析)。生产环境应使用自定义 bridge 网络。
创建名为 mynet 的自定义 bridge 网络:
docker network create --driver bridge mynet
启动两个容器并加入该网络:
docker run -d --name app1 --network mynet nginx
docker run -d --name app2 --network mynet redis
现在,app1 容器内可直接通过 ping app2 或 curl http://app2:6379 访问 Redis,因为 Docker 内置 DNS 会自动解析容器名为 IP。
✅ 优势:自动 DNS、隔离性好、可跨容器通信。
三、端口映射:让外部访问容器服务
容器内部服务(如 Web 服务器监听 80 端口)默认无法从 Docker 主机外部访问。需通过 -p 参数将主机端口映射到容器端口。
基本语法
-p <主机端口>:<容器端口>
示例:映射 Nginx 80 端口
启动容器并将主机的 8080 端口映射到容器的 80 端口:
docker run -d -p 8080:80 --name web nginx
现在,访问 http://<主机IP>:8080 即可看到 Nginx 欢迎页。
多端口映射
可多次使用 -p 映射多个端口:
docker run -d -p 8080:80 -p 8443:443 --name secure-web nginx
只指定容器端口(随机主机端口)
省略主机端口时,Docker 会自动分配一个临时端口(32768–60999):
docker run -d -p 80 --name web-auto nginx
查看实际映射的端口:
docker port web-auto
输出示例:80/tcp -> 0.0.0.0:32769
四、网络模式与端口映射的兼容性
并非所有网络模式都支持 -p 端口映射。下表总结关键差异:
| 网络模式 | 是否支持 -p 映射 |
容器间通信方式 | 外部访问方式 |
|---|---|---|---|
bridge(默认) |
✅ | 需通过 IP(无 DNS) | 主机 IP + 映射端口 |
自定义 bridge |
✅ | 容器名(自动 DNS) | 主机 IP + 映射端口 |
host |
❌ | 直接共享主机网络 | 主机 IP + 容器监听端口(无需映射) |
none |
❌ | 无法通信 | 无法访问 |
container |
❌ | 共享目标容器网络 | 同目标容器的访问方式 |
💡 最佳实践:优先使用自定义 bridge 网络 +
-p映射,兼顾隔离性、可维护性和外部访问能力。
五、排查网络问题的常用命令
-
查看容器 IP 和网络详情:
docker inspect <容器名或ID> | grep -A 20 "NetworkSettings" -
测试容器间连通性(需容器内安装
ping或telnet):docker exec -it app1 ping app2 -
查看主机上所有监听端口(确认映射是否生效):
ss -tuln | grep <主机端口> # 或 netstat -tuln | grep <主机端口> -
删除无用网络(避免资源堆积):
docker network prune
六、实战:部署一个可外访的 Web 应用
假设你有一个 Python Flask 应用,监听容器内 5000 端口。
-
构建镜像(假设 Dockerfile 已存在):
docker build -t myapp . -
创建专用网络:
docker network create appnet -
启动应用容器并映射端口:
docker run -d --name myweb --network appnet -p 8000:5000 myapp -
验证:
- 在主机上访问
http://localhost:8000 - 其他机器访问
http://<主机公网IP>:8000
- 在主机上访问
此时,应用既可通过容器名与其他服务通信(如数据库),又可通过主机端口对外提供服务。
编辑容器的 /etc/hosts 文件不是推荐做法,应依赖 Docker 网络的内置 DNS 功能。始终为不同项目创建独立的自定义网络,避免端口冲突和命名混乱。不要在生产环境使用默认 bridge 网络,因其缺乏 DNS 和隔离能力。

暂无评论,快来抢沙发吧!