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 驱动程序来启用多主机通信。

覆盖网络始终作为 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:
    # Use a custom driver
    driver: custom-driver-1
  backend:
    # Use a custom driver which takes special options
    driver: custom-driver-2
    driver_opts:
      foo: "1"
      bar: "2"

可以通过为每个连接的网络设置 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 的网络并将您的应用程序的容器连接到它。

更多参考资料

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