Dockerコンテナ内で2つのプロセスを開始するときのDockerfile実装コード

Dockerコンテナ内で2つのプロセスを開始するときのDockerfile実装コード

最近、cronスケジュールタスク用のdockerを作りたいと思っており、Dockerfileで次のように定義しています

library/alpine:latest より
apk --update add rsync openssh bash を実行します
ボリューム ["/data"]
start.sh を追加します /
コマンド ["/bin/bash","/start.sh"]

crontab を使用して、start.sh でスケジュールされたタスク run.cron をロードし、crond を開始します。

/usr/bin/crontab /run.cron

/usr/sbin/crond

docker build Dockerfile を実行後、docker run –name xxx -d を使用してコンテナを実行しました。start.sh の実行後にコンテナが終了し、スケジュールされたタスクをまったく開始できないことがわかりました。nohup の使用、無限ループ、シグナルの使用など、オンラインでさまざまな方法を試しましたが、どれも信頼できるものではないことがわかりました。

docker のメカニズムを分析した結果、docker コンテナは一度に 1 つのプロセスしか管理できないことがわかりました。プロセスが終了すると、コンテナも終了します。これは、コンテナ内で一度に 1 つのプロセスしか実行できない (それは無駄です) ことを意味するのではなく、最後に実行されているプロセスは終了できないことを意味します。

この場合、コンテナの起動時に start.sh が実行されます。crond のデフォルト設定はバックグラウンドで実行されるため、start.sh の実行が終了し、start.sh が終了するとコンテナが終了します。

したがって、start.sh では、crond をフォアグラウンドで強制的に実行する必要があります: crond -f。

この方法では start.sh は終了せず、docker run -d はコンテナをバックグラウンドで実行し続けることができます。

start.sh の概要:

(1)コンテナ内で複数のデーモンプロセスを実行する場合、最初のプロセスをバックグラウンドで実行する必要があります(または&を追加してください)。そうしないと、後続のサービスを開始できません。

(2)コンテナ内の最後のデーモンプロセスはフォアグラウンドモードで実行する必要があります。そうしないと、start.shが終了し、コンテナが終了し、すべてのサービスが無駄に開始されます。

ubuntu:latestから

mkdir -p "/usr/src/pdas" を実行します。
  mkdir -p "/usr/src/pdas/reload"

コピー bin.tar /usr/src/pdas
config.tar /usr/src/pdas をコピーします
lib.tar /usr/src/pdas をコピーする

ワークディレクトリ /usr/src/pdas
tar -xvf lib.tar && \ を実行します。
  tar -xvf bin.tar && \
  tar -xvf config.tar

ENV LD_LIBRARY_PATH /usr/src/pdas/lib/libxml/lib:/usr/src/pdas/lib/curl/lib:$LD_LIBRARY_PATH

ワークディレクトリ /usr/src/pdas/bin
chmod +x start.sh && \ を実行します。
  chmod +x f_recv && \
  chmod +x f_send

ボリューム /behb/diqu
ボリューム /var/log/pdas

エントリポイント ./start.sh

./start.shスクリプトは以下のとおりです

#!/bin/bash
./f_recv &
./f_send

上記は、Docker イメージの起動スクリプトに関するいくつかの考察です。

追加知識: Docker で複数のプロセスを処理する方法

通常、Docker コンテナは単一のプロセスを実行するのに適していますが、多くの場合、Docker コンテナ内で複数のプロセスを実行する必要があります。マルチプロセス コンテナを実行するには、シェル スクリプトを使用する方法とスーパーバイザーを使用する方法の 2 つがあります。どちらの方法もシンプルで、それぞれに長所と短所がありますが、注目すべき詳細がいくつかあります。ここではスクリプトを使用した処理方法についてのみ説明します。

スクリプト multiple_thread.sh を記述します。このスクリプトは 2 つの Python プログラムを実行し、結果をログ ファイルに保存します。スクリプトの内容は次のとおりです

#!/bin/bash
# 最初のプロセスを開始する
nohup python -u /tmp/thread1.py > /tmp/thread1.log 2>&1 &
ps aux |grep スレッド1 |grep -q -v grep
PROCESS_1_STATUS=$ ですか?
echo "thread1 のステータス..."
$PROCESS_1_STATUSをエコーする
[ $PROCESS_1_STATUS -ne 0 ]の場合;
echo "my_first_process の起動に失敗しました: $PROCESS_2_STATUS"
$PROCESS_1_STATUS を終了
フィ
睡眠5
# 2番目のプロセスを開始する
nohup python -u /tmp/thread2.py > /tmp/thread2.log 2>&1 &
ps aux |grep スレッド2 |grep -q -v grep
PROCESS_2_STATUS=$ ですか?
echo "thread2 ステータス..."
$PROCESS_2_STATUSをエコーする
[ $PROCESS_2_STATUS -ne 0 ]の場合;
echo "my_second_process の起動に失敗しました: $PROCESS_2_STATUS"
$PROCESS_2_STATUS を終了
フィ
# sleep 60; 中にプロセスが60秒ごとに実行されているかどうかを確認します
ps aux |grep スレッド1 |grep -q -v grep
PROCESS_1_STATUS=$ ですか?
ps aux |grep スレッド2 |grep -q -v grep
PROCESS_2_STATUS=$ ですか?
# 上記のgrepで何かが見つかった場合は、0ステータスで終了します
# 両方とも 0 でない場合は、何かがおかしい
[ $PROCESS_1_STATUS -ne 0 -o $PROCESS_2_STATUS -ne 0 ]の場合;
echo "プロセスの 1 つはすでに終了しています。"
出口1
フィ

次に、Dockerfile を作成します。

Centos:latest から
 
thread1.py をコピー /tmp/thread1.py
thread2.py をコピー /tmp/thread2.py
multiple_thread.sh をコピー /tmp/multiple_thread.sh
 
コマンド bash /tmp/multiple_thread.sh

Docker コンテナ内で 2 つのプロセスを開始するための上記の Dockerfile 実装コードは、私が皆さんと共有できるすべてです。これが皆さんの参考になれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • DockerはDockerfileを使用して、sshサービスの自動起動をサポートするコンテナイメージを作成します。
  • Docker コンテナで DockerFile を使用して複数の Tomcat サービスをデプロイする手順
  • MyEclipse でビルドした Java Web プロジェクトを Docker の Dockerfile コンテナーで実行する
  • Dockerfileを使用してシンプルなコンテナを作成する方法

<<:  innerHTML アプリケーション

>>:  JSの基本概念の詳細な紹介

推薦する

MySQL マスタースレーブ同期遅延の原因と解決策

歴史的な理由により、MySQL レプリケーションは、REDO ログではなく論理バイナリ ログに基づい...

HTML ページはダーク モードの実装をサポートします

2019年から、AndroidとiOSの両方のプラットフォームでダークモードが使用され始めました。も...

MySQLパラダイムの使用に関する詳細な説明

1. パラダイムこのパラダイムの英語名は Normal Form であり、1970 年代にリレーショ...

適応型ウェブページを設計および作成する方法

3G の普及により、携帯電話を使ってインターネットにアクセスする人が増えています。モバイル デバイス...

MySQL シリーズ 7 MySQL ストレージ エンジン

1. MyISAM ストレージエンジン欠点:トランザクションはサポートされていません最小粒度ロック:...

XHTML CSS ページをプリンタ ページに変換する

<br />これまで、Web ページのプリンタ対応バージョンを作成するには、印刷したとき...

Iframe の使用を減らすべきいくつかの理由の分析

次のグラフは、100 個の異なる要素で iframe を作成するのにどれくらいの時間がかかるかを示し...

Vue はユーザーのログイン状態を維持します (さまざまなトークン保存方法)

目次クッキーの設定方法クッキーのデメリット: LocalStorage と SessionStora...

JavaScript でドラッグ可能なプログレスバーを実装する

この記事では、ドラッグ可能なプログレスバーを実装するためのJavaScriptの具体的なコードを参考...

JavaScript で大きなファイルの並列ダウンロードを実装する方法

目次1. HTTP範囲リクエスト1.1 範囲構文2. 大きなファイルをダウンロードする方法2.1 補...

DOCTYPE宣言の機能と使い方の詳しい説明

1. ブラウザのレンダリングモードとdoctype一部の Web ページは標準に従って作成されていま...

jQueryは居住地を選択するためのドロップダウンボックスを実装します

居住地を選択するためのドロップダウンボックスをjQueryで実装するための具体的なコードは参考までに...

ボタンの権限判定を実装するためのVueカスタムv-has命令

アプリケーションシナリオバックグラウンド管理システムを例にとると、各ユーザーには異なるボタン権限があ...

Linux で rpm パッケージを見つけるために CD をマウントする方法

前面に書かれたLinux を使用する際にソフトウェアをインストールする必要がある場合があります。もち...

Linuxにおけるumaskコマンドの使用原理と計算方法の詳しい解説

目次umask umaskの使用法原理1. umask値2. ファイルディレクトリの最大権限3. 従...