Init Container(初始化容器)

在很多应用场景中,应用在启动之前都需要进行如下初始化操作:

  • 等待其他关联组件正确运行(例如数据库或某个后台服务)
  • 基于环境变量或配置模板生成配置文件。
  • 从远程数据库获取本地所需配置,或者将自身注册到某个中央数据库中。
  • 下载相关依赖包,或者对系统进行一些预配置操作。

Kubernetes 1.3引入了一个Alpha版本的新特性init container(初始化容器),用于在启动应用容器(app container)之前启动一个或多个初始化容器,完成应用容器所需的预置条件,如图所示。

在这里插入图片描述
init container与应用容器在本质上是一样的,但它们是仅运行一次就结束的任务,并且必须在成功执行完成后,系统才能继续执行下一个容器。

根据Pod的重启策略(RestartPolicy),当init container执行失败,而且设置了RestartPolicy=Never时,Pod将会启动失败;而设置RestartPolicy=Always时,Pod将会被系统自动重启。

下面以Nginx应用为例,在启动Nginx之前,通过初始化容器busybox为Nginx创建一个index.html主页文件。
这里为init container和Nginx设置了一个共享的Volume,以供Nginx访问init container设置的index.html文件:

vim nginx-init-containers.yaml

apiVersion: v1
kind: Pod
metadata: 
  name: nginx
  annotations:
spec:
  initContainers: #这个是重点
  - name: install
    image: busybox
    command: ["wget","-O","/work-dir/index.html","http://kubernetes.io"]
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: workdir
      mountPath: /usr/share/nginx/html
  dnsPolicy: Default
  volumes:
  - name: workdir
    emptyDir: {}

创建这个Pod:

[root@bogon ~]# kubectl create -f nginx-init-containers.yaml 
pod/nginx created

在运行init container的过程中查看Pod的状态,可见init过程还未完成:

[root@bogon ~]# kubectl get pods
NAME                     READY   STATUS     RESTARTS   AGE
nginx                    0/1     Init:0/1   0          10s

[root@bogon ~]# kubectl get pods
NAME                     READY   STATUS            RESTARTS   AGE
nginx                    0/1     PodInitializing   0          62s

在init container成功执行完成后,系统继续启动Nginx容器,再次查看Pod的状态:

[root@bogon ~]# kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
nginx                    1/1     Running   0          70s

查看Pod的事件,可以看到系统首先创建并运行init container容器(名为install),成功后继续创建和运行Nginx容器:

kubectl describe pod nginx

Events:
  Type    Reason     Age        From               Message
  ----    ------     ----       ----               -------
  Normal  Scheduled  <unknown>  default-scheduler  Successfully assigned default/nginx to kafka03
  Normal  Pulling    5m30s      kubelet, kafka03   Pulling image "busybox"
  Normal  Pulled     5m14s      kubelet, kafka03   Successfully pulled image "busybox"
  Normal  Created    5m14s      kubelet, kafka03   Created container install
  Normal  Started    5m14s      kubelet, kafka03   Started container install
  Normal  Pulling    4m44s      kubelet, kafka03   Pulling image "nginx"
  Normal  Pulled     4m30s      kubelet, kafka03   Successfully pulled image "nginx"
  Normal  Created    4m30s      kubelet, kafka03   Created container nginx
  Normal  Started    4m29s      kubelet, kafka03   Started container nginx

启动成功后,登录进Nginx容器,可以看到/usr/share/nginx/html目录下的index.html文件为init container所生成,内容查看:

[root@kafka03 ~]# docker exec -it 16f055f90d3a /bin/bash
root@nginx:/# cat  /usr/share/nginx/html/index.html 

init container与应用容器的区别如下:

扫描二维码关注公众号,回复: 11513641 查看本文章
  1. init container的运行方式与应用容器不同,它们必须先于应用容器执行完成。
    当设置了多个init container时,将按顺序逐个运行,并且只有前一个init container运行成功后才能运行后一个init container。
    当所有init container都成功运行后,Kubernetes才会初始化Pod的各种信息,并开始创建和运行应用容器。

  2. 在init container的定义中也可以设置资源限制、Volume的使用和安全策略,等等。但资源限制的设置与应用容器略有不同:
    a:如果多个init container都定义了资源请求/资源限制,则取最大的值作为所有init container的资源请求值/资源限制值。
    b: Pod的有效(effective)资源请求值/资源限制值取以下二者中的较大值。
    b1: 所有应用容器的资源请求值/资源限制值之和。
    b2: init container的有效资源请求值/资源限制值。
    c: 调度算法将基于Pod的有效资源请求值/资源限制值进行计算,也就是说init container可以为初始化操作预留系统资源,即使后续应用容器无须使用这些资源。
    d: Pod的有效QoS等级适用于init container和应用容器。
    e: 资源配额和限制将根据Pod的有效资源请求值/资源限制值计算生效。
    f: Pod级别的cgroup将基于Pod的有效资源请求/限制,与调度机制一致。

  3. init container不能设置readinessProbe探针,因为必须在它们成功运行后才能继续运行在Pod中定义的普通容器。
    在Pod重新启动时,init container将会重新运行,常见的Pod重启场景如下:
    a: init container的镜像被更新时,init container将会重新运行,导致Pod重启。仅更新应用容器的镜像只会使得应用容器被重启。
    b: Pod的infrastructure容器更新时,Pod将会重启。
    c: 若Pod中的所有应用容器都终止了,并且RestartPolicy=Always,则Pod会重启。

猜你喜欢

转载自blog.csdn.net/zhangshaohuas/article/details/107435394