一、理解init容器
Pod可以包含多個容器,應用運行在這些容器里,同時Pod也可以有一個或多個先於應用容器啟動的init容器。
init容器與普通的容器非常像,除了以下兩點:
-
它們總是運行到完成
-
如果Pod的init容器失敗,Kubernetes會不斷的重啟該Pod,直到init容器成功為止。然而,如果Pod對應的restartPolicy
值為Never,它不會重新啟動。
二、Init容器作用
因為init容器具有與應用容器分離的單獨鏡像,其啟動相關代碼具有如下優勢:
-
Init 容器可以包含一些安裝過程中應用容器中不存在的實用工具或個性化代碼。例如,沒有必要僅為了在安裝過程中使用類似
sed
、awk
、python
或dig
這樣的工具而去FROM
一個鏡像來生成一個新的鏡像。 -
Init 容器可以安全地運行這些工具,避免這些工具導致應用鏡像的安全性降低。
-
應用鏡像的創建者和部署者可以各自獨立工作,而沒有必要聯合構建一個單獨的應用鏡像。
-
Init 容器能以不同於Pod內應用容器的文件系統視圖運行。因此,Init容器可具有訪問
-
由於 Init 容器必須在應用容器啟動之前運行完成,因此 Init 容器提供了一種機制來阻塞或延遲應用容器的啟動,直到滿足了一組先決條件。一旦前置條件滿足,Pod內的所有的應用容器會並行啟動。
三、創建init容器
3.1 服務依賴的場景下初始化容器的使用方法
apiVersion: v1 kind: Pod metadata: name: init-pod1 labels: app: init spec: containers: - name: init-container image: busybox command: ['sh','-c','echo The app is running! & sleep 3600'] initContainers: - name: init-myservice image: busybox command: ['sh','-c','until nslookup myservice;do echo waiting for myservice;sleep 2;done;'] - name: init-mydb image: busybox command: ['sh','-c','until nslookup mydb;do echo waiting for mydb;sleep 2;done;']
查看狀態
# kubectl get pods NAME READY STATUS RESTARTS AGE init-pod1 0/1 Init:0/2 0 2m7s # kubectl describe pod init-pod Name: init-pod1 Namespace: default Priority: 0 Node: node1/192.168.10.107 Start Time: Thu, 11 Jun 2020 18:30:50 +0800 Labels: app=init Annotations: <none> Status: Pending IP: 10.38.0.6 IPs: IP: 10.38.0.6 Init Containers: init-myservice: Container ID: docker://11430cd7e93e25cd1f9c6180a2d3763a8bc8fbf98eca225e95af88e64888034e Image: busybox Image ID: docker-pullable://busybox@sha256:95cf004f559831017cdf4628aaf1bb30133677be8702a8c5f2994629f637a209 Port: <none> Host Port: <none> Command: sh -c until nslookup myservice;do echo waiting for myservice;sleep 2;done; State: Running Started: Thu, 11 Jun 2020 18:31:13 +0800 Ready: False Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-ft6g4 (ro) init-mydb: Container ID: Image: busybox Image ID: Port: <none> Host Port: <none> Command: sh -c until nslookup mydb;do echo waiting for mydb;sleep 2;done; State: Waiting Reason: PodInitializing Ready: False Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-ft6g4 (ro) Containers: init-container: Container ID: Image: busybox Image ID: Port: <none> Host Port: <none> Command: sh -c echo The app is running! & sleep 3600 State: Waiting Reason: PodInitializing Ready: False Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-ft6g4 (ro) Conditions: Type Status Initialized False Ready False ContainersReady False PodScheduled True Volumes: default-token-ft6g4: Type: Secret (a volume populated by a Secret) SecretName: default-token-ft6g4 Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m30s default-scheduler Successfully assigned default/init-pod1 to node1 Normal Pulling 2m29s kubelet, node1 Pulling image "busybox" Normal Pulled 2m7s kubelet, node1 Successfully pulled image "busybox" Normal Created 2m7s kubelet, node1 Created container init-myservice Normal Started 2m7s kubelet, node1 Started container init-myservice
因為現在myservice
還沒有創建,所以init-mydb
和main-container
都還處於PodInitializing
狀態,我們可以先創建下面的myservice
服務,然后觀察下init-mydb
和main-container
的狀態變化,然后在創建init-mydb
服務,觀察main-container
容器的狀態變化
Service
對應的YAML內容
kind: Service apiVersion: v1 metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 6376
創建Service和查看init容器狀態
# kubectl create -f init-service.yaml service/myservice created # kubectl get pods NAME READY STATUS RESTARTS AGE init-pod1 0/1 Init:1/2 0 10m
可以看到有一個init 容器已經起來了
再創建mydb服務
apiVersion: v1 kind: Service metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 6377
創建mydb服務
# kubectl create -f init-mydb.yaml service/mydb created # kubectl get pods NAME READY STATUS RESTARTS AGE init-pod1 1/1 Running 0 16m
我們在Pod
啟動過程中,初始化容器會按順序在網絡和數據卷初始化之后啟動。每個容器必須在下一個容器啟動之前成功退出。如果由於運行時或失敗退出,導致容器啟動失敗,它會根據Pod
的restartPolicy