Docker网络

常用命令

# 列出所有网络
docker network ls
​
# 检查网络详情
docker network inspect <network-name>
​
# 创建自定义网络
docker network create [options] <network-name>
​
# 将容器连接到网络
docker network connect <network-name> <container-name>
​
# 断开容器与网络的连接
docker network disconnect <network-name> <container-name>
​
# 删除网络
docker network rm <network-name>
​
# 删除所有未使用的网络
docker network prune

默认 bridge 网络

Bridge 网络是 Docker 的默认网络驱动程序。当你创建一个容器而不指定网络时,它会自动添加到默认的 bridge 网络中。Bridge 网络在单机环境下使用非常广泛,它通过软件网桥实现容器间的通信。

  1. 装完 Docker,系统自动生成一台虚拟交换机docker0,它自带一段专属内网地址:172.17.0.x,就像你家 WiFi 默认是 192.168.1.x 网段。
  2. 只要新建容器没指定网络,容器自动连到docker0这个交换机,分到一段 172.17 开头的内网 IP。
  3. 缺点(重点):同一台默认交换机里的容器,只能靠 IP 地址互相访问,不能用容器名字访问

你在电脑开 2 个容器:容器 A、容器 B,都在默认 bridge 里

  • 容器 AIP:172.17.0.2;容器 BIP:172.17.0.3
  • A 想连 B 数据库,只能输172.17.0.3才能连上
  • 你直接输容器名字B,系统不认识,访问失败
  • 一旦删掉 B 重新创建,它的 IP 会变,你每次都要改地址,非常麻烦

为了解决这个限制,Docker 提供了用户自定义 bridge 网络的功能。 当你创建自己的 bridge 网络时,连接到这个网络的容器就能获得更多便利的特性:容器之间可以通过名称相互访问, 网络隔离性更好,还可以随时将容器从网络中添加或移除。这就像是给容器们创建了一个独立的局域网, 既安全又方便管理。比如说,你可以把一个应用的前端、后端和数据库容器都放在同一个自定义 bridge 网络中, 它们就能通过容器名称轻松地相互通信,同时又与其他应用的容器网络保持隔离。

实践案例一:默认 Bridge 网络

让我们先来看看默认 bridge 网络的行为:

我们现构建一个装有 ping, curl 等指令的 nginx 镜像,方便我们在容器内容观察网络行为。

# 启动两个容器
docker run -d --name container1 my-nginx
docker run -d --name container2 my-nginx
​
# 查看容器的网络配置
docker inspect container1 -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
172.17.0.4
docker inspect container2 -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
172.17.0.3
​
# 进入容器1,尝试通过 IP 访问容器2
docker exec -it container1  curl http://172.17.0.3
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
​
# 注意:在默认 bridge 网络中,无法通过容器名称访问
docker exec -it container1  curl http://container2  # 这将失败
curl: (6) Could not resolve host: container2 (Domain name not found)

Docker 默认的 bridge 网络存在通信限制:容器间只能通过易变的 IP 地址互相访问,无法使用固定的容器名称进行通信。 这种 IP 依赖会导致服务地址变更时需要人工调整配置,增加维护成本。通过创建自定义 bridge 网络, 容器可通过稳定的名称直接互访,这种自动化的服务发现机制正是 Docker Compose 实现容器编排的基础——编排工具会自动创建专用网络, 使多容器应用能够通过服务名称维持稳定的通信链路。

实践案例二:自定义 Bridge 网络

现在让我们看看自定义 bridge 网络的优势:

# 创建自定义 bridge 网络
docker network create \
    --driver bridge \
    --subnet=172.20.0.0/16 \
    --gateway=172.20.0.1 \
    my-bridge-network
​
# 启动两个容器,连接到自定义网络
docker run -d \
    --name custom-container1 \
    --network my-bridge-network \
    my-nginx
​
docker run -d \
    --name custom-container2 \
    --network my-bridge-network \
    my-nginx
​
# 现在可以通过容器名称访问
docker exec -it custom-container1 curl http://custom-container2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

Docker 中默认的 bridge 网络与自定义 bridge 网络在容器名称解析上的差异

核心原因在于 DNS 服务的启用机制网络配置的隔离性

默认的 bridge 网络(即 docker0 虚拟网桥)不提供容器名称解析功能。容器间若需通信,必须通过 IP 地址。

因此默认网络下的容器 IP 可能因重启或容器重建而变化,导致依赖 IP 的通信失效。

而自定义 bridge 网络启用 Docker 内置的 DNS 服务器(127.0.0.11),容器可通过名称直接解析其他容器的 IP 地址。

容器启动时,Docker 自动将 /etc/resolv.conf中的 DNS 服务器指向 127.0.0.11

# Generated by Docker Engine.
# This file can be edited; Docker Engine will not make further changes once it
# has been modified.

nameserver 127.0.0.11
options ndots:0

# Based on host file: '/etc/resolv.conf' (internal resolver)
# ExtServers: [10.235.16.19 183.60.83.19 183.60.82.98]
# Overrides: [nameservers]
# Option ndots from: host

而使用默认 bridge 网络创建的容器,/etc/resolv.conf 文件中的内容如下:

# Generated by Docker Engine.
# This file can be edited; Docker Engine will not make further changes once it
# has been modified.

nameserver 10.235.16.19
nameserver 183.60.83.19
nameserver 183.60.82.98
options ndots:0

# Based on host file: '/etc/resolv.conf' (legacy)
# Overrides: [nameservers]
# Option ndots from: host

实践案例三: 使用自定义 Bridge 网络演示 Web 应用与 Redis 通信

这个案例展示了在实际应用中如何使用自定义 bridge 网络:

首先,创建一个简单的 Web 应用:

# 构建web-app镜像
docker build -t web-app web-app

然后创建网络并运行容器:

# 创建自定义 bridge 网络
docker network create my-bridge-network
​
# 启动 Redis 容器
docker run -d \
    --name redis-server \
    --network my-bridge-network \
    redis:alpine
​
# 启动 Web 应用容器
docker run -d \
    --name web-app \
    --network my-bridge-network \
    -p 5000:5000 \
    web-app

现在可以测试应用了:

# 访问应用
curl http://localhost:5000
​
# 多次访问,观察计数器增加
curl http://localhost:5000
curl http://localhost:5000
​
# 查看 Redis 中的数据
docker exec -it redis-server redis-cli get hits
图片[1]-Docker网络-软栈

Host 网络

Host 网络移除了容器和 Docker 主机之间的网络隔离,直接使用主机的网络。

特点:

  • 最佳网络性能
  • 直接使用主机的网络栈
  • 没有网络隔离
  • 端口直接绑定到主机上

实践案例:使用 Host 网络运行 Nginx 服务器

# 使用 host 网络运行 Nginx (80)
docker run -d \
    --name nginx-host \
    --network host \
    my-nginx

# 启动 Web 应用容器 (8080)
docker run -d \
    --name web-app-host \
    --network host \
    python:alpine \
    python -m http.server 8080

# 访问Nginx服务 访问Web应用
docker exec -it nginx-host curl http://localhost:8080


# 特别注意!
# 因为使用了 host 网络,容器直接使用主机的 80 端口, 所以当我们再次启动一个 Nginx 容器时,会报端口冲突的错误
docker run -d \
    --name nginx-host-2 \
    --network host \
    my-nginx
    
docker logs nginx-host-2

2026/07/11 11:14:13 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address in use)
2026/07/11 11:14:13 [emerg] 1#1: bind() to [::]:80 failed (98: Address in use)
nginx: [emerg] bind() to [::]:80 failed (98: Address in use)
2026/07/11 11:14:13 [notice] 1#1: try again to bind() after 500ms
2026/07/11 11:14:13 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address in use)
2026/07/11 11:14:13 [emerg] 1#1: bind() to [::]:80 failed (98: Address in use)

None 网络

None 网络完全禁用了容器的网络功能,容器在这个网络中没有任何外部网络接口。

特点:

  • 完全隔离的网络环境
  • 容器没有网络接口
  • 适用于不需要网络的批处理任务

实践案例:使用 None 网络运行独立计算任务

# 运行一个计算密集型任务,不需要网络
docker run --network none alpine sh -c \
  'for i in $(seq 1 10); do echo $((i*i)); done'

Overlay 网络

Overlay 网络是 Docker 用于实现跨主机容器通信的网络驱动,主要用于 Docker Swarm 集群环境。 它通过在不同主机的物理网络之上创建虚拟网络,使用 VXLAN 技术在主机间建立隧道,从而实现容器间的透明通信。 在 Overlay 网络中,每个容器都会获得一个虚拟 IP,容器之间可以直接通过这个 IP 进行通信, 而不需要关心容器具体运行在哪个主机上。这种网络类型特别适合于微服务架构、分布式应用以及需要跨主机通信的容器化应用, 例如分布式数据库集群、消息队列集群等。Overlay 网络支持网络加密,能确保跨主机通信的安全性, 同时还提供了负载均衡和服务发现等特性,是构建大规模容器集群的重要基础设施。


广告:

THE END
喜欢就支持一下吧
点赞10打赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容