コンテナを初期化する
Init Container は、初期化に使用されるコンテナです。1 つ以上にすることができます。複数ある場合、これらのコンテナは定義された順序で実行されます。すべての Init Container が実行された後にのみ、メイン コンテナが起動されます。ポッド内のすべてのコンテナはデータ ボリュームとネットワーク名前空間を共有するため、Init コンテナで生成されたデータをメイン コンテナで使用できます。
Init Container は前のフック関数に似ていますが、コンテナが実行される前にいくつかの作業を行います。直観的な観点から見ると、初期化コンテナは確かに PreStart に少し似ていますが、フック関数と InitContainer は異なる段階にあります。次の図から理解できます。
上の図から、Liveness と Readiness を含む PostStart と PreStop はメイン コンテナのライフ サイクルに属し、Init コンテナはメイン コンテナから独立していることが直感的にわかります。もちろん、これらはすべて Pod のライフ サイクルに属しています。
さらに、上記のポッドの右側にインフラ コンテナがあることがわかります。クラスター環境内の任意のポッドに対応する実行中の Docker コンテナを確認できます。各ポッドにポーズ amd64 イメージが含まれていることがわかります。これがインフラ イメージです。ポッド下のすべてのコンテナが同じネットワーク名前空間を共有していることがわかります。
很多 Pod 启动不起来就是因为这个 infra 镜像没有被拉下来,所以需要提前拉取到节点上面。
初期コンテナと通常のコンテナの違いは次のとおりです。
- Init コンテナは成功するまで常に実行されます。
- 次の Init コンテナを開始するには、各 Init コンテナが正常に完了する必要があります。
ポッドの Init コンテナが失敗した場合、Kubenetes は Init コンテナが成功するまで継続的にポッドを再起動します。ただし、Pod の対応する restartPolicy が Never の場合、再起動されません。
Init コンテナの利点:
- ユーティリティを含めて実行できます。セキュリティ上の理由から、これらのユーティリティをアプリケーション コンテナー イメージに含めることはお勧めできません。
- これらには、インストールするツールやカスタム コードを含めることができますが、アプリケーション コンテナー イメージには表示できません。たとえば、ミラーを作成するために別のイメージを FROM する必要はなく、インストール プロセス中に sed、awk、python、または dig などのツールを使用するだけです。
- アプリケーション コンテナー イメージは、作成とデプロイメントの役割を分離することができ、必ずしもこれらを組み合わせて単一のイメージを構築する必要はありません。
- Init コンテナは LinuxNamespace を使用するため、アプリケーション コンテナとは異なるファイル システムのビューを持ちます。したがって、Init コンテナーは Secret アクセス許可を持つことができますが、アプリケーション コンテナーは持つことができません。
- これらはアプリケーション コンテナが開始する前に完了するまで実行する必要があり、アプリケーション コンテナは並行して実行されるため、Init コンテナは、前提条件が満たされるまでアプリケーション コンテナの開始をブロックまたは遅延する簡単な方法を提供します。
コンテナー アプリケーションの初期化シナリオ:
- 他のモジュールの準備が整うまで待機: サービス間の依存関係の問題を解決するために使用できます。たとえば、別のデータベース サービスに依存する Web サービスがありますが、この Web サービスを開始するときに、依存するデータベース サービスが開始されていることを保証できないため、Web サービスが一定期間内にデータベースに接続するときに例外が発生する可能性があります。この問題を解決するには、Web サービスのポッドで nitContainer を使用して、初期化コンテナーでデータベースの準備ができているかどうかを確認できます。初期化コンテナーの準備が完了すると、初期化コンテナーが終了し、メイン コンテナー Web サービスが開始されます。この時点では、データベースへの接続に問題はありません。
- 初期構成を実行します。たとえば、クラスター内のすべての既存のメンバー ノードを検出し、メイン コンテナーのクラスター構成情報を準備します。これにより、メイン コンテナーは起動後にこの構成情報を使用してクラスターに参加できるようになります。
- その他のシナリオ: 中央データベース、構成センターなどへのポッドの登録など。
例
apiVersion: v1
kind: Pod
metadata:
name: init-demo
labels:
demo: init-demo
spec:
containers:
- name: init-demo
image: busybox
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-demo1
image: busybox
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice;sleep 2; done;']
- name: init-demo2
image: busybox
command: ['sh', '-c', 'until nslookup mysql; do echo waiting for mysql; sleep 2;done;']
---
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- port: 1234
targetPort: 4567
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 4321
targetPort: 7654
protocol: TCP
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
init-demo 0/1 Init:0/2 0 6s
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
init-demo 1/1 Running 0 4m24s
[root@master ~]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13d
myservice ClusterIP 10.108.202.229 <none> 1234/TCP 4m40s
mysql ClusterIP 10.110.222.227 <none> 4321/TCP 4m39s
[root@master ~]# kubectl logs init-demo
the app is running1
容器の特記事項
- ポッドの起動中、ネットワークとデータ ボリュームの初期化後に Init コンテナが順番に起動されます。次のコンテナを開始するには、各コンテナが正常に終了する必要があります。
- 実行時または終了失敗によりコンテナが起動に失敗した場合、PodrestartPolicy で指定されたポリシーに従って再試行されます。ただし、ポッドの restartPolicy が Always に設定されている場合、Init コンテナが失敗したときに RestartPolicy ポリシーが使用されます。
- すべての Init コンテナが失敗するまで、Pod は Ready になりません。Init コンテナのポートは Service に集約されません。初期化中のポッドは保留状態ですが、初期化状態を true に設定する必要があります
- ポッドが再起動すると、すべての Init コンテナを再実行する必要があります
- Init コンテナ仕様への変更はコンテナ イメージ フィールドに限定されており、他のフィールドへの変更は有効になりません。Init コンテナの Image フィールドを変更することは、Pod を再起動することと同じです。
- Init コンテナにはアプリケーション コンテナのすべてのフィールドが含まれます。readinessProbe に加えて、Init コンテナーでは readiness 以外の完了以外の状態を定義できないためです。これは検証中に強制されます。
- ポッド内の各アプリと初期コンテナ名は一意である必要があります。同じ名前を他のコンテナと共有すると、検証中にエラーがスローされます。