一、Docker 网络基础

Docker 容器在运行时需要与外界通信(例如,访问互联网,与其他容器或宿主机通信,或被外部访问)。Docker 提供了多种网络模式来满足这些需求,每种模式决定了容器如何连接到网络以及与其他网络实体如何交互。

Docker 默认支持以下几种网络模式:

  1. 桥接模式 (bridge): 默认模式,最常用。
  2. 宿主机模式 (host): 容器直接使用宿主机的网络栈。
  3. 无网络模式 (none): 容器没有网络接口。
  4. 容器模式 (container): 容器共享另一个容器的网络命名空间。
  5. 覆盖网络 (overlay): 用于 Docker Swarm 集群或多主机通信。
  6. Macvlan 模式 (macvlan): 为容器分配 MAC 地址,使其在物理网络上显示为物理设备。
  7. 自定义网络: 用户自定义配置的网络。

二、桥接模式 (bridge) - 默认模式详解

这是 Docker 创建容器时默认使用的网络模式。

工作原理
  1. 虚拟网桥 (docker0): Docker 守护进程启动时,会在宿主机上创建一个名为 docker0 的虚拟以太网桥。其作用类似于物理交换机。
  2. 虚拟网卡 (veth pair): 当创建一个容器时:
    • Docker 会创建一对虚拟以太网设备 (veth pair)。
    • 一端 (vethXXX) 连接到 docker0 网桥上。
    • 另一端 (eth0) 放入容器的网络命名空间 (namespace),作为容器内的默认网络接口 eth0
  3. IP 地址分配: Docker 会从 docker0 网桥的子网中(默认为 172.17.0.0/16)为容器内的 eth0 分配一个 IP 地址。docker0 网桥本身也有一个 IP 地址(如 172.17.0.1),通常作为该子网的网关。
  4. 容器间通信: 连接到同一个 docker0 网桥的容器,其 eth0 接口都在同一个子网内。它们可以通过各自的 IP 地址直接通信(例如,172.17.0.2 可以直接 ping 172.17.0.3)。通信数据包通过 docker0 网桥进行二层交换转发。
  5. 容器访问外部网络 (出站):
    • 容器尝试访问外部 IP(如 8.8.8.8)。
    • 流量通过容器的 eth0 发出,到达 docker0 网桥。
    • 宿主机内核会根据路由规则,将目的地址不是本机或本子网的流量转发到其默认网关(通常是宿主机的物理网卡 eth0 的网关)。
    • 宿主机内核会启用 IP 伪装 (IP Masquerading)网络地址转换 (NAT)。它会将容器的源 IP 地址(如 172.17.0.2)替换为宿主机物理接口 eth0 的 IP 地址,然后发送出去。
    • 外部服务器将响应发送回宿主机的 eth0 IP。
    • 宿主机内核根据 NAT 规则将响应转发回对应的容器。
  6. 外部访问容器 (入站):
    • 默认情况下,外部网络无法直接通过容器的 IP 地址(如 172.17.0.2)访问容器,因为该 IP 是私有地址。
    • 要暴露容器服务,需要使用 -p--publish 选项进行端口映射
      docker run -p 8080:80 nginx
      
    • 此命令告诉 Docker:将宿主机的 8080 端口映射到容器的 80 端口。
    • 当外部用户访问 <宿主机IP>:8080 时:
      • 流量到达宿主机的 8080 端口。
      • Docker 监听到此端口的流量,根据映射规则,将流量转发到对应容器的 80 端口。
      • 这通常是通过在宿主机的 iptables 中添加 DNAT 规则实现的。
特点
  • 优点:
    • 容器拥有独立的网络命名空间和 IP 地址,网络隔离性好。
    • 容器间通信方便(同主机内)。
    • 通过端口映射可以灵活地暴露服务。
    • 易于配置和管理。
  • 缺点:
    • 性能稍低于 host 模式(有虚拟化开销)。
    • 默认情况下,容器间需要通过 IP 地址通信(除非使用用户自定义桥接网络,它支持 DNS 服务发现)。
    • 入站访问需要显式端口映射。

三、宿主机模式 (host)

在这种模式下,容器创建自己的网络命名空间,而是直接使用宿主机的网络栈。容器内的网络接口(如 eth0)看到的配置和流量与宿主机完全一致。

工作原理
  • 容器启动时添加 --network=host 参数:
    docker run --network=host nginx
    
  • 容器内的应用程序可以直接使用宿主机的 IP 地址和所有端口号。例如,容器内的 Nginx 监听 80 端口,就相当于在宿主机上监听 80 端口。
特点
  • 优点:
    • 网络性能最好(几乎没有虚拟化开销)。
    • 无需端口映射,容器服务天然可用。
  • 缺点:
    • 安全性最差:容器与宿主机网络完全共享,容器应用可能干扰宿主机的网络配置或服务(如占用端口)。
    • 容器失去独立的网络隔离性。
    • 无法为容器分配独立的 IP 地址。

四、宿主机网络

宿主机网络是指运行 Docker 引擎的物理服务器或虚拟机本身的网络配置。它通常包括:

  1. 物理网卡 (eth0, enpXsY 等): 连接物理网络。
  2. IP 地址、子网掩码、网关: 配置在物理网卡或虚拟接口上。
  3. 路由表: 决定数据包如何转发。
  4. 防火墙 (iptables/nftables, firewalld 等): 控制进出宿主机的流量。
  5. DNS 配置: 用于宿主机自身的域名解析。

五、Docker 网络与宿主机网络的关系

  1. 隔离与共享:
    • bridge 模式下,Docker 容器通过虚拟网桥 docker0veth pair 与宿主机网络连接,但拥有独立的网络命名空间。容器访问外部网络需要通过宿主机的 NAT。
    • host 模式下,容器直接共享宿主机的网络栈,没有隔离。
  2. 通信路径:
    • 容器 <-> 容器 (同主机): 在 bridge 模式下,通过 docker0 网桥直接通信(二层)。在 host 模式下,等同于宿主机上两个进程通信(如 localhost)。
    • 容器 <-> 宿主机: 在 bridge 模式下,容器可以通过 docker0 网桥的 IP (如 172.17.0.1) 访问宿主机上的服务。宿主机也可以通过容器的 IP 访问容器。在 host 模式下,就是 localhost 通信。
    • 容器 <-> 外部网络: 在 bridge 模式下,必须经过宿主机的物理网卡和 NAT。在 host 模式下,直接通过宿主机网卡。
  3. 端口映射: 这是 bridge 模式下实现外部访问容器服务的关键机制,由 Docker 管理并在宿主机的防火墙规则中体现。
  4. 网络配置影响: 宿主机的网络配置(如防火墙规则、路由表)会直接影响 Docker 容器的网络访问能力(尤其是外部访问)。

六、其他模式简要说明

  • none: 容器只有 lo 回环接口,无网络连接。用于完全隔离网络或需要自定义网络配置的场景。
  • container:<name|id>: 新容器共享指定容器的网络命名空间。两个容器网络配置完全相同(IP, port等)。适用于紧密协作的容器组。
  • overlay: 用于跨多个 Docker 宿主机构建一个虚拟网络,使不同主机上的容器能够像在同一子网内一样通信。是 Docker Swarm 的核心网络。
  • macvlan: 为容器分配一个 MAC 地址,并直接绑定到宿主机的物理接口。容器在物理网络上显示为一个独立的设备,拥有自己的 MAC 和 IP。适用于需要容器直接接入物理网络(如获取 DHCP 地址)的场景。
  • 自定义网络: 用户可以创建自己的桥接网络、覆盖网络或 Macvlan 网络,提供更好的隔离性、DNS 服务发现等特性。

七、查看网络配置

  • 查看宿主机网络接口: ip addrifconfig
  • 查看宿主机路由表: ip routeroute -n
  • 查看宿主机防火墙规则 (iptables): iptables -t nat -nvL (查看 NAT 表)
  • 查看 Docker 网络列表: docker network ls
  • 查看特定 Docker 网络详情: docker network inspect <network_name_or_id>
  • 查看容器网络配置: docker inspect <container_name_or_id> | grep -i "IPAddress\|ports" 或查看 NetworkSettings 部分。

理解 Docker 的网络模式及其与宿主机网络的关系对于部署、管理和调试容器化应用至关重要。桥接模式提供了良好的平衡,而其他模式则在特定场景下有其优势。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐