Pod には、アプリケーションが実行される複数のコンテナを含めることができ、また、アプリケーション コンテナの前に起動される 1 つ以上の Init コンテナを含めることもできます。 InitコンテナとはInit Container は特別なコンテナです。名前の通り、初期化作業に使われるコンテナです。 Init Container は 1 つ以上存在できます。複数の Init Container がある場合、これらのコンテナは定義された順序で実行されます。すべての Init Container が実行された後にのみ、メイン コンテナが起動されます。 Pod 内のすべてのコンテナはデータ ボリュームとネットワーク名前空間を共有するため、Init コンテナで生成されたデータはメイン コンテナで使用できます。 Init コンテナは、次の 2 つの点を除いて、基本的にアプリケーション コンテナと同じです。 - Init Container は、lifecycle、livenessProbe、readinessProbe、startupProbe をサポートしていません。これらは、Pod の準備ができる前に完了するまで実行する必要があるため、一度だけ実行されて終了するタスクです。
- システムは、実行が正常に完了した後にのみ、次のコンテナの実行を続行できます。
Pod の Init コンテナが失敗した場合、Kubernetes は Init コンテナが成功するまで Pod を再起動し続けます。 Pod に対応する restartPolicy が Never の場合、Pod は再起動されません。 ポッドのライフサイクル: 上の図から、Init コンテナはメイン コンテナから独立していますが、両方とも Pod ライフサイクルに属していることが直感的にわかります。 アプリケーションシナリオ- 他の依存サービス(データベースやバックグラウンドサービスなど)が正しく実行されるのを待機しています
- 環境変数または構成テンプレートに基づいて、サービスに必要な構成ファイルを生成します。
- 必要なローカル構成をリモートデータベースから取得するか、中央データベースに登録します。
- 関連する依存パッケージをダウンロードするか、システム上でいくつかの事前構成操作を実行します。
簡単な例アプリケーション コンテナーは Pod.Spec.Containers で定義され、必須フィールドです。一方、init は Pod.Spec.initContainers で定義され、オプション フィールドです。 次の例では、2 つの Init コンテナを持つ単純な Pod を定義します。最初のものは myservice の起動を待機し、2 番目のものは mydb の起動を待機します。両方の Init コンテナが起動すると、Pod は仕様セクションでアプリケーション コンテナを起動します。 myapp.yaml: apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app.kubernetes.io/name: MyApp spec: containers: - name: myapp-container image: busybox:1.28 command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: busybox:1.28 command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"] - name: init-mydb image: busybox:1.28 command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"] 作成する: [root@localhost ~]# kubectl apply -f myapp.yaml pod/myapp-pod created ステータスを確認します: [root@localhost ~]# kubectl get -f myapp.yaml NAME READY STATUS RESTARTS AGE myapp-pod 0/1 Init:0/2 0 8s 出力の詳細: [root@localhost ~]# kubectl describe -f myapp.yaml Name: myapp-pod Namespace: default [...] Labels: app.kubernetes.io/name=MyApp Annotations: <none> Status: Pending [...] Init Containers: init-myservice: [...] State: Running [...] init-mydb: [...] State: Waiting Reason: PodInitializing Ready: False [...] Containers: myapp-container: [...] State: Waiting Reason: PodInitializing Ready: False [...] Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 20s default-scheduler Successfully assigned default/myapp-pod to localhost.localdomain Normal Pulling 17s kubelet Pulling image "busybox:1.28" Normal Pulled 8s kubelet Successfully pulled image "busybox:1.28" in 9.30472043s Normal Created 7s kubelet Created container init-myservice Normal Started 6s kubelet Started container init-myservice Pod 内の Init コンテナのログを表示します。 [root@localhost ~]# kubectl logs myapp-pod -c init-myservice # 查看第一个Init 容器nslookup: can't resolve 'myservice.default.svc.cluster.local' Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local waiting for myservice [root@localhost ~]# kubectl logs myapp-pod -c init-mydb # 查看第二个Init 容器Error from server (BadRequest): container "init-mydb" in pod "myapp-pod" is waiting to start: PodInitializing この時点で、init-mydb コンテナは、init-myservice が完了するまで待機してから実行されます。これらのサービスを作成するための構成ファイル services.yaml は次のとおりです。 --- apiVersion: v1 kind: Service metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 9376 --- apiVersion: v1 kind: Service metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 9377 作成する: [root@localhost ~]# kubectl apply -f services.yaml service/myservice created service/mydb created ステータスを再度確認します。実行中になります。 [root@localhost ~]# kubectl get pod NAME READY STATUS RESTARTS AGE myapp-pod 1/1 Running 0 2m35s 詳細をもう一度確認すると、init-myservice と init-mydb の両方が終了していることがわかります。 Init Containers: init-myservice: [...] State: Terminated Reason: Completed Exit Code: 0 [...] init-mydb: [...] State: Terminated Reason: Completed Exit Code: 0 新しいサイドカー機能Kubernetes 1.28 のリリースでは、多くの重要な機能がサポートされていますが、その中で最も印象的なのは、現在アルファ バージョンである新しい Sidecar です。以前は、サイドカーという用語は、K8s の通常のコンテナと何ら変わらない、単なるマルチコンテナ設計パターンでした。しかし、そのライフサイクルはビジネス コンテナのライフサイクルと一致していないため、Sidecar のライフサイクル管理は常に問題となっていました。 Sidecar の新しいバージョンは initContainers に配置されます。 restartPolicy を Always に指定すると、Sidecar が有効になります。ライフサイクルや再起動管理は通常のコンテナと同様です。この機能はジョブの実行にも使用できます。 以下は、Sidecar を使用したデプロイメントの例です。ログサイドカーコンテナはターミナルにログを出力するために使用され、メインコンテナはログの書き込みをシミュレートします: sidecar.yaml: apiVersion: apps/v1 kind: Deployment metadata: name: myapp labels: app: myapp spec: replicas: 1 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: alpine:latest command: ['sh', '-c', 'while true; do echo "logging" >> /opt/logs.txt; sleep 1; done'] volumeMounts: - name: data mountPath: /opt initContainers: - name: logshipper # sidecar 容器image: alpine:latest restartPolicy: Always # 必须指定restartPolicy为Always才能开启sidecar command: ['sh', '-c', 'tail -f /opt/logs.txt'] volumeMounts: - name: data mountPath: /opt volumes: - name: data emptyDir: {} K8s クラスターにデプロイすると、initContainers[*].restartPolicy フィールドが表示されます。 [root@localhost ~]# kubectl create -f sidecar.yaml deployment.apps/myapp created [root@localhost ~]# kubectl get po -l app=myapp -ojsonpath='{.items[0].spec.initContainers[0].restartPolicy}' Always [root@localhost ~]# kubectl get po -l app=myapp NAME READY STATUS RESTARTS AGE myapp-215h3248d-p4z6 2/2 Running 0 1m5s myapp Pod 内の両方のコンテナが準備完了です (2/2)。ログを確認すると、ログサイドカーが常にログを出力していることがわかります。 [root@localhost ~]# kubectl logs -l app=myapp -c logshipper -f logging logging |