从零开始学习k8s-07容器的生命周期
点点寒彬 2021-10-27 22:24:19
kubernetes
背景
上文我们使用了Init
容器来给我们的容器注入必要数据,那么如果没有init
容器,也同样有办法给容器注入数据,这就要利用容器的生命周期。
目前k8s
暴露了两个回调方法,postStart
和preStop
。
postStart
是在容器启动的时候调用的方法。
preStop
是在容器停止的时候调用的方法。
开始实践
同样,我们依然参考官方的示例来学习。
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
preStop:
exec:
command: ["/bin/sh","-c","nginx -s quit; while killall -0 nginx; do sleep 1; done"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
这里定义了两个方法,分别用shell
进行了一些操作。
我们创建了容器之后,进入容器查看这个文件是否存在。
kubectl exec -it lifecycle-demo -- /bin/bash
root@lifecycle-demo:/# ls
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint.d etc lib media opt root sbin sys usr
root@lifecycle-demo:/# cat /usr/share/message
Hello from the postStart handler
1
2
3
4
5
6
2
3
4
5
6
可以看到我们的数据已经写入到容器中了。
讨论
这个实践其实很简单,我们从现象上可以发现,我们使用postStart
产生的功能和init
容器是一样的。如果功能是一样的化,那么为什么会有这么两个方法呢?
- 执行顺序差异
init
容器会优先执行,执行完毕之后才会进行主容器的启动,而postStart
则是主容器启动的时候才会触发的回调。
这里的顺序差异就会出现一个问题,数据获取的时效问题。比如我的服务的启动依赖注入的数据,那么使用init
的方式就可以保证拉取数据在服务启动之前,而postStart
回调是在容器启动的时候异步进行的,也就是说没办法保证服务启动之前把数据拉取下来。
- 数据载体差异
用init
容器来做数据注入数据,前提这个数据就被打包成镜像,然后通过共享数据卷的方式实现注入,而postStart
的回调则是触发一行命令,要拉取数据的化,大部分情况是通过这行命令进行一些网络调用,拉取数据。
由于init
使用的是镜像来承载数据,因此可以承载大量的数据,而postStart
是通过网络进行数据拉取,因此一旦数据量比较大的时候,就会由于数据量大拉取耗时导致容器的启动被卡住,而k8s
的pod
状态要变成Running
,就必须要postStart
执行完毕。