Init コンテナ

Kubernetes でメインコンテナの起動前に初期化処理を実行する特殊なコンテナ

Kubernetesコンテナ

Init コンテナとは

Init コンテナは、Pod のメインコンテナが起動する前に実行される特殊なコンテナである。初期化処理 (依存サービスの待機、DB マイグレーション、設定ファイルの生成) をメインコンテナから分離し、関心の分離を実現する。

Init コンテナは定義順に直列実行され、すべてが正常終了 (exit 0) するまでメインコンテナは起動しない。1 つでも失敗すると Pod 全体が再起動される。

基本的な設定

apiVersion: v1
kind: Pod
metadata:
  name: api-server
spec:
  initContainers:
    - name: wait-for-db
      image: busybox:1.36
      command: ['sh', '-c', 'until nc -z postgres-svc 5432; do echo "waiting..."; sleep 2; done']
    - name: migrate
      image: myapp:1.0
      command: ['npm', 'run', 'migrate']
      env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: url
  containers:
    - name: app
      image: myapp:1.0
      ports:
        - containerPort: 3000

この例では、まず wait-for-db が PostgreSQL の起動を待ち、次に migrate が DB マイグレーションを実行し、両方が成功してからメインの app コンテナが起動する。

メインコンテナとの違い

観点 Init コンテナ メインコンテナ サイドカー
実行タイミング メインの前 Init 完了後 メインと同時
実行順序 定義順に直列 同時に起動 同時に起動
完了条件 exit 0 が必須 常時稼働 常時稼働
失敗時 Pod 再起動 restartPolicy に従う restartPolicy に従う
リソース メインと別に設定可能 - メインと別に設定可能

Init コンテナはメインコンテナと異なるイメージを使える。マイグレーションツールやネットワークユーティリティなど、メインアプリには不要なツールを Init コンテナだけに含めることで、メインイメージをクリーンに保てる。

実務での活用パターン

依存サービスの待機

最も一般的な用途。DB、キャッシュ、他のマイクロサービスが起動するまで待つ。

- name: wait-for-redis
  image: busybox:1.36
  command: ['sh', '-c', 'until nc -z redis-svc 6379; do sleep 1; done']

DB マイグレーション

メインアプリの起動前にスキーマを更新する。複数 Pod がある場合でも、Init コンテナは各 Pod で実行されるため、マイグレーションのべき等性を確保する必要がある。

シークレットの取得

AWS Secrets Manager や HashiCorp Vault からシークレットを取得し、共有ボリュームにファイルとして書き出す。メインコンテナはファイルを読むだけでよい。

設定ファイルの動的生成

テンプレートから環境固有の設定ファイルを生成し、共有ボリュームに配置する。

Init コンテナが失敗した場合

Init コンテナが失敗すると、Pod は Init:Error または Init:CrashLoopBackOff 状態になる。restartPolicy: Always (デフォルト) の場合、Kubernetes は Init コンテナを最初からやり直す。

# Init コンテナの状態を確認
kubectl describe pod api-server
# Init Containers:
#   wait-for-db:
#     State: Terminated
#     Reason: Error
#     Exit Code: 1

# Init コンテナのログを確認
kubectl logs api-server -c wait-for-db

よくある落とし穴

Init コンテナのタイムアウト

依存サービスが起動しない場合、Init コンテナが永遠に待ち続ける。タイムアウトを設定し、一定時間後に失敗させる。

command: ['sh', '-c', 'timeout 60 sh -c "until nc -z postgres-svc 5432; do sleep 2; done"']

リソース制限の未設定

Init コンテナにもリソース制限 (resources.limits) を設定する。マイグレーションが大量のメモリを消費すると、ノード全体に影響する。

基礎から学ぶなら関連書籍が手がかりになる。

関連用語