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 での MySQL 8.0.11 のインストールに関するチュートリアル

1. 公式サイトにアクセスしてインストールパッケージをダウンロードしますダウンロードリンク: クリッ...

テーブルタグ(テーブル)詳細

<br />テーブルは、昔から誰もが使ってきたタグで、今も使われています。しかし、現在の...

Discuz! フォーラムに設定オプションを追加する方法

Discuz! フォーラムにはバックグラウンドで多くの設定オプションがあり、これらの設定オプションを...

Vueストレージにはブール値のソリューションが含まれています

Vueはブール値でストレージを保存します今日、問題に遭遇しました。バックグラウンドから返された真偽の...

要素ツリーコントロールは、ドロップダウンメニューとアイコンを統合します(ツリー+ドロップダウン+入力)

目次要件:実装手順:この記事では主に以下について説明します: カスタムツリーコントロール<el...

MyCat を使用して Linux で MySQL マスター/スレーブの読み取り/書き込み分離を実装する方法

目次Linux - MyCat を使用して MySQL マスター スレーブの読み取り書き込み分離を実...

MySQL InnoDBセカンダリインデックスのソート例の詳細な説明

ソート問題最近、Geek Time の「45 Lectures on MySQL Practice」...

Docker で既存のイメージに基づいて新しいイメージを構築する方法

既存のイメージから新しいイメージを構築することは、Dockerfile ドキュメントを通じて行われま...

MySQLコマンドが中国語で入力できない問題の解決方法

問題を見つける最近、MySQL コマンドを使用して MySQL サーバーに接続したときに、以下のよう...

Dockerはjenkins+mavenコード構築および展開プラットフォームを構築します

目次Docker の基本概念Docker インストール プロセス (Centos6.9)カーネルのア...

Linuxファイルの基本属性の知識ポイントのまとめ

Linux システムは典型的なマルチユーザー システムです。異なるユーザーは異なる立場にあり、異なる...

MySQL 操作: JSON データ型の操作

前回の記事では、MySQL データ保存手順パラメータの詳細な例を紹介しました。今日は、JSON デー...

Linux オペレーティング システムの概要と紹介

目次1. オペレーティングシステムとは何か2. Linuxの起源3. Linuxの基本機能4. Li...

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

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

Mysqlアカウント管理の原理と実装方法の詳細な説明

この記事では、例を使用して、MySQL アカウント管理の原則と実装方法を説明します。ご参考までに、詳...