Docker コンテナの正常なシャットダウン前にトラップを使用して環境のクリーンアップを実行する

Docker コンテナの正常なシャットダウン前にトラップを使用して環境のクリーンアップを実行する

実行中のコンテナが終了したときに、コンテナが完全に終了する前に環境をクリーンアップするなど、いくつかの定義済みアクションを実行するにはどうすればよいでしょうか。これはプレストップに似たフック体験です。ただし、Docker 自体はこの機能を提供することはできません。この記事では、Linux 組み込みコマンド トラップを組み合わせて、コンテナーが正常に閉じられる前にカスタム操作を実装します。

実行中のコンテナが終了したときに、コンテナが完全に終了する前に環境をクリーンアップするなど、いくつかの定義済みアクションを実行するにはどうすればよいでしょうか。これはプレストップに似たフック体験です。ただし、Docker 自体はこの機能を提供することはできません。この記事では、Linux 組み込みコマンド トラップを組み合わせて、コンテナーが正常に閉じられる前にカスタム操作を実装します。

コンテナを閉じる方法

実行中のコンテナをシャットダウンする方法は 3 つあり、いずれも docker コマンドラインによって開始されると理解しています。

  • 最初の方法はよりエレガントな方法ですdocker stop ContainerID
  • 2番目の方法はより恣意的であるようです: docker rm -f ContainerID
  • 3番目のタイプは、あまり使用されていませんdocker kill --signal=KILL ContainerID

Docker の設計者は、理由もなくコンテナをシャットダウンするための 3 つのコマンドの組み合わせを設計することはありません。どのようなシナリオで 3 つの方法を使用すべきでしょうか?

コンテナを終了するこれら 3 つの方法は、それぞれ若干異なります。これらの違いを説明する前に、コンテナとは関係ないと思われるいくつかの知識ポイント、つまり SIGNAL について触れておく必要があります。

プロセスとシグナル

ユーザーはシグナルを送信することでプロセスと通信できます。

ほぼすべての運用および保守エンジニアは、プロセスを強制終了するために次のコマンドを実行したことがあります。

キル -9 PID

このコマンドは正しいようです。プロセスを「強制終了」しましたが、なぜ「-9」なのでしょうか?

9 はシグナル SIGKILL のコードです。上記のコマンドは、実際に対応するプロセスにシグナルを送信します。このシグナルによって、プロセスが強制終了されます。

killコマンドの本当の意味は、プロセスに指定されたシグナルを送信することです。SIGKILL(9) に加えて、さまざまな他のシグナルを送信することもできます。

root@ubuntuserver:~# kill --help

kill: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... または kill -l [sigspec]

ジョブに信号を送信します。

root@ubuntuserver:~# kill -l

1) SIGHUP 2) シギント 3) シグクイット 4) シギル 5) シグトラップ

6) シガバート 7) シグバス 8) シグペ 9) シグナルキル 10) シグサー1

11) SIGSEGV 12) シグスレ2 13) シグパイプ 14) シガルム 15) シグターム

16) SIGSTKFLT 17) シグナル 18) シグナル継続 19) シグストップ 20) SIGTSTP

21) シグティン 22) シグトゥ 23) シグルグ 24) SIGXCPU 25) シグエックス

26) シグナル 27) シグプロフ 28) シグウィンチ 29) シジオ 30) シグプWR

31) シグシス 34) シグミン 35) シグマ最小+1 36) SIGRTMIN+2 37) シグナル最小値+3

38) シグマ最小+4 39) シグマ最小+5 40) シグマ最小+6 41) シグマイン+7 42) シグマ最小+8

43) シグマミン+9 44) シグナル最小値+10 45) シグマミニ+11 46) シグナル最小値+12 47) シグマミニ+13

48) シグマミニ+14 49) シグマ最小+15 50) シグマートマックス-14 51) シグマートマックス-13 52) シグマートマックス-12

53) シグマートマックス11 54) シグマートマックス10 55) シグマートマックス9 56) シグマックス8 57) シグマートマックス7

58) シグマートマックス6 59) シグマートマックス5 60) シグマートマックス4 61) シグマートマックス3 62) シグマートマックス2

63) シグマートマックス1 64) シグマックス

各信号の意味を詳しく説明するつもりはありません。私のスキルはまだそこまでには程遠いです。ここでは、私たちのトピックに関連する知識だけを取り上げ、説明します。

私たちのトピックに関連するシグナルはSIGTERMSIGKILL 2 つあります。

信号名コードそれを捕らえるか、無視するか?
シグナルターム15できる
シグナルキル9できない

SIGTERMは、 killコマンドによって送信されるデフォルトのシグナルです。ユーザーがプロセスの終了を要求すると、SIGTERM シグナルが生成されます。 SIGTERM シグナルはキャッチすることも無視することもできます。これにより、プロセスは保持されているリソースを解放し、終了する前にその状態を保存できるようになります。

SIGKILLプロセスに SIGKILL シグナルを送信すると、プロセスは直ちに終了 (KILL) します。 SIGTERM とは異なり、このシグナルはキャッチまたは無視することはできず、受信プロセスはこのシグナルを受信して​​もクリーンアップを実行してはなりません。しかし、 kill -9実行しても、必ずしもプロセスが強制終了され、リソースが解放されるとは限りません。いくつか特別なケースがあります:

  • ゾンビ プロセスは既に終了しており、親プロセスがそれを回収するのを待っているため、強制終了できません。
  • ブロックされたプロセスは、再び起動するまで終了しません。init プロセスは特別です。
  • init は処理対象ではないシグナルを受信しないため、SIGKILL を無視します。このルールには例外があります。Linux 上の init が ptrace の場合、SIGKILL を受信して​​強制終了される可能性があります。
  • 割り込み不可能なスリープ状態にあるプロセスは、SIGKILL が送信されても​​終了しない (およびそのリソースを解放しない) 場合があります。これは、一時的なソフトウェアの問題を解決するために Unix システムを再起動する必要がある数少ない状況の 1 つです。

コンテナとシグナル

コンテナの本質は、カプセル化されたプロセスのグループです。したがって、冒頭で述べた 3 つのコマンド ライン メソッドを使用して実行中のコンテナーを閉じることは、本質的には、コンテナー内のプロセスと対話してプロセスを「強制終了」するシグナルを送信するプロセスです。

  • ドッカー停止

docker stop ContainerIDを実行すると、コンテナ内のメインプロセスにSIGTERMシグナルが送信されます。猶予期間が経過すると、コンテナを完全に終了するためにSIGKILLシグナルが送信されます。

Docker マニュアルの原文は次のとおりです。

コンテナ内のメインプロセスはSIGTERMを受信し、猶予期間後にSIGKILL受信します。

  • ドッカーrm -f

docker rm -f ContainerID実行すると、コンテナ内のメイン プロセスにSIGKILLシグナルが直接送信されます。コンテナが強制終了されると、コンテナも削除されます。コンテナを削除する操作から判断すると、このコマンドは実行中のコンテナを停止するのではなく、停止したコンテナを削除するために使用されます。

  • ドッカーキル

docker kill --signal=KILL ContainerIDを実行すると、コンテナのメイン プロセスにさまざまなカスタム シグナルを送信できます。つまり、コンテナのkillコマンドです。現在のコマンドは、コンテナのメイン プロセスにSIGKILLシグナルを送信しています。

比較すると、実行中のコンテナを停止するためにdocker rm -f ContainerID使用すべきではありません。残りの 2 つの方法のうち、 docker stop ContainerID方が明らかに優れています。コンテナが最終的に強制終了されることを保証できるだけでなく、ユーザーが後でキャプチャして処理できるようにSIGTERMを提供することもできます。

さて、いよいよ本題に入りましょう。

信号をキャプチャして処理する

シグナルSIGTERMはキャッチできるシグナルです。コンテナのメイン プロセスがこの信号をキャプチャすると、事前に設計されたロジックをトリガーして、完全に終了する前にスケジュールされたタスクを完了することができます。たとえば、実行環境をクリーンアップしたり、データを保存したり、メインプロセスによって制御されていない他のプロセスを閉じたりすることができます。シナリオによっては、この要件が非常に顕著になります。

Linux には、シグナルをキャプチャし、プロセスが完全に終了する前に特定のタスクが実行されるようにする組み込みのtrapコマンドが用意されています。

root@ubuntuserver:~# トラップ --help

トラップ: トラップ [-lp] [[arg] シグナル仕様 ...]

信号やその他のイベントをトラップします。

基本的な使い方は以下のとおりです。

トラップ do_some_things SIGSPEC

アイデアは明確です。コンテナが終了する前に実行する必要があるすべての処理を完了するには、コンテナの起動スクリプトにtrap命令を追加する必要があります。

以下は、コンテナの ENTRYPOINT として実行されるスクリプトの例です。

#!/bin/bash

関数 clean_up_term {
  rm -rf /データ/tmp
  echo "clean_up_term が実行中"
}

トラップ clean_up_term SIGTERM

((i=1;i<=1000;i++)) の場合
  する
    echo "$i を待つ"
    睡眠1
  終わり 

コンテナが起動したら、別のターミナルからdocker stop ContainerIDコマンドを実行し、次の結果を確認できます。

guox@MacBook-Pro-For-Guox: /Users/guox/GitHub/test-plugin git:(master) ✗

➜ docker run -ti --name=clean -v $(pwd)/data:/data clean

1を待つ

2を待つ

3を待つ

4を待つ

5分待つ

6を待つ

7を待つ

8を待つ

9を待つ

10分待つ

11を待つ

12を待つ

13を待つ

clean_up_term 実行中

14を待つ

15分待つ

16を待つ

17を待つ

18を待つ

19を待つ

20分待つ

21を待つ

22を待つ

23を待つ

guox@MacBook-Pro-For-Guox: /Users/guox/GitHub/test-plugin git:(master) ✗

SIGTERMシグナルは実際にコンテナによってキャッチされ、関連するクリーンアップ操作が実行されます。 docker stop ContainerID猶予期間を提供するため、クリーンアップ操作が実行された後、コンテナのメインプロセスは終了する前にしばらく実行を続けます。

これで、docker コンテナが正常に終了する前に、trap を使用して環境のクリーンアップを実行する方法についての説明は終了です。docker コンテナ実行環境のクリーンアップの詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Docker はすべてのコンテナをバッチ起動して閉じます
  • Dockerコンテナを閉じずに終了する方法の詳細な説明
  • Docker クリーンアップ環境操作

<<:  中国語と英語のフォント名の比較表(FounderとArphicを含む)

>>:  CSS 動的高さ遷移アニメーション効果の実装

推薦する

訪問者を惹きつけるウェブサイトコンテンツを作成する14の方法

ネットサーフィンをしていると、私の注意を引こうとする美しいグラフィックでいっぱいの Web サイトを...

MYSQL データベースの基礎 - 結合操作の原理

結合では、ネスト ループ結合アルゴリズムが使用されます。ネスト ループ結合には 3 つの種類がありま...

nginxの基礎を学ぶ

目次1. nginx とは何ですか? 2. nginx で何ができるのか? 2.1 フォワードプロキ...

MySQLリモート接続権限の詳細な説明

1. MySQLデータベースにログインするmysql -u ルート -pユーザーテーブルを表示する ...

Typescriptを使用してローカルストレージをカプセル化する方法

目次序文ローカルストレージの使用シナリオ使用上の問題解決機能性有効期限を追加データ暗号化を追加する命...

MySQL でのログインを取り消す

コンセプト紹介: MySQL の redo ログにはトランザクションの動作が記録されることはご存じの...

CSS でのフレックスレイアウトの詳細な説明

フレックス レイアウトは、エラスティック レイアウトとも呼ばれます。任意のコンテナーをフレックス レ...

シンプルなウェブ計算機を実装するJavaScript

背景私は新しいプロジェクト チームに配属されたので、プロジェクトでは js を使用する必要があります...

クリーンで美しいウェブデザインのための4つの原則

この記事では、 Webデザインに関連するこれら4 つの原則について説明します。これら4 つの原則を念...

Zabbixのインストールと展開の詳細な説明

序文Zabbix は最も主流のオープンソース監視ソリューションの 1 つです。導入自体は難しくありま...

Vmware での Ubuntu サーバーのインストール チュートリアル

この記事では、Ubuntuサーバーバージョンのインストールグラフィックチュートリアルを参考までに紹介...

MAC 上の MySQL の初期パスワードを忘れた場合の対処方法

MACでMySQLの初期パスワードを忘れた場合の解決策を参考までに共有します。具体的な内容は次のとお...

あまり多くのコードを書かずに、ハイパーリンクを使ってシンプルで美しいカスタムチェックボックスを実装できます。

今日ふと、HTML でチェックボックスのスタイルを変更できる範囲が限られていることと、チェックボック...

HTML テーブル マークアップ チュートリアル (18): テーブル ヘッダー

<br />ヘッダーはテーブルの最初の行を参照します。ヘッダー内のテキストは中央揃えで太...

Vueはスクロールロードテーブルを実装します

目次成果を達成する転がり荷重知識備蓄コンポーネントのパッケージ1. コンポーネントの命名2. 小道具...