7.2. Pod のデプロイ前の、Init コンテナーの使用によるタスクの実行

OpenShift Container Platform は、Init コンテナー を提供します。 このコンテナーは、アプリケーションコンテナーの前に実行される特殊なコンテナーであり、アプリのイメージに存在しないユーティリティーまたはセットアップスクリプトを含めることができます。

7.2.1. Init コンテナーについて

Pod の残りの部分がデプロイされる前に、init コンテナーリソースを使用して、タスクを実行することができます。

Pod は、アプリケーションコンテナーに加えて、init コンテナーを持つことができます。Init コンテナーにより、セットアップスクリプトとバインディングコードを再編成できます。

init コンテナーは以下のことを行うことができます。

  • セキュリティー上の理由のためにアプリケーションコンテナーイメージに含めることが望ましくないユーティリティーを含めることができ、それらを実行できます。
  • アプリのイメージに存在しないセットアップに必要なユーティリティーまたはカスタムコードを含めることができます。たとえば、単に Sed、Awk、Python、Dig のようなツールをセットアップ時に使用するために別のイメージからイメージを作成する必要はありません。
  • Linux namespace を使用して、アプリケーションコンテナーがアクセスできないシークレットへのアクセスなど、アプリケーションコンテナーとは異なるファイルシステムビューを設定できます。

各 init コンテナーは、次のコンテナーが起動する前に正常に完了している必要があります。そのため、Init コンテナーには、一連の前提条件が満たされるまでアプリケーションコンテナーの起動をブロックしたり、遅延させたりする簡単な方法となります。

たとえば、以下は init コンテナーを使用するいくつかの方法になります。

  • 以下のようなシェルコマンドでサービスが作成されるまで待機します。

    for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; exit 1
  • 以下のようなコマンドを使用して、Downward API からリモートサーバーにこの Pod を登録します。

    $ curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d ‘instance=$()&ip=$()’
  • sleep 60 のようなコマンドを使用して、アプリケーションコンテナーが起動するまでしばらく待機します。
  • Git リポジトリーのクローンをボリュームに作成します。
  • 設定ファイルに値を入力し、テンプレートツールを実行して、主要なアプリコンテナーの設定ファイルを動的に生成します。たとえば、設定ファイルに POD_IP の値を入力し、Jinja を使用して主要なアプリ設定ファイルを生成します。

詳細は、Kubernetes ドキュメント を参照してください。

7.2.2. Init コンテナーの作成

以下の例は、2 つの init コンテナーを持つ単純な Pod の概要を示しています。1 つ目は myservice を待機し、2 つ目は mydb を待機します。両方のコンテナーが完了すると、Pod が開始されます。

手順

  1. Init コンテナーの Pod を作成します。

    1. 以下のような YAML ファイルを作成します。

      apiVersion: v1
      kind: Pod
      metadata:
        name: myapp-pod
        labels:
          app: myapp
      spec:
        containers:
        - name: myapp-container
          image: registry.access.redhat.com/ubi8/ubi:latest
          command: ['sh', '-c', 'echo The app is running! && sleep 3600']
        initContainers:
        - name: init-myservice
          image: registry.access.redhat.com/ubi8/ubi:latest
          command: ['sh', '-c', 'until getent hosts myservice; do echo waiting for myservice; sleep 2; done;']
        - name: init-mydb
          image: registry.access.redhat.com/ubi8/ubi:latest
          command: ['sh', '-c', 'until getent hosts mydb; do echo waiting for mydb; sleep 2; done;']
      # ...
    2. Pod を作成します。

      $ oc create -f myapp.yaml
    3. Pod のステータスを表示します。

      $ oc get pods

      出力例

      NAME                          READY     STATUS              RESTARTS   AGE
      myapp-pod                     0/1       Init:0/2            0          5s

      Pod のステータス Init:0/2 は、2 つのサービスを待機していることを示します。

  2. myservice サービスを作成します。

    1. 以下のような YAML ファイルを作成します。

      kind: Service
      apiVersion: v1
      metadata:
        name: myservice
      spec:
        ports:
        - protocol: TCP
          port: 80
          targetPort: 9376
    2. Pod を作成します。

      $ oc create -f myservice.yaml
    3. Pod のステータスを表示します。

      $ oc get pods

      出力例

      NAME                          READY     STATUS              RESTARTS   AGE
      myapp-pod                     0/1       Init:1/2            0          5s

      Pod のステータス Init:1/2 は、1 つのサービス (この場合は mydb サービス) を待機していることを示します。

  3. mydb サービスを作成します。

    1. 以下のような YAML ファイルを作成します。

      kind: Service
      apiVersion: v1
      metadata:
        name: mydb
      spec:
        ports:
        - protocol: TCP
          port: 80
          targetPort: 9377
    2. Pod を作成します。

      $ oc create -f mydb.yaml
    3. Pod のステータスを表示します。

      $ oc get pods

      出力例

      NAME                          READY     STATUS              RESTARTS   AGE
      myapp-pod                     1/1       Running             0          2m

      Pod のステータスは、サービスを待機しておらず、実行中であることを示していました。