Init容器

一、理解init容器

Pod可以包含多个容器,应用运行在这些容器里,同时Pod也可以有一个或多个先于应用容器启动的init容器。

init容器与普通的容器非常像,除了以下两点:

  • 它们总是运行到完成

  • 每个都必须在下一个 启动之前成功完成

如果Pod的init容器失败,Kubernetes会不断的重启该Pod,直到init容器成功为止。然而,如果Pod对应的restartPolicy 值为Never,它不会重新启动。

二、Init容器作用

因为init容器具有与应用容器分离的单独镜像,其启动相关代码具有如下优势:

  • Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。例如,没有必要仅为了在安装过程中使用类似 sedawkpythondig 这样的工具而去FROM 一个镜像来生成一个新的镜像。

  • Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。

  • 应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。

  • Init 容器能以不同于Pod内应用容器的文件系统视图运行。因此,Init容器可具有访问 Secrets 的权限,而应用容器不能够访问。

  • 由于 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-mydbmain-container都还处于PodInitializing状态,我们可以先创建下面的myservice服务,然后观察下init-mydbmain-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启动过程中,初始化容器会按顺序在网络和数据卷初始化之后启动。每个容器必须在下一个容器启动之前成功退出。如果由于运行时或失败退出,导致容器启动失败,它会根据PodrestartPolicy指定的策略进行重试。 然而,如果 Pod 的 restartPolicy 设置为 Always,Init 容器失败时会使用 RestartPolicy 策略。

posted @ 2020-08-14 09:14  Bigberg  阅读(1097)  评论(0编辑  收藏  举报