在线文档教程
Docker 17
撰写 | Compose

Using Compose with Swarm

与 Swarm 一起使用 Compose

您正在查看传统独立群组的文档。这些主题描述了独立的 Docker Swarm。在 Docker 1.12 及更高版本中,Swarm 模式与 Docker Engine 集成。大多数用户应该使用集成的 Swarm 模式 - 一个好的开始就是 Swarm 模式入门, Swarm 模式 CLI 命令以及 Docker 演练入门。独立 Docker Swarm 未集成到 Docker Engine API 和 CLI 命令中。

Docker Compose 和 Docker Swarm 旨在实现完全集成,这意味着您可以将一个Compose应用程序指向一个 Swarm 集群,并且只需像使用单个 Docker 主机一样工作即可。

实际的集成范围取决于您使用的 Compose 文件格式的版本:

  • 如果您使用的是版本1 links,则您的应用程序可以正常工作,但Swarm会将所有容器安排在一台主机上,因为容器之间的链接不适用于使用旧网络系统的主机。

  • 如果您使用的是第2版,则您的应用程序应该无任何更改:

- subject to the [limitations](index#limitations) described below, - as long as the Swarm cluster is configured to use the [overlay driver](../../engine/userguide/networking/index#an-overlay-network-with-docker-engine-swarm-mode), or a custom driver which supports multi-host networking.

阅读多主机网络入门以了解如何使用 Docker Machine 和覆盖驱动程序设置 Swarm 群集。运行后,将应用程序部署到该应用程序应该如此简单:

$ eval "$(docker-machine env --swarm <name of swarm master machine>)" $ docker-compose up

局限性

构建图像

Swarm 可以像 Docker 实例一样通过 Dockerfile 构建镜像,但生成的镜像只能存在于单个节点上,不会分配给其他节点。

如果您想使用 Compose 将服务扩展到多个节点,则必须自己构建它,将其推送到注册表(例如 Docker Hub)并从docker-compose.yml以下位置引用它:

$ docker build -t myusername/web . $ docker push myusername/web $ cat docker-compose.yml web: image: myusername/web $ docker-compose up -d $ docker-compose scale web=3

多重依赖

如果一个服务具有强制联合调度类型的多个依赖关系(参见下面的自动调度),那么 Swarm 可能会调度依赖关系到不同的节点上,从而无法安排依赖服务。例如,这里foo需要被共同调度与barbaz

version: "2" services: foo: image: foo volumes_from: ["bar"] network_mode: "service:baz" bar: image: bar baz: image: baz

问题是,群可能会先安排barbaz不同的节点上(因为他们是不依赖于彼此),使它不可能挑选一个合适的节点foo

要解决此问题,请使用手动调度来确保所有三个服务都在同一个节点上结束:

version: "2" services: foo: image: foo volumes_from: ["bar"] network_mode: "service:baz" environment: - "constraint:node==node-1" bar: image: bar environment: - "constraint:node==node-1" baz: image: baz environment: - "constraint:node==node-1"

主机端口和重新创建容器

如果服务从主机映射端口,例如80:8000,那么docker-compose up在第一次之后运行它时可能会出现类似下面的错误:

docker: Error response from daemon: unable to find a node that satisfies container==6ab2dfe36615ae786ef3fc35d641a260e3ea9663d6e69c5b70ce0ca6cb373c02.

这种错误的常见原因是容器在没有显式映射的情况下具有一个卷(在其图像或撰写文件中定义),因此为了保留其数据,Compose 已指示 Swarm 安排新容器与旧容器相同的节点。这导致了端口冲突。

解决这个问题有两个可行的解决办法:

  • 指定一个已命名的卷,并使用一个卷驱动程序,该卷驱动程序能够将该卷挂载到容器中,而不管其预定在哪个节点上。如果服务仅使用命名卷,则Compose不会为Swarm提供任何特定的计划指示。版本:“2”服务:web:build:。端口: - “80:8000”卷: - web-logs:/ var / log / web卷:web-logs:driver:custom-volume-driver

  • 在创建新容器之前删除旧容器。您将失去该卷中的任何数据。

  • $ docker-compose stop web

调度容器

自动调度

某些配置选项将导致容器在同一个 Swarm 节点上自动进行调度,以确保它们正常工作。这些是:

  • network_mode: "service:..."network_mode: "container:..."(以及net: "container:..."第一版文件格式)。

  • volumes_from

  • links

手动调度

Swarm 提供了丰富的时间安排和亲和力提示,使您能够控制容器的位置。它们通过容器环境变量指定,因此您可以使用Compose 的environment选项来设置它们。

# Schedule containers on a specific node environment: - "constraint:node==node-1" # Schedule containers on a node that has the 'storage' label set to 'ssd' environment: - "constraint:storage==ssd" # Schedule containers where the 'redis' image is already pulled environment: - "affinity:image==redis"

有关完整的可用过滤器和表达式,请参阅 Swarm 文档

documentation, docs, docker, compose, orchestration, containers, swarm