书籍来源:《CKA/CKAD应试指南:从Docker到Kubernetes完全攻略》
一边学习一边整理老师的课程内容及实验笔记,并与大家分享,侵权即删,谢谢支持!
附上汇总贴:CKA备考实验 | 汇总_热爱编程的通信人的博客-CSDN博客
pod的延期删除
前面讲述过,删除pod的时候,可以加上--force选项提高删除pod的速度,那么如果不加--force选项,为什么会那么慢呢?原因在于kubernetes对pod的删除有个延期删除期(即宽限期),这个时间默认是30s,如图5-7所示。
假设没有宽限期的话,某个pod正在处理用户的请求,然后我们发出一个删除此pod的命。这个pod会立即被强制删除,而不管它是不是正在处理任务,这样会影响到正在连接此pod的那部分用户的正常使用,这叫作粗暴地删除pod。
有了宽限期就不一样了,当我们对某个pod发出删除命令的时候,这个pod的状态会被标记为“terminating”,但此时并不会立即把这个pod删除,而是等待这个pod继续处理手头的任务。如果在30s内任务完成的话,则pod会被自动删除,如果超过30s任务还没结束,则此pod会被强制删除。这种删除pod的方式就叫作优雅地删除pod。
这个宽限期可以通过参数terminationGracePeriodSeconds来指定。
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
terminationGracePeriodSeconds: 15
containers:
- image: busybox
imagePullPolicy: IfNotPresent
command: ["sh","-c","sleep 1000"]
name: pod1
resources: {}
这里把宽限期改为了15s,即当我们要删除pod的时候会有15s的宽限期。容器里执行的命令是sleep 1000,要1000s之后才能终止,所以15s之后pod1会被强制删除。这里如果把terminationGracePeriodSeconds的值设置为0的话,当删除此pod时,这个pod就会被立即删除。
不过,如果pod里运行的是nginx进程,就不一样了,因为nginx处理信号的方式和kubernetes处理信号的方式并不一样,如图5-8所示。
当我们要对镜像为nginx的pod发出删除信号的时候,pod里的nginx进程会被很快关闭(fast shutdown),之后pod也很快被删除,并不会使用kubernetes的删除宽限期,如图5-9所示。
这样就带来了一个问题,当我们在删除某个pod的时候,有客户端正在连接此pod怎么办?如果此pod被强制删除,客户端就会访问报错,那怎么办呢?可以通过下面的pod钩子来解决问题。
pod hook(钩子)
在整个pod生命期(lifecycle)内,有两个hook是可用的。
(1)postStart:当创建pod的时候,会随着pod里的主进程同时运行,没有先后顺序。
(2)preStop:当删除pod的时候,要先运行preStop里的程序,之后再关闭pod。
对于preStop来说,也必须要在pod宽限期内完成,如果preStop在宽限期内没有完成,则pod 仍然会被强制删除。
看下面的例子,修改pod2.yaml文件,内容如下。
##########实操验证##########
[root@vms10 pod]# cat pod2.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod2
name: pod2
spec:
terminationGracePeriodSeconds: 600
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod2
resources: {}
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "/usr/sbin/nginx -s quit"]
[root@vms10 pod]#
当执行删除pod的时候,pod的状态被标记为“terminating”,此时删除信号并没有发送到pod里的主进程nginx -g daemon off;,而是要先执行preStop hook里的进程。即/usr/sbin/nginx -s quit。
/usr/sbin/nginx -s quit是一种优雅地关闭nginx的方式,即先处理完手头已有的任务,再关闭nginx进程。当处理完所有的已有任务之后,preStop hook任务结束,然后pod里的主程序接收关闭信号,再把nginx pod删除。
这里把宽限期设置为600s,目的是让preStop hook有足够的时间去处理已有任务,preStop执行之后,主进程不会等宽限期结束,前面讲了nginx收到信号之后,会很快关闭进程。