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
需要被共同调度与bar
和baz
:
version: "2"
services:
foo:
image: foo
volumes_from: ["bar"]
network_mode: "service:baz"
bar:
image: bar
baz:
image: baz
问题是,群可能会先安排bar
和baz
不同的节点上(因为他们是不依赖于彼此),使它不可能挑选一个合适的节点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