Kubernetes的初始化容器initContainers
initContainers是一种专用的容器,在应用程序容器启动之前运行,可以包括一些应用程序镜像中不存在的实用工具和安装脚本,可以完成应用的必要数据初始化等工作。总的来说就是在正式的容器启动之前做一些准备工作的。
例如一个应用容器挂载的volume目录需要一些必不可少的初始化文件,不加init容器的时候直接挂载volume应用容器的那个目录是空的(因为docker挂载一个volume时,会用volume的内容覆盖容器内挂载目录的内容),这就需要让init容器也跟应用容器挂载同一个volume目录,将初始化文件放进去,然后在启动应用容器就能正常看到那些初始化文件了,我也正是遇到了这样的问题,才来研究和学习init容器的。
1、一个pod可以运行多个容器,同样的一个pod也可能有一个或多个先于应用容器启动的 Init 容器,每个容器启动失败后都会根据你配置的重启策略进行重启,直到运行成功。Init 容器与普通的基本一样,主要区别如下
- Init 容器总是运行到成功运行完为止。
- 前面的 Init 容器必须已经运行完成,才会开始运行下一个init容器,而应用程序容器时并行运行的。2、
2、因为 Init 容器具有与应用程序容器分离的单独镜像,所以使用他们可以具有如下优势:
- 它们可以包含并运行实用工具,但是出于安全考虑,是不建议在应用程序容器镜像中包含这些实用工具的。
- 它们可以包含使用工具和定制化代码来安装,但是不能出现在应用程序镜像中。例如,创建镜像没必要 FROM 另一个镜像,只需要在安装过程中使用类似 sed、 awk、 python 或 dig 这样的工具。
- 应用程序镜像可以分离出创建和部署的角色,而没有必要联合它们构建一个单独的镜像。
- Init 容器使用 Linux Namespace,所以相对应用程序容器来说具有不同的文件系统视图。因此,它们能够具有访问 Secret 的权限,而应用程序容器则不能。
- 它们必须在应用程序容器启动之前运行完成,而应用程序容器是并行运行的,所以 Init 容器能够提供了一种简单的阻塞或延迟应用容器的启动的方法,直到满足了一组先决条件。
3、下面是一些如何使用 Init 容器的思路:
- 等待一个 Service 创建完成,通过类似如下 shell 命令:
for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; exit 1
- 将 Pod 注册到远程服务器,通过在命令中调用 API,类似如下:
curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$(<POD_NAME>)&ip=$(<POD_IP>)'
- 在启动应用容器之前等一段时间,使用类似 sleep 60 的命令。
- 克隆 Git 仓库到数据卷。
- 将配置值放到配置文件中,运行模板工具为主应用容器动态地生成配置文件。例如,在配置文件中存放 POD_IP 值,并使用 Jinja 生成主应用配置文件。
4、 init容器使用示例,
Kubernetes 1.6 版本后使用新语法,把 Init 容器的声明移到 spec 中,只需要添加 initContainers 即可,下面列一个具有 2 个 Init 容器的简单 Pod。 第一个等待 myservice 启动,第二个等待 mydb 启动。 一旦这两个 Service 都启动完成,Pod 将开始启动。
apiVersion: v1 kind: Pod metadata:name: myapp-podlabels:app: myapp spec:containers:- name: myapp-containerimage: busyboxcommand: ['sh', '-c', 'echo The app is running! && sleep 3600']initContainers:- name: init-myserviceimage: busyboxcommand: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']- name: init-mydbimage: busyboxcommand: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
下面的 yaml 文件展示了 mydb 和 myservice 两个 Service:
kind: Service apiVersion: v1 metadata:name: myservice spec:ports:- protocol: TCPport: 80targetPort: 9376 --- kind: Service apiVersion: v1 metadata:name: mydb spec:ports:- protocol: TCPport: 80targetPort: 9377
这个 Pod 可以使用下面的命令进行启动和调试
$ kubectl create -f myapp.yaml pod "myapp-pod" created $ kubectl get -f myapp.yaml NAME READY STATUS RESTARTS AGE myapp-pod 0/1 Init:0/2 0 6m $ kubectl describe -f myapp.yaml Name: myapp-pod Namespace: default [...] Labels: app=myapp Status: Pending [...] Init Containers:init-myservice: [...]State: Running [...]init-mydb: [...]State: WaitingReason: PodInitializingReady: False [...] Containers:myapp-container: [...]State: WaitingReason: PodInitializingReady: False [...] Events:FirstSeen LastSeen Count From SubObjectPath Type Reason Message--------- -------- ----- ---- ------------- -------- ------ -------16s 16s 1 {default-scheduler } Normal Scheduled Successfully assigned myapp-pod to 172.17.4.20116s 16s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulling pulling image "busybox"13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulled Successfully pulled image "busybox"13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Created Created container with docker id 5ced34a04634; Security:[seccomp=unconfined]13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Started Started container with docker id 5ced34a04634 $ kubectl logs myapp-pod -c init-myservice # Inspect the first init container $ kubectl logs myapp-pod -c init-mydb # Inspect the second init container
一旦我们启动了 mydb 和 myservice 这两个 Service,我们能够看到 Init 容器完成,并且 myapp-pod 被创建:
$ kubectl create -f services.yaml service "myservice" created service "mydb" created $ kubectl get -f myapp.yaml NAME READY STATUS RESTARTS AGE myapp-pod 1/1 Running 0 9m
在 Pod 上使用 activeDeadlineSeconds,在容器上使用 livenessProbe,这样能够避免 Init 容器一直失败, 这就为 Init 容器活跃设置了一个期限。在 Pod 中的每个 app 和 Init 容器的名称必须唯一,与任何其它容器共享同一个名称,会在验证时抛出错误。
在 Pod 启动过程中,Init 容器会按顺序在网络和数据卷初始化之后启动。 每个容器必须在下一个容器启动之前成功退出。 如果由于运行时或失败退出,导致容器启动失败,它会根据 Pod 的 restartPolicy 指定的策略进行重试,在所有的 Init 容器没有成功之前,Pod 将不会变成 Ready 状态,如果 Pod 重启,所有 Init 容器必须重新执行。
因为 Init 容器可能会被重启、重试或者重新执行,所以 Init 容器的代码应该是幂等的(即任意多次执行所产生的影响与一次执行的影响相同)。 特别地,被写到 EmptyDirs 中文件的代码,应该对输出文件可能已经存在做好准备。
5、Pod 能够重启,会导致 Init 容器重新执行,重启主要有如下几个原因:
- 用户更新 PodSpec 导致 Init 容器镜像发生改变。更改 Init 容器的 image 字段,等价于重启该 Pod,应用容器镜像的变更只会重启应用容器。
- Pod 基础设施容器被重启。这不多见,但某些具有 root 权限可访问 Node 的人可能会这样做。
- 当 restartPolicy 设置为 Always,Pod 中所有容器会终止,强制重启,由于垃圾收集导致 Init 容器完成的记录丢失。
- 因为 Init 容器具有与应用程序容器分离的单独镜像,所以使用他们可以具有如下优势:
转载于:https://www.cnblogs.com/yanh0606/p/11395920.html
Kubernetes的初始化容器initContainers相关推荐
- kubernetes之初始化容器
参考:https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ 初始化容器是什么? 在kubernetes中,一个pod可 ...
- Kubernetes 初始化容器顺序启动
最近工作中需要保证容器启动之前PostgreSQL先启动,然后Apollo再启动,不然会出现配置加载错误的问题.Kubernetes的初始化容器就能够满足这种场景. InitContainers能够按 ...
- Kubernetes(k8s)四、Pod生命周期(初始化容器的应用,探针liveness、readliness应用,)
Pod生命周期 学习目标:初始化容器的应用及两个探针的应用 探针 是由 kubelet 对容器执行的定期诊断: Kubelet 可以选择是否执行在容器上运行的三种探针执行和做出反应: liveness ...
- CC00204.CloudKubernetes——|KuberNetes高级调度.V07|——|初始化容器|InitContainer操作|
一.InitContainer概述 ### --- InitContainer概述~~~ # InitContainer: ~~~ 初始化容器:预处理.预判断.与执行命令操作:在我应用容器启动之前做的 ...
- k8s 重启策略、健康检查、环境变量、初始化容器
深入理解Pod对象:基本管理 Pod基本概念 Pod存在意义 Pod资源共享实现机制 Pod管理命令 重启策略 健康检查 环境变量 init Container(初始化容器) 先简单的做出两个运行ht ...
- k8s pod生命周期、初始化容器、钩子函数、容器探测、重启策略
pod结构 Pause容器 Pause容器是每个Pod都会有的一个根容器,它的作用有两个 可以以它为根据,评估整个pod的健康状态 可以在根容器上设置IP地址,其他容器都以此IP(Pod IP),以实 ...
- 5. Kubernetes 进阶之容器组(Pod)
Pod详解 Pod介绍 术语中英文对照: 英文全称 英文缩写 中文翻译 Pod Pod 容器组 Container Container 容器 Controller Controller 控制器 什么是 ...
- C++列表初始化容器
initializer_list是一个模板类,可能你已经用过它了但不知道而已,比如下面的代码就用了 #include <iostream> #include <vector>i ...
- spring读取配置文件初始化容器操作总结
Spring初始化容器.三种经常用到的实现: 一.ClassPathXmlApplicationContext:从类路径中加载. 二.FileSystemXmlApplicationContext:从 ...
最新文章
- R假设检验之Durbin-Watson检验(Durbin-Watson Test)
- indesign排版标点挤压_我於\LaTeX 中文直排实践中所感受的排版需求
- leetcode 299. Bulls and Cows | 299. 猜数字游戏(Java)
- opencv 创建图像_非艺术家的图像创建(OpenCV项目演练)
- ubuntu grep搜索文本
- 数据中台建设五步法(文末赠书)
- F5实现2台机器的热备 Priority Group Activation
- shell中 if else以及大于、小于、等于逻辑表达式介绍
- 常见的数据分析模型有哪些
- 访问类路径下资源的两种方式
- iPhone中国移动收不到彩信,设置方法?
- C#命名规范(参考) (II)
- 卡内基梅隆大学计算机系难考,考出托福成绩 成功申请卡内基梅隆大学计算机科学专业...
- CDH6.3.3 paywall版之前自定义http服务器放置parcels安装数据
- 【C++学习笔记】函数基础和参数传递
- 【亲测】原神3.2+文本教程+视频教程+GM工具
- MySQL通过分组计算百分比
- 【基础】一叶知秋,从背包问题到动态规划
- 一种改进的教与学优化算法
- Codeforces 1110D Jongmah dp
热门文章
- 计算机组成原理—— 寻址方式
- 快速上手RaphaelJS--RaphaelJS_Starter翻译(三)
- c#-检查USB硬件变化
- IntelliJ IDEA绑定Github报Error 403: Not Authorized没有授权问题解决方法
- Chrome浏览器不支持字体小于12px的解决办法
- CTFshow 文件包含 web116
- vba中的查找匹配函数
- python 内存不足 dict 替代方案_2D数组代表一个巨大的python dict,COOrdinate就像解决方案来节省内存...
- PageRank算法以及Python实现(简洁版)
- 欧拉降幂及其扩展欧拉降幂