Exec を使用したコンテナへのアクセス

DockerBeginner
オンラインで実践に進む

はじめに

この実験では、実行中の Docker コンテナに入る方法を学びます。コンテナは使い捨てを前提に設計されていますが、実際に何が起きているのかを把握するために、稼働中の環境を確認しなければならないことがあります。そのため、これは重要なデバッグスキルです。

コンテナ内のファイルを確認したり、実行中のプロセスを調べたり、問題をトラブルシューティングしたりするには、多くの場合、そのコンテナの環境内でコマンドシェルを起動する必要があります。docker exec コマンドを使うと、コンテナを再ビルドしたり再起動したりせずに、すでに実行中のコンテナ内で追加のコマンドを起動できます。

ここで「追加」という点が重要です。docker exec はコンテナのメインプロセスを置き換えません。元のサービスを実行したまま、同じコンテナの名前空間内で別のプロセスを起動します。

この実験では、次の手順を行います。

  • バックグラウンドで Nginx コンテナを起動する。
  • docker exec を使用して、コンテナ内で対話型 Bash シェルを起動する。
  • コンテナ内でコマンドを実行し、オペレーティングシステムを確認する。
  • コンテナを終了し、ホストのターミナルに戻る。

バックグラウンドでコンテナを起動する

このステップでは、Nginx イメージを使用して新しい Docker コンテナを起動します。コンテナは「detached」モードで実行するため、バックグラウンドで動作します。また、後で参照しやすいように、コンテナに特定の名前を付けます。

ターミナルで次のコマンドを実行します。

docker run -d --name web1 nginx

コマンドの内訳:

  • docker run:コンテナを作成して起動するコマンドです。
  • -d:コンテナを detached モード(バックグラウンド)で実行します。
  • --name web1:コンテナに web1 という名前を付けます。
  • nginx:使用するイメージです。

コンテナが実行中であることを確認します。

docker ps

アクティブなコンテナの一覧に web1 が表示されます。

コンテナは実行中でなければなりません。docker exec は、すでに稼働しているコンテナのコンテキストに入ることで動作するためです。停止済みのコンテナ内でシェルを起動することはできません。

コンテナに入る

コンテナが実行中になったので、docker exec コマンドを使用して、コンテナ内でシェルセッションを起動します。これは、リモートサーバーに SSH で接続する場合と同じように、コンテナに「ログイン」する操作です。

次のコマンドを実行します。

docker exec -it web1 bash

コマンドの内訳:

  • docker exec:既存のコンテナ内でコマンドを実行します。
  • -it:対話型セッションに必要なオプションの組み合わせです。
    • -i(interactive):入力ストリームを開いたままにします。
    • -t(tty):擬似ターミナルを割り当て、通常のコマンドプロンプトのように動作させます。
  • web1:対象コンテナの名前です。
  • bash:コンテナ内で実行するコマンドです。ここでは Bash シェルを起動します。

つまり、docker exec は「コンテナ内でこのコマンドを実行する」ためのコマンドです。シェルは一般的な使用例の 1 つにすぎず、ls、cat、デバッグ用ユーティリティなども同じように実行できます。

変化を確認します。

このコマンドを実行すると、コマンドプロンプトが変わります。次のような形式になります。

root@<container-id>:/#

これは、現在実行しているコマンドがホストマシンではなく、コンテナ内のものであることを示しています。

この分離には通常、ファイルシステムの見え方、プロセス名前空間、ネットワークコンテキストが含まれます。同じカーネル上で動作していますが、ホスト全体の環境ではなく、コンテナのスコープに限定された環境を見ている状態です。

コンテナの環境を確認する

現在、コンテナ内にいます。ここで見えているファイルシステムは LabEx 環境のものではなく、コンテナのものです。オペレーティングシステムの情報を確認すると、このことを検証できます。

コンテナ内のシェルで次のコマンドを実行します。

cat /etc/os-release

Nginx イメージで使用されている Linux ディストリビューションの情報が表示されます(通常は Debian です)。

出力例:

PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
...

この出力から、コンテナにはホストとは別に分離されたオペレーティングシステム環境があることを確認できます。

より正確には、コンテナは独自のユーザー空間ファイルシステムとプロセス環境を持っています。独立したカーネルではありませんが、コンテナの内部から見ると、独立した小さな Linux システムのように扱えます。

終了してホストに戻る

コンテナのデバッグや確認が終わったら、シェルセッションを終了してホストマシンに戻ります。

コンテナ内で次のコマンドを入力します。

exit

Enter キーを押すと、コマンドプロンプトが通常の LabEx ユーザープロンプトに戻ります。

何が起きたのでしょうか?

コンテナ内で実行していた Bash プロセスを終了しました。ただし、メインプロセスである Nginx が引き続きアクティブなため、コンテナ自体(web1)はバックグラウンドで実行され続けています。

これが docker exec における重要なライフサイクルのポイントです。対話型シェルを終了しても、そのシェルがコンテナのライフサイクルを定義するメインプロセスでない限り、コンテナは停止しません。

次のコマンドを実行すると確認できます。

docker ps

web1 は引き続き一覧に表示されます。

後片付けとして、コンテナを停止して削除できます。

docker rm -f web1

まとめ

この実験では、docker exec -it を使用して実行中のコンテナにアクセスする方法を学びました。次の操作を練習しました。

  • コンテナをバックグラウンドで起動する。
  • 対話型 Bash シェルを使用してコンテナに入る。
  • コンテナ内の環境を確認する。
  • サービスを実行したまま、安全に終了する。

これは Docker を扱うための基本的なスキルです。アプリケーションのトラブルシューティングや、コンテナ環境の直接的な確認に役立ちます。