Init容器
一、理解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