【问题标题】:Docker Swarm deploy - wait for service/container to be presentDocker Swarm 部署 - 等待服务/容器出现
【发布时间】:2018-04-20 01:44:09
【问题描述】:

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

要获取当前的 containerID,我使用以下命令:
export MANAGER_ID=$(docker --tls ps --filter label=com.docker.swarm.service.name=projectname-php-manager -q)

这有效...但在部署期间无效。

stack deploy 很快就会退出(在容器启动之前),甚至在管理器容器更新之前。 在获取 containerID 之前,我还添加了 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 compose 你可以使用“depends_on”来“等待”一个容器:docs.docker.com/compose/compose-file/#depends_on我不确定你在部署堆栈时是否可以使用它(当然你在使用版本 3 Compose 文件以 swarm 模式部署堆栈时无法使用它。)
  • 您可以在 docker_compose 文件中使用depends_on 属性,该属性一个接一个地执行 docker 图像。
  • depends_on 不是解决方案。因为对于滚动更新,我(或 gitlab-ci 作业)依赖于运行当前的管理器容器。其他服务不关心它。我认为@herm 在服务.CurrentState 的轮询中走在了正确的轨道上,我会试一试。
  • 堆栈部署也不支持“depends_on”
  • 有一个open issue 可以将此功能添加到docker stack deploy

标签: docker continuous-deployment docker-swarm


【解决方案1】:

Docker stack deploy 创建任务,尝试使系统达到您想要的状态。有时任务成功,有时失败,编排器会生成新任务,直到系统匹配您的 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 task states documentation,任务状态的可能值是:

NEW 任务已初始化。

为该任务分配了 PENDING 资源。

ASSIGNED Docker 将任务分配给节点。

ACCEPTED 任务被工作节点接受。如果一个工作节点 拒绝任务,状态变为 REJECTED。

PREPARING Docker 正在准备任务。

STARTING Docker 正在启动任务。

RUNNING 任务正在执行。

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

FAILED 任务以错误代码退出。

SHUTDOWN Docker 请求关闭任务。

REJECTED 工作节点拒绝了任务。

ORPHANED 节点宕机时间过长。

【讨论】:

  • 同样,仅仅因为您的容器已启动并不意味着您的应用程序已准备好接收流量。为了确保您的应用程序准备就绪,您需要进行运行状况检查以确保它已准备就绪。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-23
  • 1970-01-01
  • 2019-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多