docker compose サービスの起動順序を制御する方法

docker compose サービスの起動順序を制御する方法

まとめ

Docker-compose は複数の Docker コンテナ サービスを簡単に組み合わせることができます。ただし、コンテナ サービス間に依存関係がある場合、Docker-compose はサービスの起動順序を保証できません。

docker-compose のdepends_on 構成はコンテナの起動順序であり、コンテナ内のサービスの起動順序ではありません。

問題の再現

まず、docker-compose によって発生する問題を示す例を作成しましょう。docker-compose.yml ファイルは次のとおりです。

バージョン: '2'
サービス:
 ウェブ:
  イメージ: ubuntu:14.04
  依存:
   - ウェブ
  コマンド: nc -z データベース 3306

 データベース:
  イメージ: ubuntu:14.04
  コマンド: >
   /bin/bash -c '
   睡眠5;
   echo "泊まる";
   0.0.0.0 3306; を出力します。
   '

起動後、最初にデータベースが起動し、次に Web が起動していることがわかりますが、約 5 秒後にデータベース内のサービスが完了してしまうため、Web の起動に失敗します。

$ docker-compose を起動します
tmp_database_1 を作成しています...完了
tmp_database_1 を作成しています...
tmp_web_1 を作成しています...完了
tmp_database_1、tmp_web_1 に接続しています
tmp_web_1 はコード 1 で終了しました
database_1 | 泊まる

問題解決方法 1.0

Web 起動スクリプトを変更し、サービスを開始する前にデータベース ポートが接続されるのを待ちます。

バージョン: '2'
サービス:
 ウェブ:
  イメージ: ubuntu:14.04
  依存:
   - データベース
  コマンド: >
   /bin/bash -c '
   !nc -z データベース 3306;
   する
    echo "データベースを待つ";
    睡眠1;
   終わり;

   echo "データベースの準備ができました!";
   echo "ここでWebサービスを開始します";
   '

 データベース:
  イメージ: ubuntu:14.04
  コマンド: >
   /bin/bash -c '
   睡眠5;
   echo "泊まる";
   0.0.0.0 3306; を出力します。
   '

再起動、

$ docker-compose を起動します
tmp_database_1 を作成しています...完了
tmp_database_1 を作成しています...
tmp_web_1 を作成しています...完了
tmp_database_1、tmp_web_1 に接続しています
web_1 | データベースを待つ
web_1 | データベースを待つ
web_1 | データベースを待つ
web_1 | データベースを待つ
web_1 | データベースを待つ
database_1 | 泊まる
web_1 | データベースが準備完了です!
web_1 | ここからウェブサービスを開始
tmp_web_1 はコード 0 で終了しました

データベースが起動し、ポートが接続されると、Web が起動します。

問題解決 2.0

上記の解決策で問題は解決できますが、スクリプトを yaml に直接挿入するとメンテナンスが難しくなり、エラーが発生しやすくなります。依存関係が複数ある場合や依存関係が複数層ある場合は、複雑さが急激に増加します。

したがって、起動コマンドと、待機するサービスおよびポートを受け入れることができる entrypoint.sh スクリプトをカプセル化する必要があります。スクリプトの内容は次のとおりです。

#!/bin/bash
#set -x
#****************************************************************************************
# @ファイル: entrypoint.sh
# @著者: ワンギュビン
# @日付: 2018-08-1 10:18:43
#
# @brief : サービス開始順序を管理するためのエントリ ポイント
# 履歴: 初期化
#****************************************************************************************

: ${SLEEP_SECOND:=2}

待機() {
  echo $1 が $2 でリッスンするのを待機しています...
  while ! nc -z $1 $2; do echo 待機中...; sleep $SLEEP_SECOND; 完了
}

宣言する DEPENDS
CMDを宣言する

getopts "d:c:" 引数の間
する
  ケース$arg in
    d)
      依存=$OPTARG
      ;;
    c)
      コマンド=$OPTARG
      ;;
    ?)
      echo "不明な引数"
      出口1
      ;;
  エサック
終わり

${DEPENDS//,/ } 内の変数の場合
する
  ホスト=${var%:*}
  ポート=${var#*:}
  wait_for $ホスト $ポート
終わり

$CMDを評価する

このスクリプトには 2 つのパラメーターがあります。-d は待機するサービスとポート、-c はサービスとポートが開始された後の起動コマンドです。

docker-compose.yml を変更し、entrypoint.sh スクリプトを使用して起動順序を制御します。

バージョン: '2'
サービス:
 ウェブ:
  イメージ: ubuntu:14.04
  依存:
   - データベース
  ボリューム:
   - 「./entrypoint.sh:/entrypoint.sh」
  エントリポイント: /entrypoint.sh -d database:3306 -c 'echo "ここで Web サービスを開始します"';

 データベース:
  イメージ: ubuntu:14.04
  コマンド: >
   /bin/bash -c '
   睡眠5;
   echo "泊まる";
   0.0.0.0 3306; を出力します。
   '

実際の使用では、ボリューム構成を通じて entrypoint.sh スクリプトをロードしなくても、公開されたイメージに entrypoint.sh をパッケージ化することもできます。

テスト結果は次のとおりです。

$ docker-compose を起動します
tmp_database_1 を開始しています...完了しました
tmp_web_1 を起動しています...完了
tmp_database_1、tmp_web_1 に接続しています
web_1 | データベースが 3306 でリッスンするのを待機しています...
web_1 | 待機中...
web_1 | 待機中...
web_1 | 待機中...
database_1 | 泊まる
web_1 | ここからウェブサービスを開始
tmp_web_1 はコード 0 で終了しました

補充する

複数のサービスとポートに依存

上記の entrypoint.sh スクリプトを使用すると、-d パラメータの後に複数のサービスとポートをコンマ (,) で区切ることで、複数のサービスとポートに依存することもできます。

バージョン: '2'
サービス:
 ウェブ:
  イメージ: ubuntu:14.04
  依存:
   -MySQLについて
   - PostgreSQL
  ボリューム:
   - 「./entrypoint.sh:/entrypoint.sh」
  エントリポイント: /entrypoint.sh -d mysql:3306,postgresql:5432 -c 'echo "ここで Web サービスを開始します"';

 マイスク:
  イメージ: ubuntu:14.04
  コマンド: >
   /bin/bash -c '
   睡眠4;
   echo "泊まる";
   0.0.0.0 3306; を出力します。
   '
 PostgreSQL:
  イメージ: ubuntu:14.04
  コマンド: >
   /bin/bash -c '
   睡眠8;
   echo "泊まる";
   0.0.0.0 5432; を出力します。
   '

実行効果を自分で試すことができます。

試行間隔の設定

各接続試行の待機時間は、環境変数 SLEEP_SECOND で設定できます。デフォルトは 2 秒です。以下の設定で待機時間を 4 秒に設定すると、4 秒ごとに MySQL サービスへの接続が試行されます。

バージョン: '2'
サービス:
 ウェブ:
  イメージ: ubuntu:14.04
  環境:
   睡眠時間: 4
  依存:
   -MySQLについて
  ボリューム:
   - 「./entrypoint.sh:/entrypoint.sh」
  エントリポイント: /entrypoint.sh -d mysql:3306 'echo "ここで Web サービスを開始します"';

 マイスク:
  イメージ: ubuntu:14.04
  コマンド: >
   /bin/bash -c '
   睡眠4;
   echo "泊まる";
   0.0.0.0 3306; を出力します。
   '

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • Docker Compose サービスオーケストレーションの詳細な説明

<<:  Vue はカードフリップカルーセル表示を実装します

>>:  MySQL 5.7 zip版(zip版)のインストールと設定手順の詳細

推薦する

JavaScript の基本: ループと配列

目次ループ - for forループの基本的な使い方ループを終了するネストされたループ配列配列とは何...

この記事では、MySQLのマスタースレーブ同期の原理を説明します。

目次MySQL マスタースレーブ同期原理の簡単な分析1. マスタースレーブとは何ですか? 2. 主従...

Docker マイクロサービス用の ETCD クラスターの構築に関する詳細なチュートリアル

目次etcdの機能etcdが独自の高可用性クラスタを構築するには、主に3つの形式があります。今回構築...

nginx における proxy_pass のさまざまな使用法の詳細な説明

目次プロキシ転送ルール最初のもの: 2番目のタイプ: 3番目のタイプ: 4番目のタイプ: 5番目:プ...

MySQL 5.7.11 zip インストールと設定方法のグラフィックチュートリアル

1. MySQL 5.7.11 zipインストールパッケージをダウンロードするこのマシンはwin7 ...

Mysql データベースのマスタースレーブ同期構成

目次Mysql マスタースレーブ同期構成1. 2つのmysqlをインストールする2. MySQL設定...

CSSポジションの5つの異なる値の使い方の詳細な説明

位置プロパティposition プロパティは、要素に使用する配置方法のタイプ (静的、相対的、固定、...

Docker がポート 2375 を公開し、サーバー攻撃を引き起こす問題と解決策

docker リモート API を学習した学生であれば、ポート 2375 についてよくご存知だと思い...

vue data が関数である理由をご存知ですか?

公式サイトの説明: コンポーネントを定義する場合、コンポーネントは複数のインスタンスを作成するために...

最小限のルートファイルシステムを構築するためにbusyboxを移植するための詳細な手順

Busybox: 小さなコマンドが詰まったスイスアーミーナイフ。ステップ1: ディレクトリ構造を作成...

MySQL DML言語操作例

追加説明、外部キー: 外部キーを使用しないでください。すべての外部キーの概念はアプリケーション層で解...

入力テキストボックスの入力実装プロパティを無効にする

今日は、開発でよく使われる、非常に便利な HTML タグをいくつかまとめてみたいと思います。これらの...

CentOS 8.1 で LEMP (Linux+Nginx+MySQL+PHP) 環境を構築する (チュートリアルの詳細)

目次ステップ1: CentOS 8でパッケージを更新するステップ2: CentOS 8にNginx ...

MySQL における SQL ページングクエリのいくつかの実装方法と利点と欠点

【SQL】SQLページングクエリの概要開発プロセスではページングが必要になることがよくあります。今日...

HTML テーブル マークアップ チュートリアル (29): セルのライト境界線の色属性 BORDERCOLORLIGHT

セルでは、明るい境界線の色を個別に定義できます。 > 基本構文<TD ボーダーカラーライ...