Docker インストールのイベント履歴を表示する方法
公開: 2022-08-11Docker Engine は、デーモンによって重要なアクションが実行されるたびにイベントを記録します。 イベント ログにアクセスして、アクションがいつ発生したかを特定し、オブジェクトへの変更を経時的に追跡できます。
この記事では、イベントとしてキャプチャされるものと、それらをいつ表示する必要があるかについて説明します。 次に、Docker CLI と REST API を使用してリアルタイムでイベントを監視する方法を示します。
Docker イベントとは何ですか?
Docker イベントは、Docker デーモンによって実行されるアクティビティを表します。 コンテナー、イメージ、ボリューム、ネットワークなどのオブジェクトとのやり取りのほとんどはイベントを記録し、過去の変更を調査するために使用できるログを作成します。
環境内の特定の変更を識別するさまざまな種類のイベントがあります。
- コンテナーの作成と削除
- コンテナのヘルスチェックのステータス
docker exec
を使用してコンテナー内で実行されるコマンド- イメージのプルとプッシュ
- ボリュームの作成、破棄、マウント、およびアンマウント
- Docker デーモン プラグインの有効化と無効化
完全なリストは、Docker のドキュメントで確認できます。
記録された各イベントには、タイムスタンプと影響を受けるオブジェクトの ID が含まれます。 この情報を使用して、元のトリガーを観察したかどうかに関係なく、環境に対する変更の履歴を収集できます。
格納されたイベントは、予期しないコンテナーの障害などの問題の診断にも役立ちます。 ログを表示すると、コンテナーが停止した正確な時刻を特定でき、他のログと関連付けることができるデータ ポイントが提供されます。 コンテナーのヘルス チェックがいつ失敗し始めたかをイベントで確認できるため、問題の根本原因を特定するために外部サービスを検査する必要がある場合に、関心のある期間を絞り込むことができます。
Docker CLI を使用した Docker イベントのストリーミング
docker events
CLI コマンドは、Docker デーモンからターミナル ウィンドウにイベントをストリーミングします。 Ctrl+C キーボードの組み合わせを押してプロセスを終了するまで、イベントはリアルタイムで表示されます。
引数なしでコマンドを実行すると、そもそも出力が表示されません。 新しいアクティビティのみが表示されるため、イベントが発生するまで出力は空のままです。 別のシェルで新しいコンテナーを開始することで、これを誘発できます。
$ docker run --rm ハローワールド
docker events
コマンドを実行しているターミナル ウィンドウに、いくつかのイベントが表示されるはずです。
2022-05-31T15:20:00.267970018+01:00 画像プル hello-world:latest (name=hello-world) 2022-05-31T15:20:00.347054862+01:00 コンテナ作成 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378 (image=hello-world, name=nifty_morse) 2022-05-31T15:20:00.347805277+01:00 コンテナアタッチ 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378 (image=hello-world, name=nifty_morse) 2022-05-31T15:20:00.621070053+01:00 コンテナ開始 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378 (image=hello-world, name=nifty_morse) ...
各イベントはそれぞれの行に表示されます。 イベントのタイムスタンプが最初に表示され、その後に影響を受けるオブジェクトのタイプ ( image
やcontainer
など)、実行されたアクション ( create
、 attach
、 start
など) が続きます。 メッセージの残りの部分には、オブジェクトに関する有用なメタデータが含まれています。 上記の例は、 hello-world:latest
イメージがプルされ、そこからコンテナーが作成されたことを示しています。
出力の書式設定
生のイベント リストは扱いにくいことがよくあります。 Go テンプレート文字列を受け入れる--format
フラグを使用して、出力を再フォーマットできます。
$ docker events --format '{{ .Time }} {{ .Action }} {{ .Type}} {{ .ID }}'
この例を実行すると、次のような出力が生成されます。
1654006800 プル イメージ hello-world:latest 1654006800 コンテナーの作成 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378 1654006800 コンテナのアタッチ 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378 1654006800 開始コンテナ 4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378
{{ json . }}
{{ json . }}
をテンプレート文字列として:
$ docker events --format '{{ json . }}' | jq { "ステータス": "作成", "id": "4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378", 「から」:「ハローワールド」、 "タイプ": "コンテナ", "アクション": "作成", "アクター": { "ID": "4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378", "属性": { "画像": "ハローワールド", 「名前」:「nifty_morse」 } }、 "スコープ": "ローカル", 「時間」: 1654006800、 「タイムナノ」: 1654006800347054800 }
ここでは、生の JSON がjq
を介して渡されるため、端末にきれいに出力されます。 これにより、情報をスキャンしやすくなります。
カスタム形式の文字列を作成する場合、JSON 出力のプロパティを、サポートされているプレースホルダーのリファレンスとして使用できます。 ほとんどの場合、 time
to {{ .Time }}
など、各プロパティの最初の文字を大文字にする必要があります。
イベントのフィルタリング
ビジー状態の Docker デーモンのイベント ログは、すぐにノイズになる可能性があります。 --filter
フラグを使用して、イベントを特定のアクション、オブジェクト、またはオブジェクトのタイプに絞り込むことができます。
-
docker events --filter type=container
– コンテナーに関連するすべてのイベントを取得します。 -
docker events --filter event=create
– コンテナー作成イベントを取得します。 -
docker events --filter container=demo-container
–demo-container
-container というコンテナーに保存されたすべてのイベントを取得します (コンテナーの ID または名前を参照できます)。
container
以外にも、 image
、 network
、 volume
など、サポートされているすべてのオブジェクト タイプ名でフィルタリングできます。
--filter
フラグを繰り返すと、複数のフィルターがサポートされます。 個別フィルタは、論理AND条件として解釈されます。 同じフィルターを複数回使用すると、 OR句になります。 app-container
とapi-container
コンテナーの両方のcreate
イベントを表示する例を次に示します。
$ docker イベント \ --filter container=app-container --filter container=api-container --filter event=create
歴史的出来事へのアクセス
docker events
デフォルトでは、コマンドの実行後に保存されたイベントのみが表示されます。 --since
フラグを追加すると、履歴イベントを含めることができます。 これは、人間が読める時間表現または絶対タイムスタンプを受け入れます。
$ docker events --since 1h $ docker events --since '2021-05-01T16:00:00'
指定された時間以降に記録されたイベントは、すぐに端末に表示されます。 新しいイベントは、記録されるとリアルタイムで表示され続けます。
--until
フラグを使用して、特定の時間以降のイベントを除外できます。 --since
と同様に機能します。 --until
を使用すると、新しいイベントのリアルタイム ストリーミングが無効になります。要求された時間枠から外れるためです。
デーモン REST API からの Docker イベントのストリーミング
保存されたイベントにアクセスするもう 1 つの方法は、Docker デーモン REST API を使用することです。 Docker ホストで API を有効にすると、 /events
エンドポイントを使用してリアルタイムでイベントをストリーミングできます。 イベントは JSON 形式で返されます。
$ curl http://127.0.0.1:2375/v1.41/events { "タイプ": "コンテナ", "アクション": "作成", "アクター": { "ID": "4a6c8d34a183363db5dbfdcc3cab4c82c4a341d719df56ec2e7f879ee8f02378", 「属性」: { "画像": "ハローワールド", 「名前」:「nifty_morse」 } }、 "スコープ": "ローカル", 「時間」: 1654006800、 「タイムナノ」: 1654006800347054800 }
API エンドポイントは、対応する CLI と同じ動作を持つfilter
、 since
、およびuntil
パラメーターをサポートします。 過去 1 時間に記録されたすべてのコンテナー作成イベントを取得する方法は次のとおりです。
$ curl http://127.0.0.1:2375/v1.41/events?since=1h&filters={'type':'container','action':'create'}
外部サービスへのイベントの送信
Docker には、イベントを外部サービスに送信する組み込みの方法がありません。 これは、すべてのコンテナーの作成を既存の監視または監査プラットフォームに記録する場合に役立ちます。
docker events
を継続的に実行するシステム サービスを作成することで、独自のソリューションをセットアップできます。 出力の新しい各行を外部システムに送信する必要があります。
まず、必要な機能を実装する Bash スクリプトを作成します。
#!/ビン/バッシュ docker events --format '{{ .Time }} {{ .Action }} {{ .Type }} {{ .ID }}' | while read イベント 行う カール\ -X POST \ -H "コンテンツ タイプ: アプリケーション/json" \ -d '{"イベント": "$イベント"}' \ https://example.com/events 終わり
/etc/systemd/system/docker-events.service
に新しいsystemd
サービス ユニットを作成します。
[単位] Description=カスタム Docker イベント監視サービス [サービス] タイプ=フォーク ExecStart=/usr/local/bin/docker-events.sh [インストール] WantedBy=マルチユーザー.ターゲット
最後に、 systemd
をリロードしてサービスをロードし、ユニットを起動して有効にします。
$ sudo systemctl デーモン-リロード $ sudo systemctl start docker-events $ sudo systemctl enable docker-events
これで、サービスは新しいイベントをモニタリング プラットフォームにストリーミングします。 サービスを有効にすると、ホストが再起動するたびにサービスが自動的に開始するように構成されます。
概要
Docker イベントは、デーモンが環境内のオブジェクトを変更するたびに作成されます。 イベント ログをストリーミングすると、デーモンのアクティビティをリアルタイムで監視できます。 これは、問題のデバッグ、変更の監査、コンプライアンスの確保に役立ちます。
イベントは Docker サーバーから直接取得されるため、将来情報を取得する必要がある場合は、イベントに依存しないでください。 ローリング ベースで保持されるのは 1,000 エントリのみであり、Docker ホストのファイル システム経由でイベントにアクセスすることはできません。 このメカニズムは、最近のアクティビティに関連する特定の情報を探している、迅速なアドホック タスクに最適です。 長期間保持するには、独自のシステム サービスを使用して、イベントを外部リポジトリに送信する必要があります。