将堆栈部署到 Swarm
在 Swarm 模式下运行 Docker Engine 时,可以使用 docker stack deploy
将完整的应用程序堆栈部署到 Swarm。deploy
命令接受 Compose 文件形式的堆栈描述。
注意
docker stack deploy
命令使用由 Compose V1 使用的旧版 Compose 文件版本 3 格式。由 Compose specification 定义的最新格式与docker stack deploy
命令不兼容。有关 Compose 演变的更多信息,请参阅Compose 历史。
要运行本教程,你需要
一个运行在Swarm 模式下的 Docker Engine。如果你不熟悉 Swarm 模式,你可能想阅读Swarm 模式核心概念和服务工作原理。
注意
如果你在本地开发环境中尝试,可以使用
docker swarm init
将你的 Engine 置于 Swarm 模式。如果你已经有一个多节点 Swarm 在运行,请记住所有
docker stack
和docker service
命令都必须从管理器节点运行。最新版本的Docker Compose。
设置 Docker 注册表
由于 Swarm 由多个 Docker Engine 组成,因此需要一个注册表来将镜像分发给所有 Engine。你可以使用 Docker Hub 或维护自己的注册表。下面是如何创建一个临时注册表,你可以在事后将其丢弃。
在你的 Swarm 上将注册表作为服务启动
$ docker service create --name registry --publish published=5000,target=5000 registry:2
使用
docker service ls
检查其状态$ docker service ls ID NAME REPLICAS IMAGE COMMAND l7791tpuwkco registry 1/1 registry:2@sha256:1152291c7f93a4ea2ddc95e46d142c31e743b6dd70e194af9e6ebe530f782c17
当它在
REPLICAS
下显示1/1
时,表示它正在运行。如果显示0/1
,则可能仍在拉取镜像。使用
curl
检查它是否正常工作$ curl http://127.0.0.1:5000/v2/ {}
创建示例应用程序
本指南中使用的应用程序基于 Docker Compose 入门指南中的点击计数器应用程序。它由一个 Python 应用程序组成,该应用程序在 Redis 实例中维护一个计数器,并在你每次访问时增加该计数器。
为项目创建目录
$ mkdir stackdemo $ cd stackdemo
在项目目录中创建名为
app.py
的文件并粘贴以下内容from flask import Flask from redis import Redis app = Flask(__name__) redis = Redis(host='redis', port=6379) @app.route('/') def hello(): count = redis.incr('hits') return 'Hello World! I have been seen {} times.\n'.format(count) if __name__ == "__main__": app.run(host="0.0.0.0", port=8000, debug=True)
创建名为
requirements.txt
的文件并粘贴以下两行flask redis
创建名为
Dockerfile
的文件并粘贴以下内容# syntax=docker/dockerfile:1 FROM python:3.4-alpine ADD . /code WORKDIR /code RUN pip install -r requirements.txt CMD ["python", "app.py"]
创建名为
compose.yaml
的文件并粘贴以下内容services: web: image: 127.0.0.1:5000/stackdemo build: . ports: - "8000:8000" redis: image: redis:alpine
Web 应用程序的镜像使用上面定义的 Dockerfile 构建。它还使用
127.0.0.1:5000
进行了标记,这是之前创建的注册表的地址。这在将应用程序分发到 Swarm 时很重要。
使用 Compose 测试应用
使用
docker compose up
启动应用程序。这将构建 Web 应用程序镜像,如果你还没有 Redis 镜像,它将拉取 Redis 镜像,并创建两个容器。你会看到关于 Engine 处于 Swarm 模式的警告。这是因为 Compose 不会利用 Swarm 模式,并且会将所有内容部署到单个节点。你可以安全地忽略此警告。
$ docker compose up -d WARNING: The Docker Engine you're using is running in swarm mode. Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers are scheduled on the current node. To deploy your application across the swarm, use `docker stack deploy`. Creating network "stackdemo_default" with the default driver Building web ...(build output)... Creating stackdemo_redis_1 Creating stackdemo_web_1
使用
docker compose ps
检查应用程序是否正在运行$ docker compose ps Name Command State Ports ----------------------------------------------------------------------------------- stackdemo_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp stackdemo_web_1 python app.py Up 0.0.0.0:8000->8000/tcp
你可以使用
curl
测试应用程序$ curl http://localhost:8000 Hello World! I have been seen 1 times. $ curl http://localhost:8000 Hello World! I have been seen 2 times. $ curl http://localhost:8000 Hello World! I have been seen 3 times.
停止应用程序
$ docker compose down --volumes Stopping stackdemo_web_1 ... done Stopping stackdemo_redis_1 ... done Removing stackdemo_web_1 ... done Removing stackdemo_redis_1 ... done Removing network stackdemo_default
将生成的镜像推送到注册表
要将 Web 应用程序的镜像分发到整个 Swarm,需要将其推送到之前设置的注册表。使用 Compose,这非常简单
$ docker compose push
Pushing web (127.0.0.1:5000/stackdemo:latest)...
The push refers to a repository [127.0.0.1:5000/stackdemo]
5b5a49501a76: Pushed
be44185ce609: Pushed
bd7330a79bcf: Pushed
c9fc143a069a: Pushed
011b303988d2: Pushed
latest: digest: sha256:a81840ebf5ac24b42c1c676cbda3b2cb144580ee347c07e1bc80e35e5ca76507 size: 1372
堆栈现在已准备好部署。
将堆栈部署到 Swarm
使用
docker stack deploy
创建堆栈$ docker stack deploy --compose-file compose.yaml stackdemo Ignoring unsupported options: build Creating network stackdemo_default Creating service stackdemo_web Creating service stackdemo_redis
最后一个参数是堆栈的名称。每个网络、卷和服务名称都将带有堆栈名称前缀。
使用
docker stack services stackdemo
检查它是否正在运行$ docker stack services stackdemo ID NAME MODE REPLICAS IMAGE orvjk2263y1p stackdemo_redis replicated 1/1 redis:3.2-alpine@sha256:f1ed3708f538b537eb9c2a7dd50dc90a706f7debd7e1196c9264edeea521a86d s1nf0xy8t1un stackdemo_web replicated 1/1 127.0.0.1:5000/stackdemo@sha256:adb070e0805d04ba2f92c724298370b7a4eb19860222120d43e0f6351ddbc26f
一旦它开始运行,你应该会在两个服务的
REPLICAS
下看到1/1
。如果你有多节点 Swarm,这可能需要一些时间,因为需要拉取镜像。和之前一样,你可以使用
curl
测试应用程序$ curl http://localhost:8000 Hello World! I have been seen 1 times. $ curl http://localhost:8000 Hello World! I have been seen 2 times. $ curl http://localhost:8000 Hello World! I have been seen 3 times.
借助 Docker 内置的路由网格,你可以通过 Swarm 中的任何节点访问端口
8000
并被路由到应用程序$ curl http://address-of-other-node:8000 Hello World! I have been seen 4 times.
使用
docker stack rm
停止堆栈$ docker stack rm stackdemo Removing service stackdemo_web Removing service stackdemo_redis Removing network stackdemo_default
使用
docker service rm
停止注册表$ docker service rm registry
如果你只是在本地机器上测试,并且想让 Docker Engine 退出 Swarm 模式,请使用
docker swarm leave
$ docker swarm leave --force Node left the swarm.