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版)のインストールと設定手順の詳細

ブログ    

推薦する

Linux または Windows 環境での pytorch のインストールと検証 (runtimeerror 問題の解決)

1. pytorch公式サイトから対応するインストールファイルをダウンロードします。 https:...

Saltstack に Zabbix サービスをデプロイする方法を説明します

目次SaltstackがZabbixサービスを導入httpd、mysql、phpをインストールするh...

mysql バックアップ戦略の実装 (フルバックアップ + 増分バックアップ)

目次設計シナリオ技術的なポイントサーバー情報準備フルバックアップスクリプト(Mysql-FullyB...

要素の読み込み効果を実現するための純粋なHTML+CSS

これは Element UI の読み込みコンポーネントのエフェクトです。かっこいいですね。実装してみ...

nginxで複数のサーバーを簡単に構成する方法

1: nginx のインストール方法については詳しく説明しません。Baidu で検索してください。 ...

Linuxでプロセスが占有するポート番号を表示する

Linux システム管理者にとって、サービスがポートに正しくバインドされているか、またはポートをリッ...

Hyper-V の紹介とインストールと使用 (詳細な図解)

はじめに:IT 業界の巨人である Microsoft 独自の仮想化技術は、VMware や Citr...

Ubuntu 18.04 に phpMyAdmin をインストールするための詳細なチュートリアル

Ubuntu 18.04 上の Apache で動作するように phpMyAdmin をインストール...

ダイナミックな波効果を実現するSVG+CSS3

ベクトル波 <svg viewBox="0 0 560 20" class...

カルーセルの制作方法を実現するjs

この記事では、カルーセル画像の表示を実現するためのjsの具体的なコードを参考までに共有します。具体的...

MySQL で二重引用符の位置が誤っていたために起きた殺人事件の詳細な分析

1. はじめに最近、開発者が誤ってデータを削除したり更新したりするケースがよくあります。今回もまた問...

nginx のスムーズな再起動を実装する方法

1. 背景サーバーの開発プロセスでは、新しいコードや構成をロードするためにサービスを再起動することが...

MySQL 8.0.13 のインストールと設定方法のグラフィックチュートリアル (Win10 の場合)

MySQL 8.0.13 のインストールと設定方法を皆さんと共有したいと思います。お役に立てれば幸...

MySQL データベースは SQL ステートメントを知っている必要があります (拡張バージョン)

拡張版です。質問とSQL文は以下の通りです。ユーザー テーブルを作成し、id、name、gender...

JS での filter() 配列フィルターの使用

目次1. はじめに2. 方法の紹介3. 使用例要約する1. はじめに配列フィルターは、フロントエンド...