Kubernetes Init Container (初始化容器)

Init容器与普通容器的不同之处是支持应用容器的全部字段和特性,包括资源限制、数据卷和安全设置。然后,Init容器对资源请求和容器处理不同,并且它们必须在Pod就绪之前完成运行
Kubernetes Init Container (初始化容器)
Kubernetes

一、初始化容器应用场景

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

  • 可以包含并运行实用工具,出于安全考虑,是不建议在应用容器镜像中包含
  • 定制化代码和安装工具(例如需要使用sed、awk、Python、或dig)
  • 从远处数据库获取本地所需配置,或者例如将服务注册到服务中心/配置中心等
  • Init容器与普通容器的不同之处是支持应用容器的全部字段和特性,包括资源限制、数据卷和安全设置。然后,Init容器对资源请求和容器处理不同,并且它们必须在Pod就绪之前完成运行
    理解Init容器
    Pod 能够具有多个容器,应用运行在容器里面,但是它也可能有一个或多个领先于应用容器启动的Init容器
    Init容器与普通容器非常像,除了以下两点:

  • Init容器总是运行到完成 (例如执行wget、curl、ping等命令)
  • 如果有多个Init容器的情况下都必须要在下一个启动之前结束运行
  • 如果Pod中的Init容器启动失败,Kubernetes会不断重启该Pod,直到Init容器成功为止,如果Pod对应的restartPolicy值为Never(只要退出就不再重启),则它不会重新启动。

    二、初始化容器介绍

    在Kubernetes v1.3引用了Alpha版本的新特性init container(在Kubernetes v1.5时被更新为Beta版本),用于在启动应用容器之前启动一个或多个初始化容器,完成应用程序所需的预置条件。Init container与应用容器本质上是一样的,但它们是仅运行一次就结束的任务,并且必须在执行完成后,系统才能继续执行下一个容器。
    image_1dpo11oc6eav9n4p1e1s74evk9.png-26kB

    三、项目演示

    本次演示使用busybox镜像作为init镜像,应用程序使用nginx进行演示,通过挂载的方式将init镜像获取到文件挂载到nginx html目录,这样我们访问的nginx 默认index.html就是我们init提前拉取出来的地址

    cat >>init.yaml <<EOF
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: init-demo
      labels:
        app: init
    spec:
      initContainers:
        - name: init
          image: busybox
          command:
          - wget
          - "-O"
          - "/tmp/index.html"
          - http://k.i4t.com
          volumeMounts:
            - name: initdir
              mountPath: "/tmp"
    
      containers:
        - name: nginx
          image: nginx
          ports:
          - containerPort: 80
          volumeMounts:
            - name: initdir
              mountPath: /usr/share/nginx/html
      volumes:
        - name: initdir
          emptyDir: {}
    EOF
    

    使用命令直接创建即可,init也可以使用命名空间,我这里就使用默认的default进行演示

    #创建
    [root@abcdocker yaml]# kubectl apply -f init.yaml
    pod/init-demo created
    
    #此时init容器进行启动工作
    [root@abcdocker yaml]# kubectl get pod
    NAME        READY   STATUS     RESTARTS   AGE
    init-demo   0/1     Init:0/1   0          5s
    
    #当init容器完成后,应用容器启动并进行工作
    [root@abcdocker yaml]# kubectl get pod
    NAME        READY   STATUS    RESTARTS   AGE
    init-demo   1/1     Running   0          21s
    

    当我们Pod正常Running之后,我们可以通过kubectl describe pod [pod-name]查看到init容器的一个状态
    如果失败init容器默认会在State中显示CrashLoopBackOff (重启/异常),在Reason会显示Error
    State 代表状态
    Reason 原因
    Terminated 终止
    Completed 完成
    Kubernetes Init Container (初始化容器)-每日运维
    接下来我们进行验证挂在Pod正常

    #可以先通过curl一下 pod的IP:80,检查服务是否正常和挂载是否正常
    [root@abcdocker ~]# kubectl get pod -o wide
    NAME        READY   STATUS    RESTARTS   AGE   IP             NODE           NOMINATED NODE   READINESS GATES
    init-demo   1/1     Running   0          18m   172.30.144.2   k8s-master03              
    
    [root@abcdocker ~]# curl -s 172.30.144.2|head
    

    我们还可以进入容器进行查看

    [root@abcdocker ~]# kubectl get pod
    NAME        READY   STATUS    RESTARTS   AGE
    init-demo   1/1     Running   0          19m
    
    [root@abcdocker ~]# kubectl exec -it init-demo /bin/bash
    root@init-demo:/# cat /usr/share/nginx/html/index.html
    

    官方文档还给出了使用其他命令的方式

    apiVersion: v1
    kind: Pod
    metadata:
      name: myapp-pod
      labels:
        app: 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; do echo waiting for myservice; sleep 2; done;']
      - name: init-mydb
        image: busybox:1.28
        command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
    

    本文参考官方文档:https://kubernetes.io/docs/concepts/workloads/pods/init-containers

    相关文章:

    1. 深入解析Kubernetes service 概念
    2. Kubernetes 1.14 二进制集群安装
    3. Kuerbernetes 1.11 集群二进制安装
    4. 基于Kubernetes Gitlab CICD