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 时,该服务也可以在集群外部访问。

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

更新网络上的容器

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

如果任何容器都与旧容器打开连接,则这些连接将被关闭。容器有责任检测此情况,再次查找名称并重新连接。

提示

尽可能按名称而不是 IP 引用容器。否则,您需要不断更新使用的 IP 地址。

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

services:

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

有关更多信息,请参阅 链接参考

多主机网络

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

Overlay 网络始终创建为 attachable(可连接的)。您可以选择将attachable 属性设置为 false

请参阅Swarm 模式部分,了解如何设置 Swarm 集群,并参阅多主机网络入门,了解有关多主机 Overlay 网络的更多信息。

指定自定义网络

您可以使用顶层 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

配置默认网络

除了或以及指定您自己的网络之外,您还可以通过在名为 defaultnetworks 下定义条目来更改应用程序范围的默认网络的设置。

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 的网络,并将应用程序的容器连接到该网络。

更多参考信息

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