web-dev-qa-db-ja.com

DockerSwarmデプロイ-サービス/コンテナーが存在するのを待ちます

スウォームのセットアップとローリングアップデートの展開が機能しています。展開後にいくつかのタスク(データベースの移行など)を実行する必要があるため、スタックに「マネージャー」サービスを追加しました。このサービスはノードマネージャーに限定されているので、私は常にそれを見つける方法があります。

現在の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
12
Rufinus

Dockerスタックデプロイは、システムを目的の状態にしようとするタスクを作成します。タスクが成功することもあれば失敗することもあり、システムがymlファイルに記述されている状態と一致するまで、オーケストレーターは新しいタスクを生成します。

悪いニュース:docker stack deployは、目的の状態に達するまでブロッキングをサポートしません。

ここでは、docker cliと基本的なbashツール(他の言語でも同様の方法で確実に実装できます)を使用して必要な情報を取得する方法をいくつか紹介します。

Bashでは、docker service ls --format '{{.ID}} {{.Name}}' | grep ${serviceName}を実行して、サービスのServiceIdを取得できます(返される2つの単語の最初の単語)

docs docker service psによると:

1つ以上のサービスのタスクを一覧表示します

また、気になる情報であるタスク「現在の状態」に関する情報を追加します。

次に、docker service ps ${ServiceId} --format '{{.CurrentState}} {{.Image}}' | grep Running.*${newImageName}を使用します

このコマンドが何かを返す場合は、新しいイメージで実行されているコンテナがあります。やあ:)

これにより、必要なすべてのツールが紹介されることを願っています。 Dockerサービスpsは、タスクが失敗した理由を見つけるのにも役立ちます。

参考: 群れのタスク状態のドキュメント によるタスク状態の可能な値は次のとおりです。

NEWタスクが初期化されました。

タスクの保留中のリソースが割り当てられました。

ASSIGNEDDockerはタスクをノードに割り当てました。

ACCEPTEDタスクがワーカーノードによって受け入れられました。ワーカーノードがタスクを拒否すると、状態はREJECTEDに変わります。

準備中Dockerはタスクを準備しています。

開始Dockerがタスクを開始しています。

実行中タスクは実行中です。

COMPLETEタスクはエラーコードなしで終了しました。

FAILEDタスクはエラーコードで終了しました。

SHUTDOWNDockerがタスクにシャットダウンを要求しました。

REJECTEDワーカーノードがタスクを拒否しました。

ORPHANEDノードが長時間ダウンしていました。

15
herm