Docker Network(网络)使用指南

Docker Network(网络)使用指南

九月 03, 2025 次阅读

Docker 为什么需要网络管理

容器的网络默认与宿主机及其他容器相互隔离,这样能够确保容器运行环境的独立性与安全性。但在实际应用中,我们往往不仅仅需要“隔离”,还会遇到一系列与网络相关的需求与挑战,例如:

  • 容器间通信:当应用被拆分为多个微服务部署在不同容器中时,这些容器必须能够彼此通信,例如 Web 服务需要调用数据库容器。
  • 容器与宿主机通信:开发、调试或日志收集场景下,往往需要容器与宿主机建立交互通道。
  • 容器与外部主机通信:如果容器中运行的是 Web 应用、Nginx、数据库等服务,就必须让外部客户端能够访问容器内部的网络应用。
  • 容器网络隔离与共享:有些容器需要完全独立的网络空间以确保安全,而另一些容器则可能需要共享网络(如与宿主机使用同一个网络栈)以实现更直接的通信。
  • 无网络模式:部分场景下,容器完全不需要网络访问,此时可以选择禁用网络以进一步提升安全性与轻量化。
  • 定制化网络需求:在复杂的分布式架构或集群环境中,我们可能需要构建定制化的网络,例如跨主机的容器集群网络、虚拟局域网 (VLAN)、服务发现与负载均衡等。

正是因为存在以上多样化的需求,Docker 提供了灵活的 网络管理机制。通过不同的网络模式(如 bridge、host、none、overlay、自定义网络 等),我们能够针对不同的应用场景选择合适的方案:

  • 使用 bridge 网络 解决单机多容器通信问题;
  • 使用 host 网络 让容器与宿主机共享网络栈;
  • 使用 none 网络 禁止网络访问,提升安全性;
  • 使用 overlay 网络 跨主机搭建集群网络;
  • 使用 自定义网络,实现更精细的网络控制与隔离。

因此,容器网络不仅仅是基础设施的一部分,更是 容器编排、服务治理和系统安全的核心环节。合理的网络管理,能够让 Docker 容器真正成为灵活、可扩展的微服务运行环境。


Docker 网络架构简介

Docker 容器网络是容器虚拟化环境中至关重要的一环。它让应用程序能够在隔离的网络环境中运行,拥有独立的 网络设备、IP 协议栈、端口套接字、路由表、防火墙规则以及 DNS 配置。通过这种方式,容器可以与宿主机网络解耦,同时实现灵活的网络通信与隔离。

为了实现这一目标,Docker 网络架构主要由三大核心部分组成:CNM(Container Network Model)、Libnetwork 和 网络驱动(Drivers)


1. CNM(Container Network Model)

CNM 是 Docker 采用的容器网络设计规范,它定义了容器网络的基础组成元素和交互方式。CNM 包含三个核心组件:

  • Sandbox(沙箱)
    Sandbox 提供容器的虚拟网络栈,包括端口、套接字、IP 地址、路由表、防火墙、DNS 配置等。它的主要作用是将容器网络与宿主机网络隔离开,确保每个容器拥有独立的网络环境。

  • Network(网络)
    Network 可以理解为 Docker 内部的虚拟子网,它将多个容器组织在同一个逻辑网络空间内,使其能够直接通信。一个 Network 就像传统网络中的一个局域网。

  • Endpoint(端点)
    Endpoint 是连接 Sandbox 与 Network 的接口,相当于虚拟网卡。一个容器如果需要加入多个网络,就必须拥有多个 Endpoint。
    例如,容器 B 有两个 Endpoint,分别接入 Network A 和 Network B。那么容器 A 和 B 可以通过 Network A 通信,而容器 B 和 C 可以通过 Network B 通信,但容器 A 和 C 不能通过 B 的两个 Endpoint 间接通信。

通过 CNM 的定义,Docker 能够以模块化的方式管理容器的网络栈,实现 灵活的连接方式清晰的网络拓扑结构


2. Libnetwork

Libnetwork 是 CNM 的官方标准实现。它是一个开源库,由 Go 语言编写,Docker 网络的核心逻辑均基于此实现。

Libnetwork 完整实现了 CNM 的三个组件(Sandbox、Network、Endpoint),并在此基础上提供了更多高级功能:


cnm


  • 本地服务发现:容器之间可以通过名字互相访问,而不必依赖固定的 IP 地址。
  • 负载均衡(Ingress):对接入同一服务的多个容器自动分配请求,实现内置的负载均衡机制。
  • 网络管理与控制层:提供对容器网络的统一管理接口,使得用户能够通过 Docker CLI 或 API 灵活操作网络。

Libnetwork 的出现让 Docker 网络不再是一个“黑盒”,而是一个 可扩展、可编排的网络平台


3. 网络驱动(Drivers)

驱动是 Docker 网络的实际执行者,负责 数据层 的实现,例如容器之间的连通性、网络隔离、安全策略等。不同驱动对应不同的网络模式,Docker 内置了多种原生驱动:

  • Bridge Driver(桥接网络)
    默认网络驱动,在单机环境下最常用。容器之间通过虚拟网桥(docker0)互联,外部访问则通过端口映射实现。

  • Host Driver(主机网络)
    容器与宿主机共享同一个网络命名空间,没有额外的虚拟层,性能较好,但隔离性较差。

  • Overlay Driver(覆盖网络)
    用于跨主机容器通信,依赖 VXLAN 技术构建虚拟的二层网络,是 Docker Swarm 和 Kubernetes 集群中常用的网络模式。

  • Macvlan Driver(MACVLAN 网络)
    为容器分配独立的 MAC 地址,使其像真实物理机一样接入物理网络。适合需要直接暴露在局域网中的应用。

  • Ipvlan Driver(IPVLAN 网络)
    与 Macvlan 类似,但容器共享父接口的 MAC 地址,仅分配独立 IP。性能更高,适合大规模网络场景。

  • None Driver(无网络)
    容器启动后完全没有网络接口,适用于安全需求极高或只需本地计算的场景。

除了内置驱动外,Docker 还支持通过插件机制扩展网络驱动,例如接入 Calico、Weave、Flannel 等第三方网络方案,以满足云原生和大规模分布式场景的需求。


Docker 网络架构通过 CNM 规范 → Libnetwork 实现 → 驱动执行 的层层分工,构建出一个既灵活又可扩展的网络系统。

  • CNM 定义了模型,提供抽象;
  • Libnetwork 作为实现,负责管理;
  • 驱动作为底层,保障网络连通性与隔离性。

这种分层设计让 Docker 网络既能满足 单机开发环境的简单需求,也能扩展到 分布式集群的复杂网络场景,为容器化应用的广泛落地奠定了坚实的基础。


常见网络类型

Docker 提供了多种网络模式,以满足不同场景下的通信与隔离需求。常见的网络类型如下:


1. Bridge 网络(默认网络)

  • 原理:Bridge 驱动会在宿主机上创建一个 Linux 网桥(默认是 docker0)。同一主机上的容器如果加入同一个 bridge 网络,就可以直接互相通信。

  • 特点

    • 容器拥有独立的 IP 地址(由 Docker 分配)。
    • 容器与外部通信时需要通过端口映射 (-p)。
    • 默认创建容器时,如果不指定 --network,就会加入 bridge 网络。
  • 适用场景:多个容器运行在同一台宿主机上,需要互相通信时使用。

  • 示例命令

    # 启动容器并加入默认 bridge 网络
    docker run -d --name web1 nginx
    
    # 创建自定义 bridge 网络
    docker network create --driver bridge my_bridge
    
    # 启动容器并加入自定义网络
    docker run -d --name web2 --network my_bridge nginx

在宿主机上,docker0 网桥可以通过 ifconfigip addr 查看:

docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255

这里的 172.17.0.1 就是宿主机在容器内部网络中的网关地址。


2. Host 网络

  • 原理:容器直接使用宿主机的网络栈,没有独立的 IP 地址和网卡。

  • 特点

    • 容器与宿主机共享网络命名空间。
    • 端口不再需要映射,容器内暴露的端口即宿主机端口。
    • 性能较好,但容器间隔离性降低。
  • 适用场景:需要高性能网络访问,或需要让容器直接暴露在宿主机网络中的场景(如运行监控代理)。

  • 示例命令

    docker run -d --name web --network host nginx

3. Container 网络

  • 原理:新容器共享已有容器的网络命名空间(包括 IP、端口)。

  • 特点

    • 新容器不会分配新的 IP,而是直接与目标容器共享网络栈。
    • 两个容器之间通过 lo(回环接口)通信。
    • 除了网络共享外,文件系统、进程等依旧隔离。
  • 适用场景:运行调试工具容器(如 tcpdump、curl),直接进入目标容器的网络环境。

  • 示例命令

    # 先运行一个容器
    docker run -d --name web nginx
    
    # 新容器共享 web 的网络
    docker run -it --rm --network container:web busybox sh

4. None 网络

  • 原理:容器拥有独立的 Network Namespace,但不做任何网络配置。

  • 特点

    • 容器没有网卡、IP、路由等信息。
    • 处于完全网络隔离状态。
  • 适用场景:对安全性要求极高,或容器仅需执行纯计算、文件处理而无需网络时。

  • 示例命令

    docker run -d --network none nginx

5. Overlay 网络

  • 原理:基于 VXLAN 技术,在多个 Docker 主机之间创建虚拟的二层网络。

  • 特点

    • 允许运行在不同主机上的容器进行通信。
    • 常用于 Docker Swarm、Kubernetes 等容器编排场景。
    • 需要启用集群管理(Swarm 或其他插件)。
  • 适用场景:跨主机容器集群通信、多服务协同工作。

  • 示例命令

    # 初始化 Swarm
    docker swarm init
    
    # 创建 overlay 网络
    docker network create -d overlay my_overlay
    
    # 在集群中运行服务并加入 overlay 网络
    docker service create --name web --network my_overlay nginx

libnetwork


  • bridge:单机容器间通信的默认选择。
  • host:高性能,直接复用宿主机网络。
  • container:共享已有容器的网络环境。
  • none:完全隔离,无网络。
  • overlay:跨主机通信,是集群和分布式系统的核心网络方案。

通过这些网络模式的灵活组合,Docker 能够同时支持 单机开发、生产部署、分布式集群 等不同应用场景。


docker 网络管理命令

命令清单

命令 别名 功能 备注
docker network create 创建网络
docker network connect 连接网络
docker network disconnect 断开网络
docker network ls docker network list 列出网络
docker network prune 删除不使用的网络
docker network inspect 查看网络详情
docker network rm docker network remove 删除 1 个或多个网络

docker network create

docker network create 用于创建自定义网络,便于容器间通信和网络隔离。通过不同的选项,可以灵活配置网络类型、子网、网关等参数。

该指令功能如下:

  • 创建自定义 Docker 网络
  • 支持多种网络驱动(如 bridgeoverlay 等)
  • 可以指定子网、网关等,满足不同应用场景

语法

docker network create [OPTIONS] NETWORK

常用参数

  • -d, --driver:指定网络驱动(默认是 bridge
  • --subnet:CIDR 格式的子网(例如 192.168.0.0/16
  • --gateway:指定网关地址
  • --ipv6:启用 IPv6 支持
  • --attachable:允许独立容器连接到 Swarm 网络

示例

# 创建一个名为 br0 的 bridge 网络,并指定子网和网关
docker network create \
  --driver=bridge \
  --subnet=192.168.0.0/16 \
  --gateway=192.168.0.1 \
  br0
  • 创建成功后,可以使用 docker network ls 查看网络列表。
  • 新建容器时通过 --network br0 参数指定容器加入该网络。

docker network inspect

docker network inspect 用于查看一个或多个 Docker 网络的详细信息,包括网络 ID、驱动类型、子网、网关以及与其连接的容器等内容。


基本语法

docker network inspect [OPTIONS] NETWORK [NETWORK...]

常用参数

  • -f, --format:以 Go 模板的方式指定输出格式,便于只提取需要的信息。

使用示例

  1. 查看某个网络的详细信息:
docker network inspect mynetwork
  1. 使用 --format 参数过滤输出,只显示容器信息:
docker network inspect --format='{{json .Containers}}' mynetwork

通过 docker network inspect,不仅可以了解网络本身的属性,还能查看网络中与容器之间的关联关系,便于调试与排错。


docker network connect

docker network connect 用于将已有的容器连接到指定的网络(可以是网络名称或 ID)。
连接成功后,容器就能与该网络中的其他容器进行通信。


基本语法

docker network connect [OPTIONS] NETWORK CONTAINER

常用参数

  • --ip:指定容器在该网络中的 IPv4 地址。
  • --ip6:指定容器在该网络中的 IPv6 地址。

使用示例

  1. 将正在运行的容器连接到网络
docker network connect multi-host-network my_container1
  1. 容器启动时直接连接到网络
    使用 --network 选项可以在容器启动时直接加入某个网络:
docker run -itd --network=multi-host-network busybox-container
  1. 指定容器的 IP 地址
    连接容器时,可以手动分配其在网络中的 IP 地址:
docker network connect --ip 10.10.36.122 multi-host-network container2

通过 docker network connect,可以灵活地将容器加入到多个网络,从而实现更复杂的网络拓扑结构和容器间通信管理。


docker network disconnect

docker network disconnect 用于将容器从指定网络中断开连接。
断开后,该容器将无法再与该网络中的其他容器进行通信。


基本语法

docker network disconnect [OPTIONS] NETWORK CONTAINER

常用参数

  • -f:强制断开,即使容器当前正在使用该网络。

使用示例

  1. 普通断开容器与网络的连接
docker network disconnect multi-host-network my_container1
  1. 强制断开容器与网络的连接
docker network disconnect -f multi-host-network my_container1

通过 docker network disconnect,可以灵活管理容器的网络连接,避免不必要的通信,也能在容器生命周期中动态调整网络拓扑结构。


docker network prune

docker network prune 用于清理并删除当前未被任何容器使用的网络。
该命令常用于释放系统资源,保持 Docker 环境整洁。


基本语法

docker network prune [OPTIONS]

常用参数

  • -f, --force:跳过确认提示,直接删除未使用的网络。

使用示例

  1. 交互式删除未使用的网络(会提示确认)
docker network prune
  1. 强制删除未使用的网络(无确认提示)
docker network prune -f

通过 docker network prune,可以快速清理掉未使用的网络,避免累积占用存储空间或影响环境整洁。


docker network rm

docker network rm 用于删除一个或多个 Docker 网络。
删除前,确保网络没有被任何容器使用,否则需要使用强制参数。


基本语法

docker network rm NETWORK [NETWORK...]

常用参数

  • -f:强制删除网络,即使有容器当前连接该网络。

使用示例

  1. 删除单个网络
docker network rm br0
  1. 强制删除网络
docker network rm -f br0
  1. 一次删除多个网络
docker network rm net1 net2 net3

docker network rm 可以灵活地删除不再需要的网络,结合 -f 参数可以处理仍被容器使用的网络,从而便于网络管理和环境清理。


docker network ls

功能说明

docker network ls 用于列出 Docker 主机上的所有网络,包括默认网络和用户创建的网络。
它可以快速查看网络名称、ID、驱动类型以及作用范围。


基本语法

docker network ls [OPTIONS]
  • 别名:
docker network list

常用参数

  • -f, --filter:按照条件过滤网络,例如按驱动类型或名称过滤。
  • --format:指定输出格式,如 tablejson 等。
  • --no-trunc:显示完整的网络 ID,不截断。
  • -q, --quiet:只显示网络 ID,适合脚本使用。

使用示例

  1. 列出所有网络
docker network ls
  1. 仅显示网络 ID
docker network ls -q
  1. 按驱动类型过滤
docker network ls -f driver=bridge

通过 docker network ls,可以快速查看 Docker 网络信息,配合过滤和格式化选项,便于网络管理和自动化脚本使用。


指令汇总

命令 功能说明 常用参数/选项 示例 备注
docker network create 创建自定义网络 -d/--driver 指定驱动类型
--subnet 指定子网
--gateway 指定网关
docker network create mynetwork 创建自定义网络,可为容器提供隔离或自定义拓扑
docker network ls 列出所有网络 -f/--filter 过滤
--format 指定输出格式
-q/--quiet 只显示 ID
docker network ls
docker network ls -q
支持别名 docker network list
docker network inspect 查看网络详情 -f/--format 格式化输出 docker network inspect mynetwork 可以查看网络配置、子网、容器连接信息
docker network connect 将容器连接到网络 --ip 指定 IPv4
--ip6 指定 IPv6
docker network connect multi-host-network my_container1 容器连接后可以与该网络内其他容器通信
docker network disconnect 将容器从网络断开 -f 强制断开 docker network disconnect multi-host-network my_container1 动态管理容器网络连接,避免不必要的通信
docker network rm 删除 1 个或多个网络 -f 强制删除 docker network rm br0
docker network rm -f br0
删除前请确保网络未被容器使用
docker network prune 删除未被容器使用的网络 -f/--force 跳过确认提示 docker network prune
docker network prune -f
清理无用网络,释放资源

网络详解

docker Bridge 网络

网络介绍

Docker Bridge 网络采用内置的 bridge 驱动,bridge 驱动底层采用的是 Linux 内核中 Linux bridge 技术。就网络而言,bridge 网络是在网络段之间转发流量的链路层设备,而网桥可以是在主机内核中运行的硬件设备或软件设备;就 Docker 而言,桥接网络使用软件网桥 docker0,它允许连接到同一网桥网络的容器进行通信,同时提供与未连接到该网桥网络容器的隔离。Docker Container 的 bridge 桥接模式可以参考下图:

network

默认情况下,创建的容器在没有使用–network 参数指定要加入的 docker 网络时,默认都是加入 Docker 默认的单机桥接网络,即下面的 name 为 bridge 的网络

# 查看 docker 支持的网络
docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
0cb86abb53fb   bridge    bridge    local
bdd23adf8d35   host      host      local
6a68de0c74cb   none      null      local

默认的 bridge 网络会被映射到内核中为 docker0 的网桥上。Docker 默认的 bridge 网络和 Linux 内核中的 docker0 网桥是一一对应的关系。bridge 是 Docker 对网络的命名,而 docker0 是内核中网桥的名字。

cnet

说人话,就是 docker0 和 回环网络、宿主机网络坐一桌,他是你在安装 Docker 时自动创建的网络。

操作案例

容器间的网络通信

回忆一下之前学到网络知识:多台主机是如何通过网络中进行通信的?如果是两台主机可以直接通过连接网线的两端进行通信。那多台主机通信怎么处理呢?这就需要新增路由器/交换机,把多台主机连接到路由器/交换机上, 通过路由器/交换机来达到交换数据, 即通信的目的。

host connect

其实容器之间的通信也和上面主机通信的方式如出一辙, 之前我们提到了安装 Docker 的时候会默认 docker0 这个网桥软件设备, 这个 docker0 设备可以类比成上图的交换机/路由器设备,当我们创建好容器之后, 如果不手动指定网络模式,默认会使用 bridge 网络, 容器会自动连接到 docker0 这个网桥设备, 然后通过这个网桥来进行容器间的通信。

下面我们来做一个实验验证一下:

1. 容器创建与默认网络连接

docker run -itd --name c1 busybox:stable-glibc
docker run -itd --name c2 busybox:stable-glibc
  • 使用 -itd 参数:以交互模式、终端分配、后台运行方式创建容器
  • 未指定 --network 参数:容器自动连接到 Docker 的默认 bridge 网络(docker0)
  • 两个容器共享同一个网络命名空间下的默认网络环境

2. 网络接口信息检查

docker container exec -it c1 ip a
docker container exec -it c2 ip a

输出显示:

  • c1 容器:IP 地址 172.17.0.2/16
  • c2 容器:IP 地址 172.17.0.3/16
  • 网络接口:均为 eth0,通过 veth pair 与宿主机 docker0 网桥连接
  • 子网掩码:/16(255.255.0.0),属于 B 类私有地址范围

3. 容器间网络连通性测试

docker container exec -it c1 ping 172.17.0.3  # c1 ping c2
docker container exec -it c2 ping 172.17.0.2  # c2 ping c1

测试结果:

  • 双向 ping 通成功,平均延迟约 0.07ms
  • 10 个数据包零丢包,证明网络连接稳定
  • 确认容器在同一个子网内可直接通信

4. 网络配置详细分析

docker network inspect bridge

网络配置信息揭示:

  • 子网范围172.17.0.0/16(Docker 自动分配的默认子网)
  • 网关地址172.17.0.1(docker0 网桥的 IP 地址)
  • 容器连接:明确显示 c1 和 c2 都连接到该网络
  • MAC 地址:每个容器有唯一的 MAC 地址(e2:12:71:88:b8:12a6:67:b2:49:c6:e2
# 网络配置的容器相关信息
 "Containers": {
            "1a85c7a4042e55ca7bfe387e783690e9896473c3177cd7c153367e9b0c0ab787": {
                "Name": "c2",
                "EndpointID": "829b047a4dacae8e6586d6538e8876d654ead877625d6c350d3fddf3e94444fa",
                "MacAddress": "a6:67:b2:49:c6:e2",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "a762babced39202b7a637f2c674d24d5d3a6f729cd555e8029377504525f1424": {
                "Name": "c1",
                "EndpointID": "8eda16569ac629bca03d2192be481ebc37170cc4f5600f06d65eba38f7169768",
                "MacAddress": "e2:12:71:88:b8:12",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },

5. 网络状态动态变化演示

docker container stop c1
docker network inspect bridge

状态变化:

  • 停止 c1 容器后,网络配置中的 Containers 部分仅剩 c2
  • 演示了 Docker 网络的动态管理特性:容器退出时自动从网络中解除连接
# 只剩下容器 c2
"Containers": {
            "1a85c7a4042e55ca7bfe387e783690e9896473c3177cd7c153367e9b0c0ab787": {
                "Name": "c2",
                "EndpointID": "829b047a4dacae8e6586d6538e8876d654ead877625d6c350d3fddf3e94444fa",
                "MacAddress": "a6:67:b2:49:c6:e2",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            }
        },

创建自定义 bridge

本实验展示了如何在 Docker 中创建一个自定义桥接网络(bridge),并在该网络上启动容器。下面是实验的详细过程解析及实际验证数据。


  1. 创建自定义桥接网络
docker network create -d bridge bridge1
  • -d bridge 指定网络驱动为桥接(bridge)。
  • bridge1 是自定义网络的名称。
  • 命令返回网络 ID:
    45518f3ee838699c7fcad67939d4164d05293c938345fdec30596af98a1707d4

  1. 查看自定义网络详情
docker network inspect bridge1

输出结果(核心字段):

{
  "Name": "bridge1",
  "Id": "45518f3ee838699c7fcad67939d4164d05293c938345fdec30596af98a1707d4",
  "Driver": "bridge",
  "EnableIPv4": true,
  "EnableIPv6": false,
  "IPAM": {
    "Driver": "default",
    "Config": [
      {
        "Subnet": "172.18.0.0/16",
        "Gateway": "172.18.0.1"
      }
    ]
  },
  "Containers": {}
}
  • SubnetGateway 显示自定义网络的 IPv4 地址段。
  • Containers 为空,说明当前网络没有容器连接。

  1. 在自定义网络上启动容器
docker container run -itd --name c1 --network bridge1 busybox:stable-glibc
  • --network bridge1 指定容器连接到自定义桥接网络。
  • 容器启动后分配到该网络的 IP 地址为 172.18.0.2
  • 容器 ID:07dd0135e6aa3328064a5e5379f175faaba4585cba3fe1d1ab421d1299752465

  1. 验证容器网络配置
docker container inspect c1 | grep "Networks" -A 17

输出核心部分:

"Networks": {
    "bridge1": {
        "MacAddress": "4a:94:20:87:ff:f6",
        "NetworkID": "45518f3ee838699c7fcad67939d4164d05293c938345fdec30596af98a1707d4",
        "EndpointID": "132b5f7e178cc1208768bed4f6b0c22db979c46673e74493824d86f3377dacff",
        "Gateway": "172.18.0.1",
        "IPAddress": "172.18.0.2",
        "IPPrefixLen": 16,
        "DNSNames": ["c1"]
    }
}
  • 可以看到容器 c1 已连接到 bridge1 网络。
  • IPAddress172.18.0.2Gateway172.18.0.1
  • MacAddressEndpointID 显示网络接口的唯一标识。

  1. 验证网络容器列表
docker network inspect bridge1 | grep "Containers" -A 20

输出核心部分:

"Containers": {
    "07dd0135e6aa3328064a5e5379f175faaba4585cba3fe1d1ab421d1299752465": {
        "Name": "c1",
        "EndpointID": "132b5f7e178cc1208768bed4f6b0c22db979c46673e74493824d86f3377dacff",
        "MacAddress": "4a:94:20:87:ff:f6",
        "IPv4Address": "172.18.0.2/16",
        "IPv6Address": ""
    }
}
  • 通过 Containers 字段可以确认容器 c1 已成功连接到自定义桥接网络。
  • IPv4Address 与前面 inspect 输出一致,验证了网络分配的正确性。

  • Docker 允许用户创建自定义桥接网络,通过 docker network create -d bridge <name> 实现。
  • 容器连接到自定义桥接网络后,可以在该网络内部进行通信,IP 地址由 Docker 自动分配。
  • 使用 docker network inspect <network> 可以查看网络拓扑、IP 段以及连接的容器信息。

DNS 解析实验

本实验旨在验证 Docker 容器内部的 DNS 解析功能,以及默认网桥(bridge)网络下的 DNS 行为。实验通过在自定义 bridge 和默认 bridge 网络上启动容器并尝试通过容器名互相 ping,观察 DNS 是否可用。下面是详细实验过程解析及事实依据。


  1. 创建自定义桥接网络
docker network create -d bridge bridge1
  • -d bridge 指定网络类型为桥接。
  • bridge1 是自定义网络名称。
  • 创建成功返回网络 ID:
    7901308cf3c5b1af9a1dd6bb6a147c6b7e5ee582d72f2484ba610a8d495190ed

  1. 在自定义网络上启动容器
docker container run -itd --name c1 --network bridge1 busybox:stable-glibc
docker container run -itd --name c2 --network bridge1 busybox:stable-glibc
docker network inspect bridge1 | grep "Containers" -A 20
"Containers": {
    "11483dc55da7ec1caad1f1034c59713a5b58a82b2ba1eb2c2e98bba2e40c6711": {
        "Name": "c2",
        "EndpointID": "6d570105ac556afb400c09664bb9d9b43b9a58641d29e1b1b3b1f3e1f64ef869",
        "MacAddress": "c2:8b:1b:c7:38:d7",
        "IPv4Address": "172.18.0.3/16",
        "IPv6Address": ""
    },
    "6aacf832a36e81f5081aa65e120bddab119c2e8c775667f89a0f293e8574df30": {
        "Name": "c1",
        "EndpointID": "cd17740ebed4d03176a47e148472539aa64acd3c82970f10aa69e61839151754",
        "MacAddress": "86:5f:df:c0:c4:92",
        "IPv4Address": "172.18.0.2/16",
        "IPv6Address": ""
    }
}
  • 容器 c1c2 连接到自定义网络 bridge1

  • 分配 IP 地址分别为:

    • c1172.18.0.2
    • c2172.18.0.3

  1. 验证容器互通(自定义网络)
docker exec -it c1 ping c2

输出结果:

PING c2 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.086 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.090 ms
docker exec -it c2 ping c1

输出结果:

PING c1 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.044 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.069 ms
  • 结论:在自定义桥接网络中,容器可以通过名称相互解析 IP 并通信,DNS 解析可用。

  1. 在默认 bridge 网络上启动容器
docker container run -itd --name c3 busybox:stable-glibc
docker container run -itd --name c4 busybox:stable-glibc
docker network inspect bridge | grep "Containers" -A 20
"Containers": {
    "12f82693d0ff14dc42898759dc0c9ee834180b43459ef437eb82ac07a2972e59": {
        "Name": "c4",
        "EndpointID": "e1f56c1067c73ac70d8f3f178bae22d3aac8942fccc47946de4f50ea1f34811d",
        "MacAddress": "8a:c7:39:b2:a2:d9",
        "IPv4Address": "172.17.0.3/16",
        "IPv6Address": ""
    },
    "c8bf0c6d3fa3c36a3fefb4307083b89af9be3c531e1a3f2fb48345d0e095ab67": {
        "Name": "c3",
        "EndpointID": "d7a05b4995fe7e8b11e212f66ac3293df3a6ba7e4582b7b610416b18cfdd6b64",
        "MacAddress": "1a:26:32:dc:09:5d",
        "IPv4Address": "172.17.0.2/16",
        "IPv6Address": ""
    }
}
"Options": {
    "com.docker.network.bridge.default_bridge": "true",
    "com.docker.network.bridge.enable_icc": "true",
    "com.docker.network.bridge.enable_ip_masquerade": "true",
    "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
  • 容器 c3c4 默认连接到 Docker 默认 bridge 网络。

  • 分配 IP 地址分别为:

    • c3172.17.0.2
    • c4172.17.0.3

  1. 验证容器互通(默认网络)
docker exec -it c3 ping c4

输出结果:

ping: bad address 'c4'
docker exec -it c4 ping c3

输出结果:

ping: bad address 'c3'
  • 结论:在 Docker 默认桥接网络下,容器名无法进行 DNS 解析,必须使用 IP 地址通信。

总结:

  1. 自定义桥接网络(bridge1)支持容器通过名称互相 DNS 解析。
  2. Docker 默认桥接网络(bridge)不支持容器名 DNS 解析,只能通过 IP 地址通信。
  3. 实验通过 ping 验证和 docker network inspect 输出数据为实验事实依据,展示了 DNS 行为的差异。

docker Host 网络

网络介绍

Docker 容器运行默认都会分配独立的 Network Namespace 隔离子系统, 但是如果基于 host 网络模式,容器将不会获得一个独立的 Network Namespace,而是和宿主机共用同一个 Network Namespace,容器将不会虚拟出自己的网卡,IP 等,而是直接使用宿主机的 IP 和端口。

host

连接到 host 网络的容器共享宿主机的网络栈,容器的网络配置与宿主机完全一样。我们可以通过 –network=host 指定使用 host 网络

下面我们通过实验来验证 host 网络的行为。

# 通过 Host 方式创建并启动容器 c1
┌─[root@VM-16-15-debian] - [/home/ljx/lib] - [2169]
└─[$] docker container run -itd --name c1 --network=host busybox:stable-glibc
ffd86b4df415e69582595858f038ab72cd219da6cb47f0433253652243434fa3
# 查看容器的网络信息
┌─[root@VM-16-15-debian] - [/home/ljx/lib] - [2170]
└─[$] docker exec -it c1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq qlen 1000
    link/ether 52:54:00:57:45:ed brd ff:ff:ff:ff:ff:ff
    inet 10.0.16.15/22 brd 10.0.19.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe57:45ed/64 scope link
       valid_lft forever preferred_lft forever
3: lxcbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue qlen 1000
    link/ether 00:16:3e:00:00:00 brd ff:ff:ff:ff:ff:ff
    inet 10.0.3.1/24 brd 10.0.3.255 scope global lxcbr0
       valid_lft forever preferred_lft forever
    inet6 fe80::216:3eff:fe00:0/64 scope link
       valid_lft forever preferred_lft forever
7: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue
    link/ether 56:3e:0d:4b:c9:bc brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::543e:dff:fe4b:c9bc/64 scope link
       valid_lft forever preferred_lft forever
# 容器的网络信息和宿主机网络信息完全一样
┌─[root@VM-16-15-debian] - [/home/ljx/lib] - [2171]
└─[$] ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 52:54:00:57:45:ed brd ff:ff:ff:ff:ff:ff
    altname enp0s5
    altname ens5
    inet 10.0.16.15/22 brd 10.0.19.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe57:45ed/64 scope link
       valid_lft forever preferred_lft forever
3: lxcbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 00:16:3e:00:00:00 brd ff:ff:ff:ff:ff:ff
    inet 10.0.3.1/24 brd 10.0.3.255 scope global lxcbr0
       valid_lft forever preferred_lft forever
    inet6 fe80::216:3eff:fe00:0/64 scope link
       valid_lft forever preferred_lft forever
7: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 56:3e:0d:4b:c9:bc brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::543e:dff:fe4b:c9bc/64 scope link
       valid_lft forever preferred_lft forever

使用场景

• 之前我们提到 bridge 网络在通信的时候需要进行端口转发以及 NAT 地址转换,这势必会消耗掉一些资源以及性能。
• 那么直接使用 host 网络最大的好处就是性能好,如果容器对网络传输效率有较高的要求,建议选择 host 网络。当然也会牺牲一些东西,比如要考虑端口冲突问题,其它服务已经被占用的端口就不能再使用了

docker Container 网络

网络介绍

Docker Container 的 other container 网络模式是 Docker 中一种较为特别的网络的模式。之所以称为“other container 模式”,是因为这个模式下的 Docker Container,会使用其他容器的网络环境。之所以称为“特别”,是因为这个模式下容器的网络隔离性会处于 bridge 桥接模式与 host 模式之间。Docker Container 共享其他容器的网络环境,则至少这两个容器之间不存在网络隔离,而这两个容器又与宿主机以及除此之外其他的容器存在网络隔离。

Docker Container 的 other container 网络模式可以参考下图:

container

Docker Container 的 --network=container:<other_container> 模式实现逻辑

在 Docker 中,容器可以使用其他容器的网络命名空间(network namespace),实现共享网络配置的效果。这种模式通常使用 --network=container:<other_container> 指定。其实现逻辑如下:

  1. 查找目标容器的网络命名空间

    • Docker 会首先定位 <other_container> 容器的 network namespace。
    • network namespace 是 Linux 内核提供的机制,用于隔离容器的网络栈,包括 IP 地址、路由表、端口等。
  2. 将新容器绑定到目标网络命名空间

    • 新创建的容器不会创建自己的网络 namespace。
    • 相反,它会共享 <other_container> 的 network namespace,包括 IP、端口映射、路由等。
    • 这样,两个容器就像共享同一个网络接口,可以互相访问,并且对外表现为同一个网络实体。
  3. 实现效果

    • 新容器与 <other_container> 容器拥有完全相同的网络环境。
    • 新容器内使用 ifconfigip a 查看 IP 时,会显示与 <other_container> 一致。
    • 端口占用也是共享的,如果 <other_container> 已绑定端口,新容器不能再绑定同样的端口。
  • 在这个模式下,new_container 并没有独立的 IP 地址,它完全依赖 other_container 的网络配置。
  • 常用于 sidecar 容器模式,例如日志收集或代理容器需要与主业务容器共享网络。

这个模式与普通 bridge 或 host 网络模式不同,它本质上是直接复用已有容器的网络命名空间,而不是创建新的网络栈或桥接。

操作案例

在本实验中,验证了 Docker 容器共享网络命名空间的行为及其对容器生命周期的依赖。实验步骤与数据如下:

  1. 创建第一个容器 c1
docker run -itd --name c1 busybox:stable-glibc

输出容器 ID:

0908b5475c78a131c558880d921838df028a44ed5950ae0e4eba4d78127b35dc

查看 c1 的网络信息:

docker exec -it c1 ip a

结果:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet 127.0.0.1/8 scope host lo
      valid_lft forever preferred_lft forever
   inet6 ::1/128 scope host
      valid_lft forever preferred_lft forever
2: eth0@if183: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
   link/ether fa:03:a5:9a:33:41 brd ff:ff:ff:ff:ff:ff
   inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
      valid_lft forever preferred_lft forever
  1. 创建第二个容器 c2,使用 c1 的网络 namespace
docker run -itd --name c2 --network container:c1 busybox:stable-glibc

输出容器 ID:

e18ed7418a91b1ae782502c13cb7a666822904fca5945f20d92ba0e2806a51f0

查看 c2 网络信息:

docker exec -it c2 ip a

结果显示:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet 127.0.0.1/8 scope host lo
      valid_lft forever preferred_lft forever
   inet6 ::1/128 scope host
      valid_lft forever preferred_lft forever
2: eth0@if183: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
   link/ether fa:03:a5:9a:33:41 brd ff:ff:ff:ff:ff:ff
   inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
      valid_lft forever preferred_lft forever

可以看到,c1 与 c2 的 eth0 IP 信息完全一致,说明 c2 成功共享了 c1 的网络 namespace。

  1. 停止 c1 容器
docker stop c1

查看 c2 网络信息:

docker exec -it c2 ip a

结果显示:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet 127.0.0.1/8 scope host lo
      valid_lft forever preferred_lft forever
   inet6 ::1/128 scope host
      valid_lft forever preferred_lft forever

c1 停止后,c2 的 eth0 消失,说明共享网络命名空间依赖于源容器的运行状态。

  1. 重新启动 c1
docker start c1

查看 c2 网络信息:

docker exec -it c2 ip a

结果显示:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet 127.0.0.1/8 scope host lo
      valid_lft forever preferred_lft forever
   inet6 ::1/128 scope host
      valid_lft forever preferred_lft forever

即便 c1 已重启,c2 仍然没有 eth0,共享网络未自动恢复。

  1. 重启 c2 容器
docker restart c2

查看网络信息:

docker exec -it c2 ip a

结果显示:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet 127.0.0.1/8 scope host lo
      valid_lft forever preferred_lft forever
   inet6 ::1/128 scope host
      valid_lft forever preferred_lft forever
2: eth0@if185: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
   link/ether 4e:2b:53:0a:a9:99 brd ff:ff:ff:ff:ff:ff
   inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
      valid_lft forever preferred_lft forever

重启 c2 后,eth0 恢复,与 c1 再次共享网络 namespace,实验验证了 Docker 的容器网络共享逻辑。


实验结论:

  1. 使用 --network container:<other_container> 时,目标容器和新容器完全共享网络 namespace,包括 IP 和端口映射。
  2. 源容器停止会导致共享容器网络接口丢失。
  3. 源容器重启不会自动恢复共享网络,必须重启共享容器以重新绑定网络 namespace。

docker none 网络

网络介绍

none 网络就是指没有网络。挂在这个网络下的容器除了 lo(本地回环),没有其他任何网卡

如下所示:

┌─[root@VM-16-15-debian] - [/home/ljx/lib] - [2190]
└─[$] docker container run -itd --name c1 --network=none busybox:stable-glibc
064824ac172793be62616e267e7d2edaf24108e853be2abace4d522178183761
┌─[root@VM-16-15-debian] - [/home/ljx/lib] - [2191]
└─[$] docker exec -it c1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever

使用场景

• 针对一些对安全性要求比较高并且不需要联网的应用, 可以使用 none 网络, 比如生成随机密码, 避免生成密码被第三方获取。
• 一些第三方的应用可能需要 docker 帮忙创建一个没有网络的容器, 网络由第三方自己来配置