季節のメニューを更新する

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

はじめに

Juniper Café は秋のメニューを公開する準備ができています。Web サイトは動いていますが、まだ通常の品ぞろえを表示しています。Kubernetes を通じて新しいメニューを公開し、以前の設定を残したうえで、カウンタースタッフ用の実際のメニューをダウンロードします。

Pod、Deployment、Service、ラベル、簡単な YAML を理解していることを前提とします。クラスター、アプリケーションイメージ、Web サイトは準備済みです。アプリケーションのコーディングやクラウドアカウントは不要です。この実験では、各設定に内容に基づく固有の名前を付けるために必要な、Kustomize の限られた機能を学びます。

コマンドには Workspace、Juniper には Café Menu、別の読書室カフェには Reference Menu を使います。すべての入口は 1 台の学習用 VM を共有しています。参照用カフェ、アプリケーションコード、Service、レプリカ数、用意されたリリース履歴は変更しないでください。作者による所要時間の見積もりである 40 分には、読む時間と通常の操作ミスへの対応を含みます。

独立したメニューリリースを準備する

このステップでは、現在の Web サイトとその設定の関係を確認し、公開中のメニューを変えずにリリースディレクトリを準備します。

Café Menu を開き、Explore the menu を選択して Maple Latte を探します。現在の価格は $4.20 で、Not available today と表示されています。Cold Brew は提供中です。Oat Latte の About this drink を開いてから、Back to the menu で戻ります。これらは、準備済みのアプリケーションが配信する実際のページです。

Reference Menu に切り替え、Our menu を選択します。こちらは Willow Reading Room で、動作を維持する必要がある別のサービスです。Workspace に切り替えます。開始ディレクトリは /home/labex/project/cafe-menu です。現在のディレクトリを表示する pwd で確認します。

pwd

期待される出力:

/home/labex/project/cafe-menu

Kubernetes の ConfigMap は、設定をアプリケーションイメージとは別に保存します。Pod はその ConfigMap を名前で参照します。このカフェのプロセスは、マウントされたメニューファイルを起動時に一度だけ読み込みます。設定を編集しても、既存のプロセスが自動的にメニューを再読み込みするわけではありません。

準備済みの starter ディレクトリには、小さなファイルが 3 つあります。ls で一覧を表示します。

ls starter
deployment.json  kustomization.yaml  menu.json

JSON も Kubernetes マニフェストの入力として使用できます。deployment.json は準備済みの Deployment 定義です。アプリケーションの設定を維持し、別ファイルのメニューデータを変更します。

cp -r で自分のディレクトリを作成します。cp はコピーを行い、-r はディレクトリの内容も含めます。コピー先の release はまだ存在しません。

cp -r starter release

誤って 2 回実行すると、cp によって release/starter が入れ子で作成されることがあります。必要な 3 ファイルは、引き続き release の直下に置いてください。誤って作成した入れ子のコピーだけを rm -r release/starter で削除します。release、versions、approved は削除しないでください。

ファイルを表示する cat で設定を読みます。

cat release/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: cafe-menu
resources:
  - deployment.json
configMapGenerator:
  - name: cafe-menu
    files:
      - menu.json

resources は Deployment を含めます。configMapGenerator は menu.json を ConfigMap のデータに変換します。Kustomize は内容から導いた接尾辞を付け、その生成名を参照するよう Deployment を更新します。そのため、データを変更すると新しい Pod テンプレートと新しいロールアウトを生成でき、以前の ConfigMap も残ります。この接尾辞は内容を識別するもので、価格が正しいかどうかを示すものではありません。

承認済みの秋メニューを作成する

このステップでは、Kubernetes に変更を適用する前に、秋メニュー全体を準備します。

Workspace で続けます。カウンタースタッフの承認内容は approved/menu.csv に保存されています。CSV はカンマ区切りの値を意味します。最初の行は列名で、それ以降の各行は 1 つの飲み物を表します。price_cents はセント単位の整数なので、450 は $4.50 を意味します。true と false は、その飲み物を提供しているかどうかを示します。

cat approved/menu.csv
id,name,price_cents,available
espresso,Espresso,250,true
oat-latte,Oat Latte,350,true
cold-brew,Cold Brew,390,false
maple-latte,Maple Latte,450,true

Espresso と Oat Latte は変更しません。Cold Brew は本日の品ぞろえから外し、Maple Latte は $4.50 で提供します。季節のラベルは Autumn at Juniper にする必要があります。カフェ名、所在地、営業時間、商品の識別情報、説明は変更しません。

次の JSON 全体を書き込みます。JSON ではプロパティ名を引用符で囲み、項目をカンマで区切り、真偽値は引用符なしの小文字で記述します。シェルの記述 cat > release/menu.json <<'EOF' は、囲まれたテキストをそのファイルに書き込みます。> は以前の内容を置き換え、引用符付きの EOF はテキストをそのまま扱わせます。最後の、単独の行にある EOF まで貼り付けてください。

cat > release/menu.json <<'EOF'
{
  "name": "Juniper Café",
  "season": "Autumn at Juniper",
  "hours": "Mon–Sat · 08:00–17:00",
  "address": "14 Willow Lane",
  "items": [
    {"id": "espresso", "name": "Espresso", "price_cents": 250, "available": true, "description": "A small, rich cup with a golden crema."},
    {"id": "oat-latte", "name": "Oat Latte", "price_cents": 350, "available": true, "description": "Our espresso with smooth oat milk."},
    {"id": "cold-brew", "name": "Cold Brew", "price_cents": 390, "available": false, "description": "Slow-steeped coffee, served over ice."},
    {"id": "maple-latte", "name": "Maple Latte", "price_cents": 450, "available": true, "description": "Espresso, oat milk, and a little maple sweetness."}
  ]
}
EOF

使用する前に JSON を検証します。python3 -m json.tool は JSON を読み、インデントを付けた形式で表示します。ファイル自体は変更しません。

python3 -m json.tool release/menu.json

正常な出力には 4 種類すべての飲み物が含まれます。ツールが é を \u00e9 と表示する場合があります。これは JSON のエスケープ表現で、カフェ名が変わったわけではありません。カンマや引用符が欠けていると、行と列を示す解析エラーになります。上のブロック全体をもう一度書き込み、この検証を繰り返して復旧してください。パスが間違っている場合は、ファイルが見つからないというエラーになります。pwd を実行し、cd /home/labex/project/cafe-menu で戻ってから再試行してください。

変更したのはリリースのソースだけなので、Web サイトにはまだ通常のメニューが表示されます。これは想定どおりです。

新しい設定バージョンを公開する

このステップでは、リリースをレンダリングして適用し、両方のカフェレプリカが新しい設定を使うまで待ちます。

Workspace で続けます。kubectl kustomize はディレクトリを適用せずにレンダリングします。生成される ConfigMap 名と、Deployment 内の対応する参照を調べます。

kubectl kustomize release

出力には cafe-menu-... のような名前と、Deployment の volumes にある menu という項目の下に同じ名前が含まれます。正確な接尾辞はデータによって変わります。これは通常メニューとは異なる設定オブジェクトです。

kubectl apply -k でディレクトリを適用します。-k オプションは、-f で 1 つのマニフェストを読む代わりに、Kustomize ディレクトリをレンダリングするよう kubectl に指示します。

kubectl apply -k release

期待される出力には次が含まれます。

configmap/cafe-menu-... created
deployment.apps/cafe configured

ConfigMap が作成されただけでは、実行中のアプリケーションが変わった証拠にはなりません。rollout status は Deployment コントローラーが Pod を置き換えるまで待ちます。-n cafe-menu はこのレッスンの名前空間を選び、--timeout=120s は待機時間を制限します。

kubectl rollout status deployment/cafe -n cafe-menu --timeout=120s
deployment "cafe" successfully rolled out

待機がタイムアウトしたら、現在の環境を維持し、次のコマンドで調べます。イメージやコンテナーのエラーは Pod の状態やイベントに現れます。セットアップを再実行したり、名前空間を削除したりしないでください。

kubectl get pods -n cafe-menu
kubectl describe deployment cafe -n cafe-menu

正常なロールアウト後に、現在の Deployment とその ReplicaSet を調べます。ReplicaSet は特定の 1 つの Pod テンプレートを維持します。Deployment は、古い ReplicaSet をロールアウト履歴として保持します。

kubectl get replicasets -n cafe-menu -l app=cafe

Deployment 自体を名前で調べます。

kubectl get deployment cafe -n cafe-menu

Ready なレプリカが 2/2 と表示されるはずです。複数の設定オブジェクトが残っています。新しいリリースを適用しても、古いメニューは上書きされていません。一覧を表示します。

kubectl get configmaps -n cafe-menu

古い設定は削除しないでください。後で古いバージョンを復元する場合、その ReplicaSet には参照している正確な名前の設定が必要です。

Web サイトを確認してメニューを引き渡す

このステップでは、実際の顧客体験を検証し、カウンタースタッフが使うメニューを保存します。

Café Menu に切り替え、Our menu を選択します。すでにページが開いている場合は更新します。Maple Latte は $4.50 で Available today になっている必要があります。Cold Brew は Not available today になっている必要があります。Maple Latte の詳細ページを開き、Back to the menu で戻ります。その後、Visit us で所在地と営業時間を引き続き確認できることを確かめます。

承認済みの秋メニュー

提供状況のバッジと価格を見てください。Cold Brew は提供されず、Maple Latte は $4.50 で提供されています。

Download menu で実際の完全な CSV をダウンロードします。開いて、4 種類すべての飲み物をステップ 2 の承認表と比較してください。ダウンロードには提供していない飲み物も false として含まれるため、スタッフは誤って欠落した商品と区別できます。

Reference Menu に切り替え、Willow Reading Room の通常メニューが引き続き機能することを確認します。その後、Workspace に戻ります。

実際の Juniper のダウンロードをワークスペースにも保存できます。curl はローカルのブラウザー入口にリクエストし、その入口が実際の Kubernetes Service に転送します。--fail は HTTP エラーを報告し、--silent は進捗表示を隠し、--show-error はエラーメッセージを表示したままにします。-o は出力ファイル名を指定します。

curl --fail --silent --show-error http://127.0.0.1:8081/menu.csv -o menu-handover.csv

diff -u で受信したファイルを承認内容と比較します。-u オプションは、差異があればその前後の行も表示します。

diff -u approved/menu.csv menu-handover.csv

出力がなければ、ファイルは一致しています。差異は役立つ証拠です。メニューのソースと実際のロールアウトに戻って原因を修正し、ダウンロードと比較を繰り返してください。誤った Web サイトの内容を隠すために、受信した CSV を編集してはいけません。

これで、使えるメニュー、実際のスタッフ用ダウンロード、実行中の設定を再現するリリースディレクトリがそろいました。この環境の復旧用資料として、versions と古い ConfigMap をそのまま保持してください。次のレッスンには、独立した環境が用意されます。

まとめ

完全なメニューリリースを準備し、内容に基づく名前の ConfigMap を生成して、両方のアプリケーションレプリカへの Deployment のロールアウトを確認しました。実際のページとダウンロードを調べ、参照用カフェと以前の設定を維持し、実際のスタッフ用 CSV を引き渡しました。

次の実験は別の環境で始まります。同じ考え方を使い、アプリケーションは正常でも価格が誤っているメニューを復元します。