持续集成部署-k8s-高级调度-InitC:初始化容器的概念和使用

持续集成部署-k8s-高级调度-InitC:初始化容器的概念和使用

  • [1. Init Container(初始化容器)是什么?](#1. Init Container(初始化容器)是什么?)
  • [2. Init Container 的简单使用](#2. Init Container 的简单使用)

1. Init Container(初始化容器)是什么?

Kubernetes中,Init Container(初始化容器)是一种特殊类型的容器,它在Pod中的其他容器之前运行。Init Container用于在主容器启动之前执行一些初始化任务,例如配置文件的下载、数据库的初始化等。

Init Container与普通容器一样,但它们具有以下几个特点:

  • 顺序执行:在同一个Pod中,所有的Init Container会按照定义的顺序依次执行,只有当前Init Container成功退出(即返回状态码为0)后,下一个Init Container才会开始执行。
  • 容器间共享文件系统卷:Init Container可以与其他容器共享相同的卷(volume),使它们能够访问相同的文件或配置信息。
  • 生命周期独立:Init Container的生命周期与Pod中的其他容器是独立的。它们可以在主容器正在运行时继续执行,也可以在主容器结束后继续执行。

2. Init Container 的简单使用

新建配置文件:init-container.yaml

yml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: init-container-pod
spec:
  containers:
    - name: main-container-nginx
      image: nginx:1.7.9
      # 主容器的定义

  initContainers:
    - name: init-container-1
      image: busybox:latest
      command: ['sh', '-c', 'echo Init Container 1']
      # 第一个Init Container的定义

    - name: init-container-2
      image: busybox:latest
      command: ['sh', '-c', 'echo Init Container 2']
      # 第二个Init Container的定义

在上面的示例中,我们定义了一个Pod,其中包含一个名为 main-container-nginx的主容器和两个Init Container:init-container-1init-container-2。它们将按照定义的顺序依次执行。

每个Init Containerk可以使用不同的镜像(这里使用了Busybox镜像),并通过command字段指定了要执行的命令。在这个示例中,Init Container只是打印一些文本信息。

当Pod启动时,Kubernetes将首先创建并运行init-container-1,待其成功退出后,再创建并运行init-container-2。最后,Kubernetes会创建并运行main-container-nginx

接着我们操作下看下执行的流程:kubectl create -f init-container.yaml

bash 复制代码
[root@docker-54 jobs]# kubectl create -f init-container.yaml 
pod/init-container-pod created
[root@docker-54 jobs]# 
[root@docker-54 jobs]# kubectl get po
NAME                           READY   STATUS      RESTARTS        AGE
init-container-pod             0/1     Init:0/2    0               6s
[root@docker-54 jobs]# 
[root@docker-54 jobs]# kubectl get po
NAME                           READY   STATUS      RESTARTS        AGE
init-container-pod             0/1     Init:1/2    0               6s
[root@docker-54 jobs]# 
[root@docker-54 jobs]# kubectl get po
NAME                           READY   STATUS             RESTARTS        AGE
init-container-pod             0/1     PodInitializing    0               6s
[root@docker-54 jobs]# 
[root@docker-54 jobs]# kubectl get po
NAME                           READY   STATUS     RESTARTS        AGE
init-container-pod             1/1     Running    0               6s
[root@docker-54 jobs]# 

可以看到,Pod 创建成功后,READY显示 0/1表示未就绪状态,并且STATUS显示有两个 Init Container 在初始化,然后等待初始化完成后,容器状态变为 Running;

接着看下描述事件的内容:

bash 复制代码
[root@docker-54 jobs]# kubectl describe po  init-container-pod 
Name:         init-container-pod
Namespace:    default
...
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  87s   default-scheduler  Successfully assigned default/init-container-pod to docker-56
  Normal  Pulling    87s   kubelet            Pulling image "busybox:latest"
  Normal  Pulled     48s   kubelet            Successfully pulled image "busybox:latest" in 39.045941073s
  Normal  Created    48s   kubelet            Created container init-container-1
  Normal  Started    48s   kubelet            Started container init-container-1
  Normal  Pulling    47s   kubelet            Pulling image "busybox:latest"
  Normal  Pulled     16s   kubelet            Successfully pulled image "busybox:latest" in 31.46613887s
  Normal  Created    16s   kubelet            Created container init-container-2
  Normal  Started    16s   kubelet            Started container init-container-2
  Normal  Pulled     15s   kubelet            Container image "nginx:1.7.9" already present on machine
  Normal  Created    15s   kubelet            Created container main-container-nginx
  Normal  Started    14s   kubelet            Started container main-container-nginx
[root@docker-54 jobs]# 

可以看到,首先是任务调度到 docker-56 节点上,然后拉取了 "busybox:latest"的镜像,这里有两个 Init Container 但是用了同一个版本的镜像,却拉取了两次,就有点神奇了。

这是因为当Pod被调度到节点上并开始执行时,Kubernetes会按顺序为每个Init Container创建一个容器实例。每个容器实例需要从镜像仓库中拉取镜像,以便在节点上运行。

所以,在上面示例中,第一个Init Container(init-container-1)在开始时拉取了busybox:latest镜像,然后在成功退出后,第二个Init Container(init-container-2)也会拉取相同的镜像。这是因为每个Init Container都是独立的,它们之间没有共享镜像的缓存。

主容器(main-container-nginx)则是另一个独立的容器,它使用的是不同的镜像(nginx:1.7.9)。由于该镜像已经存在于节点上,所以在事件信息中显示为Container image "nginx:1.7.9" already present on machine,表示不需要再次拉取该镜像。

接着看下节点上容器的执行情况:

bash 复制代码
[root@docker-56 ~]# docker ps -a | grep init
8962da1d4913   84581e99d807                                                              "nginx -g 'daemon of..."   11 minutes ago   Up 11 minutes                         k8s_main-container-nginx_init-container-pod_default_c8984746-7c8e-4724-82da-4bb7376ec560_0
d29abaa670cd   busybox                                                                   "sh -c 'echo Init Co..."   11 minutes ago   Exited (0) 11 minutes ago             k8s_init-container-2_init-container-pod_default_c8984746-7c8e-4724-82da-4bb7376ec560_0
1cc8c7423c64   busybox                                                                   "sh -c 'echo Init Co..."   12 minutes ago   Exited (0) 12 minutes ago             k8s_init-container-1_init-container-pod_default_c8984746-7c8e-4724-82da-4bb7376ec560_0
[root@docker-56 ~]# docker logs -f --tail 20 k8s_init-container-1_init-container-pod_default_c8984746-7c8e-4724-82da-4bb7376ec560_0
Init Container 1
[root@docker-56 ~]# 

确实可以看到,这里运行了三个容器,Init Container 执行完成,已经是停止的状态了,并且查看对应 Init Container 的日志,也是可以正常看到的。

使用Init Container可以实现一些初始化任务,确保主容器在启动之前具备所需的条件。例如,可以使用Init Container下载配置文件初始化数据库执行数据迁移等操作。

需要注意的是,如果Init Container失败退出(即返回状态码非零),Kubernetes将会重启整个Pod,以便重新执行Init Container主容器。因此,在编写Init Container时,应确保其能够处理错误情况,并保证在正常情况下能够成功退出。

相关推荐
南猿北者4 分钟前
Docker Volume
运维·docker·容器
网络研究院2 小时前
Am I Isolated:一款安全态势基准测试工具
容器·工具·基准测试·安全态势
颜淡慕潇6 小时前
【K8S问题系列 | 9】如何监控集群CPU使用率并设置告警?
后端·云原生·容器·kubernetes·问题解决
运维&陈同学6 小时前
【模块一】kubernetes容器编排进阶实战之k8s基础概念
运维·docker·云原生·容器·kubernetes·云计算
信子姚青6 小时前
K8s使用nfs
容器
葡萄皮Apple6 小时前
[CKS] K8S RuntimeClass SetUp
java·容器·kubernetes
mit6.8247 小时前
[Docker#4] 镜像仓库 | 部分常用命令
linux·运维·docker·容器·架构
诡异森林。9 小时前
Docker--Docker是什么和对Docker的了解
运维·docker·容器
老大白菜9 小时前
goframe开发一个企业网站 验证码17
运维·docker·容器·golang·goframe
zhangxueyi12 小时前
OpenEuler 下 Docker 安装、配置与测试实例
运维·docker·容器