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 可以从 web 通过主机名 dbdatabase 访问:

services:

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

查看 links reference 以获取更多信息。

多主机网络

在启用了Swarm模式的Docker引擎上部署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 的网络,并将你的应用程序的容器连接到它。

更多参考信息

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