Docker Swarm部署 - 等待服务/容器存在

时间:2017-11-07 15:29:09

标签: docker continuous-deployment docker-swarm

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

要获取当前的containerID,我使用此命令:
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

1 个答案:

答案 0 :(得分:10)

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 service ps也有助于找出任务失败的原因。

仅供参考:根据Swarm task states documentation,任务状态的可能值为:

  

新任务已初始化。

     

PENDING已分配任务的资源。

     

ASSIGNED Docker将任务分配给节点。

     

ACCEPTED工作节点接受了该任务。如果是工作节点   拒绝任务,状态变为REJECTED。

     

准备Docker正在准备任务。

     

启动Docker正在启动任务。

     

RUNNING任务正在执行。

     

COMPLETE退出任务时没有错误代码。

     

FAILED任务退出并显示错误代码。

     

SHUTDOWN Docker请求关闭任务。

     

拒绝工作人员节点拒绝了该任务。

     

ORPHANED节点停机时间过长。