Docker Swarm 部署 - 等待服务/容器出现

问题描述 投票:0回答:1

我有一个工作群设置和滚动更新部署。由于我必须在部署后执行一些任务(例如数据库迁移),因此我向堆栈添加了“管理器”服务。这项服务仅限于节点管理器 - 所以我总有办法找到它。

要获取当前的容器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 continuous-deployment docker-swarm
1个回答
25
投票

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 节点关闭时间过长。

© www.soinside.com 2019 - 2024. All rights reserved.