Kubernetes ポッドの起動時にコマンドを実行する方法

KubernetesKubernetesBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

このチュートリアルでは、Kubernetes のポッド起動時にコマンドを実行する方法を説明します。command フィールドと args フィールドを使用して起動コマンドを設定する方法、複数のコマンドを実行する方法、および起動失敗を処理する方法を学びます。これらの概念を実際に練習できるローカルの Kubernetes 環境を作成するために、Minikube を使用します。

この実験の終了時には、Kubernetes のポッドの起動時の動作をカスタマイズし、アプリケーションを円滑にデプロイする方法を理解するようになります。この知識は、Kubernetes 環境でコンテナ化されたアプリケーションを適切に構成するために不可欠です。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL kubernetes(("Kubernetes")) -.-> kubernetes/BasicsGroup(["Basics"]) kubernetes(("Kubernetes")) -.-> kubernetes/BasicCommandsGroup(["Basic Commands"]) kubernetes(("Kubernetes")) -.-> kubernetes/AdvancedCommandsGroup(["Advanced Commands"]) kubernetes(("Kubernetes")) -.-> kubernetes/TroubleshootingandDebuggingCommandsGroup(["Troubleshooting and Debugging Commands"]) kubernetes(("Kubernetes")) -.-> kubernetes/ConfigurationandVersioningGroup(["Configuration and Versioning"]) kubernetes/BasicsGroup -.-> kubernetes/initialization("Initialization") kubernetes/BasicCommandsGroup -.-> kubernetes/get("Get") kubernetes/BasicCommandsGroup -.-> kubernetes/create("Create") kubernetes/BasicCommandsGroup -.-> kubernetes/delete("Delete") kubernetes/AdvancedCommandsGroup -.-> kubernetes/apply("Apply") kubernetes/TroubleshootingandDebuggingCommandsGroup -.-> kubernetes/exec("Exec") kubernetes/TroubleshootingandDebuggingCommandsGroup -.-> kubernetes/logs("Logs") kubernetes/ConfigurationandVersioningGroup -.-> kubernetes/config("Config") subgraph Lab Skills kubernetes/initialization -.-> lab-392761{{"Kubernetes ポッドの起動時にコマンドを実行する方法"}} kubernetes/get -.-> lab-392761{{"Kubernetes ポッドの起動時にコマンドを実行する方法"}} kubernetes/create -.-> lab-392761{{"Kubernetes ポッドの起動時にコマンドを実行する方法"}} kubernetes/delete -.-> lab-392761{{"Kubernetes ポッドの起動時にコマンドを実行する方法"}} kubernetes/apply -.-> lab-392761{{"Kubernetes ポッドの起動時にコマンドを実行する方法"}} kubernetes/exec -.-> lab-392761{{"Kubernetes ポッドの起動時にコマンドを実行する方法"}} kubernetes/logs -.-> lab-392761{{"Kubernetes ポッドの起動時にコマンドを実行する方法"}} kubernetes/config -.-> lab-392761{{"Kubernetes ポッドの起動時にコマンドを実行する方法"}} end

Kubernetes 環境のセットアップ

このステップでは、Minikube を起動し、この実験に必要な基本的な Kubernetes の概念を理解することで、環境を準備します。

Kubernetes とは何ですか?

Kubernetes は、アプリケーションコンテナのデプロイ、スケーリング、および運用を自動化するために設計されたオープンソースのプラットフォームです。Kubernetes の核心はポッド (Pod) で、これは作成および管理できる最小のデプロイ可能な単位です。

Minikube の起動

Minikube は、Kubernetes をローカルで実行できるツールです。以下のコマンドで起動しましょう。

minikube start --driver=docker

このコマンドは、Docker をドライバーとして使用してローカルの Kubernetes クラスターを作成します。必要なコンポーネントをダウンロードするため、起動プロセスには数分かかる場合があります。

以下のような出力が表示されるはずです。

😄  minikube v1.30.1 on Ubuntu 22.04
✨  Using the docker driver based on user configuration
📌  Using Docker driver with root privileges
👍  Starting control plane node minikube in cluster minikube
🚜  Pulling base image ...
🔥  Creating docker container (CPUs=2, Memory=2200MB) ...
🐳  Preparing Kubernetes v1.27.4 on Docker 24.0.4 ...
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
🔎  Verifying Kubernetes components...
🌟  Enabled addons: default-storageclass, storage-provisioner
💡  kubectl not found. If you need it, try: 'minikube kubectl -- get pods -A'
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

インストールの確認

Minikube クラスターの状態を確認することで、すべてが正常に動作していることを確認しましょう。

minikube status

Minikube が実行中であることを示す出力が表示されるはずです。

minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

次に、kubectl (Kubernetes のコマンドラインツール) が正しく構成されていることを確認しましょう。

kubectl get nodes

1 つのノード (Minikube インスタンス) が Ready として表示されるはずです。

NAME       STATUS   ROLES           AGE     VERSION
minikube   Ready    control-plane   2m15s   v1.27.4

Kubernetes ポッドの理解

ポッド (Pod) は、Kubernetes アプリケーションの基本的な実行単位です。各ポッドは、クラスター上で実行中のプロセスを表し、1 つ以上のコンテナをカプセル化します。ポッドは設計上一時的であり、必要に応じて作成、破棄、再作成することができます。

Kubernetes では、通常、ポッドを YAML ファイルで定義します。この実験では、環境にいくつかのサンプル YAML ファイルを用意しています。

これらのファイルがあるディレクトリに移動しましょう。

cd ~/project/kubernetes-examples
ls -la

以下のファイルが表示されるはずです。

total 20
drwxr-xr-x 2 labex labex 4096 Sep 21 10:00 .
drwxr-xr-x 3 labex labex 4096 Sep 21 10:00 ..
-rw-r--r-- 1 labex labex  193 Sep 21 10:00 basic-pod.yaml
-rw-r--r-- 1 labex labex  254 Sep 21 10:00 liveness-probe-pod.yaml
-rw-r--r-- 1 labex labex  312 Sep 21 10:00 multi-command-pod.yaml
-rw-r--r-- 1 labex labex  263 Sep 21 10:00 startup-command-pod.yaml

これで環境のセットアップが完了したので、Kubernetes ポッドを操作し、起動時にコマンドを実行する方法を学ぶ準備ができました。

基本的な起動コマンドを持つ最初のポッドの作成

このステップでは、最初の Kubernetes ポッドを作成し、起動時にコマンドがどのように実行されるかを理解します。コンテナが起動するときに実行する内容を定義する command フィールドを調べます。

基本的なポッド構成の調査

まず、基本的なポッドの構成を調べましょう。nano エディタで basic-pod.yaml ファイルを開きます。

nano basic-pod.yaml

次の内容の YAML ファイルが表示されます。

apiVersion: v1
kind: Pod
metadata:
  name: basic-pod
spec:
  containers:
    - name: ubuntu
      image: ubuntu:20.04
      command: ["/bin/bash", "-c", "echo 'Pod is running' && sleep 3600"]

この構成では以下が定義されています。

  • basic-pod という名前のポッド
  • ubuntu:20.04 イメージを使用する ubuntu という名前の単一のコンテナ
  • メッセージを表示してから 3600 秒 (1 時間) スリープする起動コマンド

command フィールドは、コンテナが起動するときに実行される実行可能ファイルを指定します。この場合、-c フラグを付けて /bin/bash シェルを実行しており、これにより実行するコマンドの文字列を渡すことができます。

Ctrl+X を押して nano エディタを終了します。

ポッドの作成

このポッドを Kubernetes クラスターに作成しましょう。

kubectl apply -f basic-pod.yaml

以下のような出力が表示されるはずです。

pod/basic-pod created

ポッドの状態を確認する

ポッドが正常に実行されているか確認しましょう。

kubectl get pods

以下のような出力が表示されるはずです。

NAME        READY   STATUS    RESTARTS   AGE
basic-pod   1/1     Running   0          30s

これは、ポッドが正常に実行されていることを示しています。READY の下の 1/1 は、期待される 1 つのコンテナのうち 1 つが実行されていることを意味します。

ポッドのログを表示する

起動コマンドの出力を確認するには、ポッドのログを確認できます。

kubectl logs basic-pod

以下のように表示されるはずです。

Pod is running

これにより、起動コマンドが正常に実行されたことが確認できます。

実行中のコンテナを調査する

インタラクティブシェルを実行して、コンテナ内で何が起こっているかを調べましょう。

kubectl exec -it basic-pod -- /bin/bash

これでコンテナのシェル内に入りました。プロセスが実行されていることを確認しましょう。

ps aux

起動コマンドの一部である sleep コマンドが実行されているのが表示されるはずです。

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   4112  3372 ?        Ss   10:05   0:00 /bin/bash -c echo 'Pod is running' && sleep 3600
root         7  0.0  0.0   4112  3536 pts/0    Ss   10:06   0:00 /bin/bash
root        14  0.0  0.0   5900  2928 pts/0    R+   10:06   0:00 ps aux
root        15  0.0  0.0   2512   580 ?        S    10:06   0:00 sleep 3600

PID が 1 のプロセスが起動コマンドで、sleep 3600 コマンドは別のプロセスとして実行されています。

以下を入力してコンテナのシェルを終了します。

exit

ポッドのライフサイクルの理解

ポッドを作成すると、いくつかのフェーズを経ます。

  1. Pending:ポッドは Kubernetes によって受け入れられましたが、まだ実行されていません。
  2. Running:ポッドがすべてのコンテナとともに実行されています。
  3. Succeeded:ポッド内のすべてのコンテナが正常に終了しました。
  4. Failed:すべてのコンテナが終了し、少なくとも 1 つのコンテナが失敗しました。
  5. Unknown:ポッドの状態を判断できません。

メインプロセス (sleep 3600) がまだ実行されているため、ポッドは Running 状態にあります。このプロセスが完了するか、終了されると、終了コードに応じてポッドは Succeeded または Failed 状態に移行します。

これで、基本的なポッドを作成し、command フィールドを使用して起動時にコマンドを実行する方法がわかりました。

起動設定における command と args の使用

このステップでは、Kubernetes ポッドでより複雑な起動動作を設定するために、commandargs フィールドを一緒に使用する方法を学びます。

command と args の理解

Kubernetes では、コンテナが起動するときに実行するコマンドを指定する主な方法が 2 つあります。

  1. command:実行する実行可能ファイルを指定します(Docker の ENTRYPOINT に似ています)。
  2. args:コマンドに渡す引数を指定します(Docker の CMD に似ています)。

これらのフィールドを個別にまたは一緒に使用することで、コンテナの起動方法を柔軟に設定できます。

起動コマンドポッドの調査

startup-command-pod.yaml ファイルを調べましょう。

nano startup-command-pod.yaml

次の構成が表示されます。

apiVersion: v1
kind: Pod
metadata:
  name: startup-command-pod
spec:
  containers:
    - name: ubuntu
      image: ubuntu:20.04
      command: ["/bin/bash"]
      args:
        ["-c", "echo 'Custom startup message' > /tmp/startup.txt && sleep 3600"]

この構成では、以下のことが行われています。

  • command フィールドで /bin/bash を実行することを指定しています。
  • args フィールドで bash に渡す引数 -c とコマンドを含む文字列を提供しています。

コマンドと引数を分けることで、構成がより読みやすく、保守しやすくなります。

Ctrl+X を押して nano エディタを終了します。

起動コマンドポッドの作成

このポッドを作成しましょう。

kubectl apply -f startup-command-pod.yaml

以下のように表示されるはずです。

pod/startup-command-pod created

ポッドの状態を確認する

ポッドが実行されていることを確認します。

kubectl get pods startup-command-pod

以下のように表示されるはずです。

NAME                  READY   STATUS    RESTARTS   AGE
startup-command-pod   1/1     Running   0          30s

起動コマンドの検証

起動コマンドが正しく実行されたことを、期待されるファイルが作成されたかどうかを確認することで検証しましょう。

kubectl exec startup-command-pod -- cat /tmp/startup.txt

以下のように表示されるはずです。

Custom startup message

これにより、コマンドが正常に実行され、指定された内容のファイルが作成されたことが確認できます。

command と args の違いの理解

commandargs の関係を理解することは重要です。

  1. command のみを指定すると、コンテナイメージのデフォルトの ENTRYPOINT が上書きされます。
  2. args のみを指定すると、コンテナイメージのデフォルトの CMD が上書きされます。
  3. commandargs の両方を指定すると、ENTRYPOINT と CMD の両方が上書きされます。

ポッドの構成を変更するとどうなるか見てみましょう。modified-command-pod.yaml という新しいファイルを作成します。

nano modified-command-pod.yaml

以下の内容を追加します。

apiVersion: v1
kind: Pod
metadata:
  name: modified-command-pod
spec:
  containers:
    - name: ubuntu
      image: ubuntu:20.04
      command: ["/bin/echo"]
      args: ["This message is printed by echo"]

Ctrl+X を押し、続いて YEnter を押して保存して終了します。

このポッドを作成しましょう。

kubectl apply -f modified-command-pod.yaml

以下のように表示されるはずです。

pod/modified-command-pod created

何が起こったかを確認するためにログを確認します。

kubectl logs modified-command-pod

以下のように表示されるはずです。

This message is printed by echo

ポッドが指定された引数で /bin/echo コマンドを実行し、echo が出力を印刷した後に終了したことに注意してください。

ポッドの状態を確認します。

kubectl get pods modified-command-pod

以下のような表示がされるはずです。

NAME                   READY   STATUS      RESTARTS   AGE
modified-command-pod   0/1     Completed   0          45s

Completed ステータスは、ポッドが正常に実行されて終了したことを示しています。

これで、Kubernetes ポッドの起動動作を設定するために commandargs を一緒に使用する方法がわかりました。

複数のコマンドの実行と起動失敗の処理

このステップでは、ポッド起動時に複数のコマンドを実行する方法と、ヘルスチェックを使用して起動失敗を処理する方法を学びます。

複数のコマンドの実行

コンテナが起動するときに複数のコマンドを実行する必要があることがよくあります。Kubernetes では、これを行う方法がいくつかあります。

  1. シェル演算子 (&&, ; など) を使用してコマンドを連鎖させる
  2. スクリプトファイルを使用する
  3. 初期化コンテナ (init container) を使用する

最初の方法を、multi-command-pod.yaml ファイルを調べることで探ってみましょう。

nano multi-command-pod.yaml

以下の内容が表示されます。

apiVersion: v1
kind: Pod
metadata:
  name: multi-command-pod
spec:
  containers:
    - name: ubuntu
      image: ubuntu:20.04
      command: ["/bin/bash", "-c"]
      args:
        [
          "echo 'First command' > /tmp/first.txt && echo 'Second command' > /tmp/second.txt && sleep 3600"
        ]

この構成では、&& 演算子を使用して複数のコマンドを連鎖させています。この演算子は、前のコマンドが成功した場合にのみ次のコマンドを実行します。

Ctrl+X を押してエディタを終了します。

このポッドを作成しましょう。

kubectl apply -f multi-command-pod.yaml

以下のように表示されるはずです。

pod/multi-command-pod created

作成されたファイルを確認することで、両方のコマンドが実行されたことを検証しましょう。

kubectl exec multi-command-pod -- cat /tmp/first.txt

以下のように表示されるはずです。

First command

2 つ目のファイルについても同様に確認します。

kubectl exec multi-command-pod -- cat /tmp/second.txt

以下のように表示されるはずです。

Second command

ヘルスチェックによる起動失敗の処理

Kubernetes は、起動失敗を検出して処理するメカニズムを提供しています。

  1. 生存性プローブ (Liveness Probes):コンテナが実行中かどうかを確認します。実行中でない場合、Kubernetes はコンテナを再起動します。
  2. 就緒性プローブ (Readiness Probes):コンテナがトラフィックを受け入れる準備ができているかどうかを確認します。
  3. 起動プローブ (Startup Probes):アプリケーションが起動したかどうかを確認します。起動が遅いコンテナに役立ちます。

生存性プローブを使用するポッドを調べてみましょう。

nano liveness-probe-pod.yaml

以下の内容が表示されます。

apiVersion: v1
kind: Pod
metadata:
  name: liveness-probe-pod
spec:
  containers:
    - name: ubuntu
      image: ubuntu:20.04
      command: ["/bin/bash", "-c"]
      args: ["touch /tmp/healthy && sleep 3600"]
      livenessProbe:
        exec:
          command: ["cat", "/tmp/healthy"]
        initialDelaySeconds: 5
        periodSeconds: 5

この構成では、以下のことが行われています。

  • コンテナは起動時に /tmp/healthy ファイルを作成します。
  • 生存性プローブは、このファイルを 5 秒ごとに確認します。
  • ファイルが存在しない場合、Kubernetes はコンテナが不健康であると見なし、コンテナを再起動します。

Ctrl+X を押してエディタを終了します。

このポッドを作成しましょう。

kubectl apply -f liveness-probe-pod.yaml

以下のように表示されるはずです。

pod/liveness-probe-pod created

ポッドが実行されていることを確認します。

kubectl get pods liveness-probe-pod

以下のように表示されるはずです。

NAME                 READY   STATUS    RESTARTS   AGE
liveness-probe-pod   1/1     Running   0          30s

ヘルスチェックファイルを削除するとどうなるか見てみましょう。

kubectl exec liveness-probe-pod -- rm /tmp/healthy

約 10 秒待ってから、ポッドの状態を再度確認します。

kubectl get pods liveness-probe-pod

コンテナが再起動されたことがわかるはずです。

NAME                 READY   STATUS    RESTARTS   AGE
liveness-probe-pod   1/1     Running   1          60s

RESTARTS のカウントが 1 に増えています。これは、Kubernetes が不健康な状態を検出してコンテナを再起動したことを示しています。

ヘルスチェックファイルが再び存在することを検証しましょう(コンテナが再起動されたときに起動コマンドによって再作成されるはずです)。

kubectl exec liveness-probe-pod -- ls -la /tmp/healthy

ファイルが再び存在することがわかるはずです。

-rw-r--r-- 1 root root 0 Sep 21 10:30 /tmp/healthy

これは、Kubernetes が起動失敗から自動的に回復し、アプリケーションの望ましい状態を維持できることを示しています。

カスタム起動スクリプトの作成

より複雑な初期化には、カスタム起動スクリプトを使用することができます。シェルスクリプトを使用して起動するポッドを作成してみましょう。

nano script-pod.yaml

以下の内容を追加します。

apiVersion: v1
kind: Pod
metadata:
  name: script-pod
spec:
  containers:
    - name: ubuntu
      image: ubuntu:20.04
      command: ["/bin/bash", "-c"]
      args:
        - |
          cat > /tmp/startup.sh << 'EOF'
          #!/bin/bash
          echo "Script started at $(date)" > /tmp/script-log.txt
          echo "Creating configuration files..." >> /tmp/script-log.txt
          mkdir -p /tmp/config
          echo "app_name=MyApp" > /tmp/config/app.conf
          echo "version=1.0" >> /tmp/config/app.conf
          echo "Script completed successfully" >> /tmp/script-log.txt
          EOF
          chmod +x /tmp/startup.sh
          /tmp/startup.sh
          sleep 3600

この構成では、以下のことが行われています。

  1. コンテナ内に起動スクリプトを作成します。
  2. スクリプトを実行可能にします。
  3. スクリプトを実行します。
  4. sleep コマンドでコンテナを実行し続けます。

Ctrl+X を押し、続いて YEnter を押して保存して終了します。

このポッドを作成しましょう。

kubectl apply -f script-pod.yaml

以下のように表示されるはずです。

pod/script-pod created

ポッドが起動するのを少し待ってから、その状態を確認します。

kubectl get pods script-pod

以下のように表示されるはずです。

NAME         READY   STATUS    RESTARTS   AGE
script-pod   1/1     Running   0          30s

スクリプトの出力を確認しましょう。

kubectl exec script-pod -- cat /tmp/script-log.txt

以下のような内容が表示されるはずです。

Script started at Tue Sep 21 10:35:42 UTC 2023
Creating configuration files...
Script completed successfully

設定ファイルが作成されたことを検証しましょう。

kubectl exec script-pod -- cat /tmp/config/app.conf

以下のように表示されるはずです。

app_name=MyApp
version=1.0

これは、Kubernetes でコンテナを初期化するために複雑な起動スクリプトを使用する方法を示しています。

ベストプラクティスと実世界でのアプリケーション

この最後のステップでは、Kubernetes ポッドの起動時にコマンドを実行するためのベストプラクティスを探り、これらのプラクティスを実装した実世界のアプリケーションの例を作成します。

起動コマンドのベストプラクティス

Kubernetes ポッドの起動コマンドを構成する際には、以下のベストプラクティスを考慮してください。

  1. 起動コマンドを冪等性 (idempotent) にする:コマンドは複数回実行しても問題が発生しないようにする必要があります。
  2. ヘルスチェックを使用する:生存性 (liveness) および就緒性 (readiness) プローブを実装して、起動が成功したことを検証します。
  3. エラーを適切に処理する:起動スクリプトにエラーハンドリングを組み込みます。
  4. 関心事を分離する:初期化タスクには、メインアプリケーションとは別に初期化コンテナ (init container) を使用します。
  5. 起動時間を制限する:初期化を迅速に行い、デプロイ時間を短縮します。
  6. 環境変数を使用する:環境変数を介して起動コマンドを設定可能にします。
  7. 起動の進捗をログに残す:トラブルシューティングのために明確なログを出力します。

起動タスクに初期化コンテナを使用する

初期化コンテナは、アプリケーションコンテナが起動する前に実行され、セットアップタスクに最適です。初期化コンテナを持つポッドを作成してみましょう。

nano init-container-pod.yaml

以下の内容を追加します。

apiVersion: v1
kind: Pod
metadata:
  name: init-container-pod
spec:
  initContainers:
    - name: init-config
      image: ubuntu:20.04
      command: ["/bin/bash", "-c"]
      args:
        - |
          echo "Initializing configuration..."
          mkdir -p /work-dir/config
          echo "database_url=mysql://user:password@db:3306/mydb" > /work-dir/config/db.conf
          echo "api_key=1234567890" > /work-dir/config/api.conf
          echo "Initialization complete"
      volumeMounts:
        - name: shared-volume
          mountPath: /work-dir
  containers:
    - name: app
      image: ubuntu:20.04
      command: ["/bin/bash", "-c"]
      args:
        - |
          echo "Application starting..."
          echo "Reading configuration:"
          cat /work-dir/config/db.conf
          cat /work-dir/config/api.conf
          echo "Application running..."
          sleep 3600
      volumeMounts:
        - name: shared-volume
          mountPath: /work-dir
  volumes:
    - name: shared-volume
      emptyDir: {}

この構成では、以下のことが行われています。

  1. 初期化コンテナ init-config が最初に実行され、設定ファイルが作成されます。
  2. 両方のコンテナは shared-volume という名前のボリュームを共有します。
  3. メインアプリケーションコンテナは、初期化コンテナによって作成された設定を読み取ります。

Ctrl+X を押し、続いて YEnter を押して保存して終了します。

このポッドを作成しましょう。

kubectl apply -f init-container-pod.yaml

以下のように表示されるはずです。

pod/init-container-pod created

ポッドの状態を確認します。

kubectl get pods init-container-pod

ポッドが実行中であることがわかるはずです。

NAME                 READY   STATUS    RESTARTS   AGE
init-container-pod   1/1     Running   0          30s

メインコンテナのログを確認しましょう。

kubectl logs init-container-pod -c app

以下のような内容が表示されるはずです。

Application starting...
Reading configuration:
database_url=mysql://user:password@db:3306/mydb
api_key=1234567890
Application running...

これにより、初期化コンテナが設定ファイルを正常に作成し、メインコンテナがそれらを読み取ることができたことが確認できます。

実世界の例: データベースチェックを行う Web アプリケーション

もっと現実的な例を作成してみましょう。起動前にデータベースの可用性をチェックする Web アプリケーションです。

nano webapp-pod.yaml

以下の内容を追加します。

apiVersion: v1
kind: Pod
metadata:
  name: webapp-pod
spec:
  initContainers:
    - name: wait-for-db
      image: busybox:1.28
      command: ["/bin/sh", "-c"]
      args:
        - |
          echo "Checking for database availability..."
          ## In a real scenario, this would check an actual database
          ## For this example, we'll simulate success after a short delay
          sleep 5
          echo "Database is available"
          touch /tmp/db-ready
      volumeMounts:
        - name: shared-volume
          mountPath: /tmp
  containers:
    - name: webapp
      image: nginx:1.19
      ports:
        - containerPort: 80
      command: ["/bin/sh", "-c"]
      args:
        - |
          if [ -f /tmp/db-ready ]; then
            echo "Database connection verified, starting web application..."
            ## Customize nginx configuration
            echo "<h1>Web Application Started Successfully</h1>" > /usr/share/nginx/html/index.html
            echo "<p>Connected to database</p>" >> /usr/share/nginx/html/index.html
            ## Start nginx
            nginx -g 'daemon off;'
          else
            echo "Error: Database not available"
            exit 1
          fi
      volumeMounts:
        - name: shared-volume
          mountPath: /tmp
      readinessProbe:
        httpGet:
          path: /
          port: 80
        initialDelaySeconds: 5
        periodSeconds: 5
  volumes:
    - name: shared-volume
      emptyDir: {}

この構成では、以下のことが行われています。

  1. 初期化コンテナを使用してデータベースの可用性をチェックします(シミュレート)。
  2. メインコンテナは起動前に初期化コンテナによって作成されたファイルをチェックします。
  3. アプリケーションがトラフィックを提供していることを検証するための就緒性プローブを含みます。
  4. コンテナ間の通信に共有ボリュームを使用します。

Ctrl+X を押し、続いて YEnter を押して保存して終了します。

このポッドを作成しましょう。

kubectl apply -f webapp-pod.yaml

以下のように表示されるはずです。

pod/webapp-pod created

ポッドが完全に起動するのを少し待ってから、その状態を確認します。

kubectl get pods webapp-pod

以下のように表示されるはずです。

NAME         READY   STATUS    RESTARTS   AGE
webapp-pod   1/1     Running   0          30s

READY 列の 1/1 は、就緒性プローブが成功したことを示しています。

Web アプリケーションにアクセスするためにポートフォワーディングを行いましょう。

kubectl port-forward webapp-pod 8080:80 &

このコマンドはバックグラウンドで実行されます(& のため)。これで curl を使用して Web アプリケーションにアクセスできます。

curl http://localhost:8080

以下のように表示されるはずです。

<h1>Web Application Started Successfully</h1>
<p>Connected to database</p>

これにより、アプリケーションが正しく初期化され、データベースの可用性が検証され、現在トラフィックを提供していることが確認できます。

ポートフォワーディングプロセスを停止します。

pkill -f "kubectl port-forward"

クリーンアップ

実験を終える前に、作成したリソースをクリーンアップしましょう。

kubectl delete pod basic-pod startup-command-pod modified-command-pod multi-command-pod liveness-probe-pod script-pod init-container-pod webapp-pod

以下のように表示されるはずです。

pod "basic-pod" deleted
pod "startup-command-pod" deleted
pod "modified-command-pod" deleted
pod "multi-command-pod" deleted
pod "liveness-probe-pod" deleted
pod "script-pod" deleted
pod "init-container-pod" deleted
pod "webapp-pod" deleted

これで、Kubernetes ポッドの起動時にコマンドを実行する方法、複数のコマンドを実行する方法、エラーを処理する方法、および実世界のシナリオでベストプラクティスを適用する方法を学びました。

まとめ

この実験では、Kubernetes ポッドの起動時にコマンドを実行する方法を学びました。以下の内容に関する実践的な経験を積みました。

  • Minikube を使用して Kubernetes 環境をセットアップする
  • 特定の起動コマンドを持つポッドを作成および管理する
  • commandargs フィールドを使用してコンテナの動作を構成する
  • シェル演算子とスクリプトを使用して複数のコマンドを実行する
  • ヘルスチェックを使用して起動失敗を処理する
  • 初期化コンテナ (init container) を使用してベストプラクティスを実装する
  • 適切な初期化が必要な実世界のアプリケーションを構築する

これらのスキルは、Kubernetes 環境でコンテナ化されたアプリケーションをデプロイするために不可欠です。起動コマンドを適切に構成することで、アプリケーションが正しく初期化され、依存関係が検証され、エラーが適切に処理されることを保証できます。

Kubernetes の学習を続ける際には、適切なアプリケーションの初期化が、信頼性が高く、スケーラブルで、保守可能なシステムを構築する上で重要な要素であることを忘れないでください。