Featured image of post Docker 网络:从桥接网络到覆盖网络Featured image of post Docker 网络:从桥接网络到覆盖网络

Docker 网络:从桥接网络到覆盖网络

Docker 网络的完整指南,涵盖桥接、主机、覆盖网络、DNS 解析、端口映射、隔离、Swarm 多主机网络和 Compose 模式。

介绍

Docker 容器被设计为可移植和隔离的,但它们很少单独运行。容器需要相互通信、与主机系统以及外部服务通信。了解 Docker 的网络模型对于构建可靠、安全和高性能的容器化应用程序至关重要。

Docker 提供了多种内置网络驱动程序——bridge、host、overlay、macvlan、ipvlan 和 none——每种驱动程序都适合不同的用例。本指南深入介绍了每个驱动程序,以及 DNS 解析、端口映射、安全隔离和 Docker Compose 网络模式。


了解 Docker 网络驱动程序

每个容器都有一个连接到主机的虚拟网络接口(veth 对)。 Docker 使用 网络命名空间 为每个容器提供一个独立的网络堆栈,并拥有自己的 IP 地址、路由表和端口。

docker network 命令是管理网络的控制中心:

# List all networks
docker network ls

# Create a user-defined bridge network
docker network create my-network

# Inspect network details
docker network inspect my-network

# Connect a running container to a network
docker network connect my-network my-container

下面是 Docker 内置网络驱动的比较:

司机范围使用案例DNS解析
桥梁单主机独立容器的默认值仅限用户定义
主持人单主机低延迟,无需隔离不适用(主机 DNS)
覆盖多主机Swarm 服务、跨主机通信是的
麦克弗兰单主机需要 MAC 地址的旧版应用程序是的
ipvlan单主机高性能、大型子网是的
单主机最大程度的隔离

桥接网络的实践

桥接网络是 Docker 的默认驱动程序。当 Docker 启动时,它会在主机上创建一个名为 docker0 的虚拟网桥,并默认从 172.17.0.0/16 子网分配容器 IP。

默认网桥有局限性:没有自动 DNS 解析,并且所有容器都无隔离地连接。 用户定义的桥解决这些问题:

docker network create my-app-net

docker run -d --name web --net my-app-net nginx
docker run -d --name api --net my-app-net node:18

同一用户定义桥上的容器可以通过容器名称相互解析:

# From the api container, this resolves to web's IP
ping web

端口发布通过 iptables DNAT 规则将主机端口映射到容器端口:

# Map host port 8080 to container port 80
docker run -p 8080:80 nginx

主机和覆盖网络

主机网络

使用 --network host,容器直接共享主机的网络堆栈 — 无 NAT,无虚拟接口,并且延迟最小。这对于性能基准测试或需要监视主机接口的应用程序非常有用。但是,不存在网络隔离:容器可以绑定到任何主机端口并可能干扰其他服务。

# docker-compose.yml
services:
  benchmark:
    image: tool:latest
    network_mode: "host"

覆盖网络

覆盖网络支持跨多个 Docker 主机进行通信。在 Swarm 模式下,创建覆盖网络会自动将其分发到所有节点:

docker network create -d overlay --attachable my-overlay

在底层,覆盖网络使用 VXLAN 封装来包装容器数据包,允许它们穿越物理网络边界。可以使用 --opt encrypted 标志通过 IPsec 对流量进行加密。性能开销约为每个数据包 50 字节,吞吐量降低 5-10%。


DNS解析和服务发现

Docker 在每个容器内的 127.0.0.11 处运行嵌入式 DNS 服务器。该服务器将容器名称解析为用户定义的桥接和覆盖网络上的 IP 地址。默认桥提供 DNS 解析 - 您必须使用 --link (旧版)或切换到用户定义的桥。

在 Swarm 模式下,Docker DNS 为具有多个副本的服务提供循环解析:

# Create a service with 3 replicas
docker service create --name api --replicas 3 --network my-overlay my-api:latest

# Other containers resolve "api" to one of the 3 replicas via DNS round-robin

自定义 DNS 设置可以应用于每个容器:

docker run --dns 8.8.8.8 --dns-search example.com nginx

端口映射和安全隔离

端口映射将主机端口转换为容器端口。 -p 标志接受格式 hostPort:containerPort/protocol

# Multiple ports, specific interface binding
docker run -p 127.0.0.1:8080:80 -p 443:443 nginx

对于网络隔离,Docker提供了几种机制:

  • 内部网络 (--internal) — 容器无法访问互联网。
  • 无网络 (--network none) — 仅环回,最大隔离。
  • 单独的网桥 — 根据信任级别将容器保留在不同的用户定义的网桥上。

Docker 没有像 Kubernetes 那样内置网络策略。要进行细粒度控制,请使用 iptables、firewalld 或第三方插件,例如 Calico、Weave 或 Cilium。


Docker Compose 网络模式

Docker Compose 为每个项目创建一个用户定义的桥接网络 (<project>_default)。您可以在 Compose 文件中定义多个自定义网络来分隔关注点:

services:
  web:
    image: nginx
    networks:
      - frontend
      - backend
  db:
    image: postgres
    networks:
      - backend
  redis:
    image: redis
    networks:
      - backend

networks:
  frontend:
  backend:

此模式将面向公众的 Web 层与内部数据层分开。 web 服务连接到两个网络,而 dbredis 只能在内部 backend 网络上访问。

要连接到预先存在的网络(例如共享监控网络),请使用外部网络:

networks:
  monitoring:
    external: true

扩展服务时,每个副本在同一网络上都有自己的容器。将 depends_onhealthcheckcondition 结合使用以确保服务准备就绪,而不是仅依赖启动顺序。


结论

Docker 的网络模型为容器通信提供了灵活、安全且高性能的选项。从针对单主机多容器应用程序的用户定义的桥接网络开始 - 它们提供自动 DNS 解析和比默认桥接更好的隔离。对于多主机部署,请使用带有 Docker Swarm 的 覆盖网络

设计网络拓扑时:

  1. 优先选择基于 DNS 的服务发现,而不是硬编码的 IP 地址。
  2. 使用单独的桥接网络根据信任级别隔离各层。
  3. 仅当延迟或接口访问至关重要时才选择主机网络。
  4. 利用 Compose 网络定义使您的基础设施具有声明性和可复制性。

docker network inspectdocker exec 的网络问题调试到容器中以运行 ip addrtcpdump,并检查防火墙规则是否存在跨主机连接问题。有了这些基础知识,您就可以构建强大且易于管理的容器网络。