TT Lab
はじめる
学ぶ 学習パス コース

Docker基礎

最初のコンテナを立ち上げる

TT Labで続きを見る

このラボは本物のVM上で動きます

この環境はPodではなく、KubeVirtが起動した仮想マシンです。Linuxカーネルが別に動き、systemdが実際にサービスを管理し、dockerは模倣ではなく本物のDockerエンジンです。docker runで起動したコンテナは実際にプロセスになり、docker execもdocker logsもそのまま動作します。

以前はこのラボがPodの中で動いていました。カーネル権限をすべて落とした環境だったため、コンテナを起動するステップが塞がれており、イメージアーカイブを自分で展開してみるという回り道で学んでいました。もう回り道は必要ありません。

知っておくべきことが2つあります。

目標

イメージとコンテナを手で操作しながら、タグがイメージをコピーしないことと、コンテナの内側と外側では見えるファイルツリーが違うことを自分で確認します。

なぜ重要なのか

コンテナに初めて触れると、ほとんどの人はコマンドを暗記しようとします。しかし実務でつまずくのはコマンドではなく、モデルです。「イメージを削除したのにコンテナが生きている」「タグを変えたのに容量が減らない」「コンテナ内にはファイルがあるのにホストにはない」。これらはすべて、イメージは読み取り専用のレイヤーの山であり、コンテナはその上の書き込みレイヤー+プロセスであるという1つの文で説明できます。そのため、このラボはコマンドを覚えるのではなく、その文を目で確かめる過程です。

ステップ

  1. /root/dk1ディレクトリを作成し、この環境で使えるイメージの一覧を/root/dk1/images.txtとして保存します。リポジトリとタグが一緒に見える必要があります。 docker imagesはこの環境では動作しません。代わりに、/opt/images/*.tarの中のindex.jsonから.manifests[0].annotations["org.opencontainers.image.ref.name"]を読むと、docker.io/library/alpine:3.20のような名前:タグがそのまま得られます。docker imagesのRepositoryとTagの2列がどこから来るのかを、1段下の層から見ることになります。
  2. alpine:3.20イメージでdk-helloという名前のコンテナを作成してhello-labhubを出力させ、終了後もコンテナを残しておきます。
  3. nginx:1.27-alpineをdk-webという名前でバックグラウンド実行します。
  4. nginx:1.27-alpineコンテナから見える/etc/os-releaseを読み、/root/dk1/web-os.txtとして保存します。 docker exec dk-web cat /etc/os-releaseで読みます。このVMの/etc/os-releaseをそのまま読むとUbuntuが表示されて失敗します。その違いこそが、マウントネームスペースの働きです。
  5. dk-webのコンテナIPアドレスを調べ、/root/dk1/web-ip.txtにIPv4アドレスを1行だけ保存します。
  6. alpine:3.20にlabhub/base:v1という名前をもう1つ付けます。
  7. dk-helloコンテナを削除します。dk-webはそのままにします。
  8. /root/dk1/report.txtに、次の3行を実際の値で埋めて書き込みます。
image=<dk-web 이 쓰는 이미지 이름:태그>
container=dk-web
state=<dk-web 의 현재 상태>

(プレースホルダーは、dk-webが使うイメージの名前:タグと、dk-webの現在の状態です)

参考

イメージ一覧を保存する

/root/dk1ディレクトリを作成し、この環境で使えるイメージの一覧を/root/dk1/images.txtとして保存します。リポジトリとタグが一緒に見える必要があります。 docker imagesはこの環境では動作しません。代わりに、/opt/images/*.tarの中のindex.jsonから.manifests[0].annotations["org.opencontainers.image.ref.name"]を読むと、docker.io/library/alpine:3.20のような名前:タグがそのまま得られます。docker imagesのRepositoryとTagの2列がどこから来るのかを、1段下の層から見ることになります。

イメージの一覧を表示するサブコマンドがあります。出力を画面で読むだけで終わらせず、リダイレクトでファイルに残してください。リポジトリ名だけでなく、タグの列まで一緒に残す必要があります。

1回実行して終わるコンテナ

alpine:3.20イメージでdk-helloという名前のコンテナを作成してhello-labhubを出力させ、終了後もコンテナを残しておきます。

名前を付けておくと、あとで探しやすくなります。--rmを付けると終わった直後に削除され、採点する対象がなくなる点に注意してください。

バックグラウンドで動き続けるコンテナ

nginx:1.27-alpineをdk-webという名前でバックグラウンド実行します。

フォアグラウンドで起動すると、ターミナルが占有されてしまいます。コンテナを切り離して起動するフラグがあります。nginxは終了せず、動き続けているのが正常です。

実行中のコンテナ内でコマンドを実行する

nginx:1.27-alpineコンテナから見える/etc/os-releaseを読み、/root/dk1/web-os.txtとして保存します。 docker exec dk-web cat /etc/os-releaseで読みます。このVMの/etc/os-releaseをそのまま読むとUbuntuが表示されて失敗します。その違いこそが、マウントネームスペースの働きです。

ホストで/etc/os-releaseを読むと、Ubuntuが表示されます。コンテナのマウントネームスペースの中で読むと、Alpineが表示されます。

コンテナのIPを調べる

dk-webのコンテナIPアドレスを調べ、/root/dk1/web-ip.txtにIPv4アドレスを1行だけ保存します。

inspectの出力はJSONです。jqで掘り下げるか、--formatテンプレートを使ってください。ファイルにはIPアドレスだけを残す必要があります。

イメージに別の名前を付ける

alpine:3.20にlabhub/base:v1という名前をもう1つ付けます。

タグはイメージをコピーしません。新しい名前を付けたあと、2つの名前のイメージIDを比べてみてください。

終了したコンテナだけを片付ける

dk-helloコンテナを削除します。dk-webはそのままにします。

終了したコンテナも、書き込みレイヤーを保持し続けます。実行中のものは残し、終わったものだけを削除する必要があります。

現在の状態をレポートにする

/root/dk1/report.txtに、次の3行を実際の値で埋めて書き込みます。

3行とも、実際のinspectの値と照合されます。推測で書かず、コマンドで確認した値を書いてください。