Compose 中的网络

重要

Docker 的文档引用并描述了 Compose V2 的功能。

自 2023 年 7 月起,Compose V1 已停止接收更新,且不再包含在新的 Docker Desktop 版本中。Compose V2 已取代它,并集成到所有当前的 Docker Desktop 版本中。更多信息,请参阅 迁移到 Compose V2

默认情况下,Compose 会为应用设置一个单一的 网络。每个服务的容器都会加入该默认网络,既可以被该网络上的其他容器访问,也可以通过服务名称被发现。

注意

您的应用网络会根据“项目名称”进行命名,而项目名称则基于其所在目录的名称。您可以通过 --project-name 标志COMPOSE_PROJECT_NAME 环境变量 来覆盖项目名称。

例如,假设您的应用位于名为 myapp 的目录中,且您的 compose.yml 如下所示:

services:
  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres
    ports:
      - "8001:5432"

当您运行 docker compose up 时,将发生以下情况:

  1. 已创建一个名为 myapp_default 的网络。
  2. 容器是使用 web 的配置创建的。它以名称 web 加入网络 myapp_default
  3. 容器是使用 db 的配置创建的。它以名称 db 加入网络 myapp_default

每个容器现在都可以查找服务名称 webdb,并获取相应容器的 IP 地址。例如,web 的应用程序代码可以连接到 URL postgres://db:5432 并开始使用 Postgres 数据库。

值得注意的是 HOST_PORTCONTAINER_PORT 之间的区别。 在上述示例中,对于 dbHOST_PORT8001,而容器端口为 5432(Postgres 默认端口)。网络化的服务间通信使用 CONTAINER_PORT。当定义了 HOST_PORT 时, 该服务在 Swarm 外部也可访问。

web 容器内,您连接到 db 的连接字符串将类似于postgres://db:5432;而从主机机器出发,连接字符串将类似于 postgres://{DOCKER_IP}:8001,例如,如果您的容器在本地运行,则为 postgres://localhost:8001

更新网络上的容器

如果您对服务进行了配置更改并运行 docker compose up 来更新它,旧容器将被移除,新容器将以不同的 IP 地址但相同的名称加入网络。正在运行的容器可以查找该名称并连接到新地址,但旧地址将不再生效。

如果有任何容器与旧容器建立了开放连接,这些连接将被关闭。检测此条件、重新查找名称并重新连接是容器自身的责任。

提示

尽可能通过名称而非 IP 地址来引用容器。否则,您将需要不断更新所使用的 IP 地址。

链接允许您定义额外的别名,以便一个服务可以通过这些别名访问另一个服务。启用服务通信并不需要链接。默认情况下,任何服务都可以通过该服务的名称访问任何其他服务。在以下示例中,db 可以从 web 通过主机名 dbdatabase 访问:

services:

  web:
    build: .
    links:
      - "db:database"
  db:
    image: postgres

请参阅 链接参考以获取更多信息。

多主机网络

当在启用了 Swarm 模式 的 Docker Engine 上部署 Compose 应用程序时,您可以使用内置的 overlay 驱动程序来启用多主机通信。

覆盖网络始终创建为 attachable。您可以选择将 attachable 属性设置为 false

请参阅 Swarm 模式部分,了解如何设置 Swarm 集群,以及 多主机网络入门指南 ,以了解多主机覆盖网络。

指定自定义网络

除了仅使用默认的应用程序网络外,您还可以使用顶层 networks 键指定自己的网络。这使您能够创建更复杂的拓扑结构,并指定 自定义网络驱动程序和选项。您还可以使用它将服务连接到不由 Compose 管理的外部创建的网络。

每个服务都可以通过服务级别的 networks 键指定要连接的网络,该键是一个名称列表,引用顶层 networks 键下的条目。

以下示例展示了一个 Compose 文件,该文件定义了两个自定义网络。proxy 服务与 db 服务是隔离的,因为它们没有共享任何公共网络。只有 app 可以同时与两者通信。

services:
  proxy:
    build: ./proxy
    networks:
      - frontend
  app:
    build: ./app
    networks:
      - frontend
      - backend
  db:
    image: postgres
    networks:
      - backend

networks:
  frontend:
    # Specify driver options
    driver: bridge
    driver_opts:
      com.docker.network.bridge.host_binding_ipv4: "127.0.0.1"
  backend:
    # Use a custom driver
    driver: custom-driver

可以通过为每个附加网络设置 ipv4_address 和/或 ipv6_address,使用静态 IP 地址配置网络。

网络也可以被赋予一个 自定义名称

services:
  # ...
networks:
  frontend:
    name: custom_frontend
    driver: custom-driver-1

配置默认网络

除了(或同时)指定您自己的网络外,您还可以通过在 networks 下定义一个名为 default 的条目来更改应用范围默认网络的设置:

services:
  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres

networks:
  default:
    # Use a custom driver
    driver: custom-driver-1

使用现有网络

如果您希望容器加入一个已存在的网络,请使用 external 选项

services:
  # ...
networks:
  network1:
    name: my-pre-existing-network
    external: true

Compose 不会尝试创建一个名为 [projectname]_default 的网络,而是查找名为 my-pre-existing-network 的网络,并将您应用的容器连接到该网络。

更多参考信息

有关可用网络配置选项的完整详情,请参阅以下参考资料: