我有一个工作群设置和滚动更新部署。由于我必须在部署后执行一些任务(例如数据库迁移),因此我向堆栈添加了“管理器”服务。这项服务仅限于节点管理器 - 所以我总有办法找到它。
要获取当前的容器ID,我使用以下命令:
export MANAGER_ID=$(docker --tls ps --filter label=com.docker.swarm.service.name=projectname-php-manager -q)
这有效......但在部署期间无效。
stack deploy
很快就会退出(在容器启动之前),甚至在管理器容器更新之前退出。我还在获取容器ID之前添加了sleep 10
,但结果有所不同。
有没有办法等待或知道特定服务何时部署?
完整部署如下所示(在 gitlab-ci 作业中完成 - 但这不是问题的根源):
deploy:staging:
variables:
DOCKER_HOST: "tcp://swarm-manager.hostname.tld:2376"
DOCKER_CERT_PATH: "/home/gitlab-runner/docker/swarm-manager.hostname.tld"
VERSION_TAG: "$CI_COMMIT_TAG"
MYSQL_PROD_PASSWORD: "$MYSQL_PROD_PASSWORD"
SECRET_TOKEN: "$SECRET_TOKEN"
script:
- docker --tls stack deploy -c docker-compose.prod.yml project-name --with-registry-auth --prune
- sleep 10
- export MANAGER_ID=$(docker --tls ps --filter label=com.docker.swarm.service.name=project-name_php-manager -q)
- docker --tls exec -t $MANAGER_ID bin/console doctrine:migrations:migrate --no-interaction --allow-no-migration
stage: deploy
environment:
name: staging
url: http://projectname.com
only: [tags]
cache: ~
dependencies:
- build:app
tags:
- deploy
来自 docker-compose.prod.yml 的部分:
php-manager:
image: dockerhub.mydomain.tld/namespace/projectname/php:${VERSION_TAG}
environment:
DATABASE_URL: "mysql://projectname:${MYSQL_PROD_PASSWORD}@mysql:3306/projectname?charset=utf8mb4&serverVersion=5.7"
APP_ENV: prod
APP_SECRET: "${SECRET_TOKEN}"
VERSION: "${VERSION_TAG}"
REDIS_HOST: redis
networks:
- default
deploy:
placement:
constraints: [node.role == manager]
replicas: 1
restart_policy:
condition: on-failure
Docker 堆栈部署创建任务,尝试使系统达到您想要的状态。有时任务会成功,有时会失败,编排器将生成新任务,直到系统与 yml 文件中描述的状态匹配。
坏消息:docker stack deploy 不支持阻塞,直到达到你想要的状态。
这里有一些如何使用 docker cli 和基本 bash 工具获取您想要的信息(您肯定可以在任何其他语言中以类似的方式实现)
在 bash 中,您可以执行
docker service ls --format '{{.ID}} {{.Name}}' | grep ${serviceName}
来获取服务的 ServiceId(它是返回的两个单词中的第一个)
根据docs docker service ps 所做的:
列出一项或多项服务的任务
它还添加了一些有关任务“当前状态”的信息,这是您关心的信息。
然后你使用
docker service ps ${ServiceId} --format '{{.CurrentState}} {{.Image}}' | grep Running.*${newImageName}
如果此命令返回某些内容,则表明有一个容器正在使用您的新映像运行。万岁:)
我希望这能向您介绍您需要的所有工具。 Docker 服务 ps 也有助于找出任务失败的原因。
仅供参考:根据Swarm 任务状态文档,任务状态的可能值是:
NEW 任务已初始化。
PENDING 该任务的资源已分配。
ASSIGNED Docker 将任务分配给节点。
ACCEPTED 该任务已被工作节点接受。如果一个工作节点 拒绝任务,状态更改为 REJECTED。
PREPARING Docker 正在准备任务。
STARTING Docker 正在启动任务。
RUNNING 任务正在执行。
完成任务已退出且没有错误代码。
FAILED 任务退出并出现错误代码。
SHUTDOWN Docker 请求关闭任务。
REJECTED 工作节点拒绝了任务。
ORPHANED 节点关闭时间过长。