在介绍Kubernetes容器生命周期回调前,展示一个案例。
有个私有化部署的项目需要跑一个redis用作缓存,因redis中的数据不需要持久化,选择在Kubernetes中通过deployment的方式部署,下面是deployment的代码片段,
......
- image: arm64v8/redis:6.0-alpineimagePullPolicy: IfNotPresentname: redislifecycle:# 使用k8s回调机制给redis配置访问凭据postStart:exec:command: [ "/bin/sh", "-c", "redis-cli config set requirepass 'verylongpwd'" ]ports:- containerPort: 6379name: redisprotocol: TCPresources:limits:cpu: 500mmemory: 1024Mirequests:cpu: 100mmemory: 100Mi
......
为了满足业主的安全需求,redis配置了密码访问。这里通过容器的生命周期回调“postStart”来实现。pod启动后,都很正常,一段时间后,业主那边反馈,服务连接redis异常,并提供了日志,

为什么会出现这个问题?
这里直接给出结论,因为redis使用的内存量超过1024M,进程被kubernetes杀死后又重启了,配置的密码失效,后端程序通过带凭据的方式访问redis,导致访问失败。通过“postStart”回调的方式配置redis密码是问题的原因。
“postStart”回调指定的命令会在容器被创建后立即执行。如果redis进程被重启,通过“redis-cli”配置的密码就会失效,此时容器已经产生,“postStart”指定的命令就不会再次执行,此时运行的redis是没有配置访问密码的。进入pod,在redis交互式命令行,输入“info”命令直接输出结果,也印证个这个判断。
那么什么是Kubernetes的生命周期回调?
Kubernetes有两种类型的回调:“PostStart”和“PreStop”。什么是回调,它是一种事件执行机制,将指定的函数注册到特定事件上,在事件发生前或发生后执行注册的函数。
PostStart:回调在容器产生后立即执行,不保证运行在容器的“ENTRYPOINT”之前。
PreStop:容器终止前立即执行。
上面的回调有三类实现,
- Exec,直接执行命令,比如上面配置redis访问密码的命令。退出状态码是0表示成功,否则表示失败。
- httpGet,执行http请求,访问配置的http服务,http返回状态码在[200,400)表示成功,否则表示失败。
- TcpSocket,执行tcp探测(笔者使用的k8s版本是1.20,提示TCP回调还不支持)
如果有使用blackbox的同学,对这个应该不会陌生。需要注意,httpGet和tcpSocket由kubelet进程执行,而exec在容器中直接执行。
本文对Kubernetes的容器生命周期回调做了简单介绍,希望对你有所帮助。如果需要更进一步了解,请访问官方网站。