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

ボリューム・ネットワーク・Compose

スタックを宣言して照合する

TT Labで続きを見る

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

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

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

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

目標

2つのサービスで構成されるスタックをComposeファイルで宣言し、同じスタックを手でも起動したうえで、宣言した値と実際の値が正確に一致するかを照合します。

なぜ重要なのか

Composeを「複数のコンテナを一度に起動するツール」としてしか理解しないと、半分しか得られません。本当の価値は、スタックの形がファイルに書かれ、リポジトリに残ることです。そして、この価値は、ファイルと現実が一致しているときにだけ成り立ちます。誰かが手でコンテナを変更した瞬間、ファイルはドキュメントではなく嘘になり、その嘘は次のデプロイまで誰も気づきません。そのため、このラボの最後のステップは、新しい機能を作ることではなく、照合です。宣言的なツールを使うチームが必ず身につけるべき習慣が、ここにあります。

ステップ

/root/ops3/compose.yamlを、次の構造で作成します。インデントは2スペースで、最上位のキー(services:、volumes:、networks:)は必ず行の先頭から始める必要があります。

  1. 最上位にservices:を置き、その下にweb:とcache:の2つのサービスを、2スペースのインデントで宣言します。
  2. webのimageはnginx:1.27-alpine、cacheのimageはalpine:3.20とし、cacheには、動き続けるようにcommandも書きます。
  3. 最上位にnetworks:を置き、その下にappnet:を宣言したうえで、2つのサービスの両方のnetworks:リストに- appnetを入れます。
  4. webにports:を置き、"127.0.0.1:8081:80"を入れます。cacheにはportsを置きません。
  5. 最上位にvolumes:を置き、webdata:を宣言したうえで、webのvolumes:にwebdata:/usr/share/nginx/htmlを入れます。
  6. cacheにenvironment:でCACHE_TTLの値60を入れ、webにdepends_on:で- cacheを入れます。
  7. 同じスタックを手で起動します。ネットワーク名はops3net、コンテナ名はops3-web(nginx:1.27-alpine、127.0.0.1:8081:80をパブリッシュ)とops3-cache(alpine:3.20、環境変数CACHE_TTL=60)で、どちらもops3netに接続します。
  8. このステップで新しく作るものはありません。ステップ6までの宣言と、ステップ7の実際のコンテナが、イメージ・ポート・環境変数の3項目で正確に一致しているかを確認します。

参考

サービスを2つ宣言する

最上位にservices:を置き、その下にweb:とcache:の2つのサービスを、2スペースのインデントで宣言します。

最上位のservicesの下に、サービス名を2スペースのインデントで置きます。インデントがずれると、ファイル全体の意味が変わります。

イメージとコマンドを指定する

webのimageはnginx:1.27-alpine、cacheのimageはalpine:3.20とし、cacheには、動き続けるようにcommandも書きます。

alpineはデフォルトのコマンドがすぐに終了するため、動き続けるcommandも一緒に書く必要があります。

共用のネットワークを宣言する

最上位にnetworks:を置き、その下にappnet:を宣言したうえで、2つのサービスの両方のnetworks:リストに- appnetを入れます。

最上位でnetworksを宣言し、各サービスからその名前を参照します。両方の場所で必要です。

ポートはループバックにだけ

webにports:を置き、"127.0.0.1:8081:80"を入れます。cacheにはportsを置きません。

ポートの文字列の先頭に、バインドアドレスを付けられます。内部通信だけを行うサービスには、portsを使いません。

名前付きボリュームを宣言する

最上位にvolumes:を置き、webdata:を宣言したうえで、webのvolumes:にwebdata:/usr/share/nginx/htmlを入れます。

最上位のvolumesで名前を宣言し、サービスでは対象パスと一緒に書きます。

環境変数と起動順序

cacheにenvironment:でCACHE_TTLの値60を入れ、webにdepends_on:で- cacheを入れます。

depends_onは順序だけを保証し、準備状態は保証しないことを覚えておいてください。

同じスタックを手で起動する

同じスタックを手で起動します。ネットワーク名はops3net、コンテナ名はops3-web(nginx:1.27-alpine、127.0.0.1:8081:80をパブリッシュ)とops3-cache(alpine:3.20、環境変数CACHE_TTL=60)で、どちらもops3netに接続します。

ネットワークを先に作り、コンテナを接続します。宣言ファイルに書いた値と、まったく同じ値を使ってください。

宣言と実際を照合する

このステップで新しく作るものはありません。ステップ6までの宣言と、ステップ7の実際のコンテナが、イメージ・ポート・環境変数の3項目で正確に一致しているかを確認します。

採点では、composeファイルから読み取った値と、実際のコンテナのinspectの値を、直接比較します。1文字でも違えば、ずれています。