持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情
一、Pod的生命周期概述
其实pod的生命周期就是从pod启动到死亡,经历了哪些事情。一个pod里可以有多个容器,应用运行在容器里面,也可能运行在有一个或者多个先于应用容器启动的Init容器里面。
真正给用户提供服务的容器,一定要封装在mainC里,而不是initC里面。因为initC执行完毕就销毁了。
pod的生命周期,一共有三个阶段:
第一阶段:创建pause容器,初始化网络卷,共享网络栈。
第二阶段:初始化阶段,也叫Init容器,简称initC
第三阶段:应用容器(应用运行的容器),也是主容器,主容器运行阶段,简称MainC
下面来具体看看这三个阶段都做了哪些事?
第一阶段:pause容器创建
一个pod创建以后,首先会创建一个pause容器,创建这个容器的目的有两个。第一个是创建网络栈,第二个是共享数据卷。
第二阶段:初始化InitC阶段
初始化容器,又叫initC。他和普通容器非常像,但它又有自己的特点。
init容器总是运行到成功完成为止,所以init容器一定要有退出逻辑。每个init容器都必须在下一个init容器启动之前成功完成。如果不成功,就会将整个pod删除,然后重建。如果init容器启动失败,k8s会不断地重试该pod,直到init容器成功为止。但是,如果pod对应的restartPolicy重试策略为never,他不会重新启动。
下面来看看初始化阶段的特点:
- 初始化容器类似于一个批处理操作。
- 初始化容器不是在pod创建过程中一直运行的,而是在mainC启动之前执行。
- 初始化容器这个阶段可以有,可以没有;可以有1个,也可以有多个。所以取值范围是0-Max正无穷
- initC可有可无,但一旦有,就必须执行成功,才能执行后面的操作,如果执行失败,就会将整个pod删除重建。
- 当有多个initC的时候,多个initC之间执行是串行的。执行第一个initC的时候,其他initC等待。只有第一个执行成功了,才会执行第二个initC。
- 只要有一个initC执行失败,就会删除整个pod重建。
- initC执行完以后,就退出。当前这个initC就结束了。
- 在initC中,对容器名和端口没有要求,因为initC中初始化容器是一个一个运行的,一个成功结束才会开启第二个,所以,无关容器名和端口号是否一样。
第三阶段:主容器mainC运行阶段
主容器,我们简称为mainC。来看看主容器运行的特点:
1、主容器一定是等到初始化容器全部成功执行完毕以后才执行。主容器至少要有一个。所以,主容器的取值范围是1 - max 2、在主容器运行的阶段,mainC可以在任何时候启动,在任何时候结束。整体是并行执行。 3、当mainC有多个的时候,容器名和端口不能重复。因为他们在同一个pod中,共享网络和存储卷 4、多个MainC时,执行顺序是按照代码执行的逻辑执行,但不需要等待,可以理解为每个MainC都是一个单独的线程,时间到了,就执行,不需要等待上一个mainC执行完才执行。 5、在mainC上可以加钩子函数。常用的钩子函数有两个:启动前和关闭前。
- 启动前:在mainC启动之前,有很多元数据要注入,比如:环境变量。在初始化结束之后,接下来就要去执行启动脚本了,在执行启动脚本之前执行的一些命令。但注意:启动命令,也就是启动前的钩子函数,不一定会在启动脚本执行之前完成。
- 关闭前:关闭前的钩子函数,一定会保证是在主命令MainC执行完以后才执行
6、钩子函数的作用范围是每一个MainC。每一个MainC可以有自己的启动前和关闭前钩子函数,也可以没有。
7、MainC上除了有钩子函数,还有探针。老版本探针有两种:就绪探测、存活探测。新版本增加了一种,探测前探针。
-
就绪探测:准备好了,提供给用户使用;没有准备好,就不提供给用户使用。
就绪探测的时间点是在启动后的一段时间,就像是问准备好了么?准备好了,就可以对外访问了。这里可以设置重试间隔,比如2s问一次。直到回答准备好了,这时就绪探针就结束了。
-
存活探测:就像上报心跳,如果活着,就上报活着;如果死了,就要删除pod,然后重建。mainC开始以后,会间隔 一段时间开始探测,间隔的这段时间是留出来让程序做准备工作的。这里涉及到pod的重启策略。pod的重启策略有三种:
-
第一种--always:只要关闭,就重启,不管是怎么死的。默认是第一种
-
第二种--OnFailure:只有pod以非0退出码退出时,才会重启容器。正常退出(退出码为0),则不会重启。
-
三是无论什么情况怎么死的都不重启,
不同的应用容器会选择不同的策略。比如nginx,我就不希望你死掉,所以,如果你死掉,那么就请重启,不管是什么原因。所以会选择第一种always;如果是批处理任务,批处理结束正常退出了,这时就不能是always了,应该使用第二种OnFailure。
-
-
探测前探针:在就绪探测和存活探测之前都要有一段时间让mainC做准备工作,但是应该留多长时间呢?这个是不确定的,这个时候,我们就用到了探测前探针。比如有一个就绪探测需要用到80端口,探测前探针就需要提前去检测80端口就绪了么?如果没就绪就继续等待,如果就绪了,那就可以进行就绪探测。
8、探针探测有三种方式:
- tcp:
- http: 200<=返回码<=400, 正常
- 脚本:
探针探测的结果有三种:正常,异常,未知。当探测结果是未知的时候,保持原来的状态不变。
\