文章目录

Docker 网络:网络模式与端口映射

发布于 2026-04-03 00:28:26 · 浏览 8 次 · 评论 0 条

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 app2curl 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 映射,兼顾隔离性、可维护性和外部访问能力。


五、排查网络问题的常用命令

  1. 查看容器 IP 和网络详情

    docker inspect <容器名或ID> | grep -A 20 "NetworkSettings"
  2. 测试容器间连通性(需容器内安装 pingtelnet):

    docker exec -it app1 ping app2
  3. 查看主机上所有监听端口(确认映射是否生效):

    ss -tuln | grep <主机端口>
    # 或
    netstat -tuln | grep <主机端口>
  4. 删除无用网络(避免资源堆积):

    docker network prune

六、实战:部署一个可外访的 Web 应用

假设你有一个 Python Flask 应用,监听容器内 5000 端口。

  1. 构建镜像(假设 Dockerfile 已存在):

    docker build -t myapp .
  2. 创建专用网络

    docker network create appnet
  3. 启动应用容器并映射端口

    docker run -d --name myweb --network appnet -p 8000:5000 myapp
  4. 验证

    • 在主机上访问 http://localhost:8000
    • 其他机器访问 http://<主机公网IP>:8000

此时,应用既可通过容器名与其他服务通信(如数据库),又可通过主机端口对外提供服务。


编辑容器的 /etc/hosts 文件不是推荐做法,应依赖 Docker 网络的内置 DNS 功能。始终为不同项目创建独立的自定义网络,避免端口冲突和命名混乱。不要在生产环境使用默认 bridge 网络,因其缺乏 DNS 和隔离能力。

评论 (0)

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

扫一扫,手机查看

扫描上方二维码,在手机上查看本文