アプリケーションを開発している際や、既存のアプリケーションをkubernetes上で稼働できるように置き換えをしていく起動順序に他のアプリケーションとの兼ね合いで、Podが再起動を繰り返す(=CrashLoopBackOff)するケースがあります。そのようなケースには、InitContainerを使って解決するのが良いので、紹介します。
よくあるケース
アプリケーションの起動シーケンスでは、下記のようなことが多いかと思います。
- DBアクセス(コネクション生成)
- メッセージブローカ初期化 + コネクション生成
- 他サービスとのコネクション生成
など、依存先のアプリケーションがすでに立ち上がっていることを前提にするケースが多いです。
postgresを例に具体的に考えてみる
下記例は、postgresをDBを生成するサービス、Statefullsets, Podのマニュフェスト例です。
apiVersion: v1 kind: Service metadata: name: postgres-svc spec: ports: - port: 5432 selector: app: postgres clusterIP: None --- apiVersion: apps/v1 kind: StatefulSet metadata: name: postgres-sts spec: serviceName: postgres-svc replicas: 1 selector: matchLabels: app: postgres template: metadata: labels: app: postgres spec: containers: - name: postgres image: postgres:latest ports: - containerPort: 5432 env: - name: POSTGRES_USER value: dmin - name: POSTGRES_PASSWORD value: admin - name: PGDATA value: /var/lib/postgresql/data/pgdata - name: POSTGRES_DB value: sample volumeMounts: - name: postgres-pvc mountPath: /var/lib/postgresql/data/pgdata subPath: postgres volumeClaimTemplates: - metadata: name: postgres-pvc spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 3Gi
StatefullsetsでPodを起動するケースは、起動に少し時間がかかります。下記のようなコンテナを同時に起動してまうと、“CrashLoopBackOff”を繰り返し、kubectl get pods
等で確認するとRESTARTS回数が増えていきます。
apiVersion: v1 kind: Pod metadata: name: sample-app spec: containers: - image: xxxx:latest # DBアクセスするアプリ name: sample
kubernetesには、Init Containersという仕組みがあります。このInit Containersは、Pod内でメインとなるコンテナを起動する前に別のコンテナを起動させる機能です。この機能を使うことで、DBアクセス可能になるまでまつことが可能になります。
apiVersion: v1 kind: Pod metadata: name: sample-app spec: initContainers: - name: check-db-ready image: postgres:latest command: ['sh', '-c', 'until pg_isready -h postgres-svc -p 5432; do echo waiting for database; sleep 2; done;'] containers: - image: xxxx:latest # DBアクセスするアプリ name: nginx
このようにすることで、postgresが立ち上がって、通信できる状態になるまで待つことができます。initContainers自体、containersと同様、複数のPodを記載することができます。 他の利用方法としては、自動テストなどで利用するデータの投入処理なんかにも利用可能です。このようにすることで、メインのコンテナは、必要な処理だけ記載できます。
今回は、kubernetes利用時によく出るエラー”CrashLoopBackOff”の対処方法の一つとして、initContainersを紹介しました。お疲れさまでした。