k8s中pod的生命周期
Pod 是Kubernetes 集群中的最小单元,而 Pod 是由容器组成的,所以Pod 的生命周期可以先来讨论下容器的生命周期。
实际上 Kubernetes 为容器提供了生命周期钩子,就是Pod Hook,Pod Hook 是由 kubelet 发起的,当容器中的进程启动前或者容器中的进程终 止之前运行,这是包含在容器的生命周期之中。可以同时为 Pod 中的所有 容器都配置 hook
pod的生命周期
根容器为基础容器负责网络及存储卷的共享
liveness 就是存活探针 周期性的检测主容器是否健康,如果判断为不健康那么将会重启创建容器并且启动。他为周期性持续运行监测 。可通过 http 命令 socket进行判断是否存活
readiness 为就绪探针 周期性的检测程序是否健康 如果不健康就不会分发请求
当pod被调度后pod的生命周期首先创建一个pause容器(根容器),然后进行初始化容器成功后退出,再进入到下一步当主容器运行起来以后先做一个进程起来前的钩子,比如环境初始化之类的,当这些都运行起以后才会运行容器的主要进程,这时liveness(探针)就会启动,然后启动readiness,当所有的都正常执行后
当删除pod时如果还有请求,那么可以配置钩子函数进行优雅关闭主容器中进程,关闭后再关闭容器
PostStart:这个钩子在容器创建后立即执行。但是,并不能保证钩子 将在容器ENTRYPOINT 之前运行,因为没有参数传递给处理程序。主要 用于资源部署、环境准备等。不过需要注意的是如果钩子花费太长时间 以至于不能运行或者挂起,容器将不能达到running状态。
PreStop:这个钩子在容器终止之前立即被调用。它是阻塞的,意味着 它是同步的,所以它必须在删除容器的调用发出之前完成。主要用于优 雅关闭应用程序、通知其他系统等。如果钩子在执行期间挂起,Pod阶 段将停留在running状态并且永不会达到failed 状态。
如果PostStart 或者PreStop钩子失败,它会杀死容器。所以应该让钩子 函数尽可能的轻量。当然有些情况下,长时间运行命令是合理的,比如在 停止容器之前预先保存状态。
两种方法:
Exec - 用于执行一段特定的命令,不过要注意的是该命令消耗的资源 会被计入容器。
HTTP - 对容器上的特定的端点执行HTTP请求。
使用poststart
#使用PostStart
vim poststart.yaml
apiVersion: v1
kind: Pod
metadata:
name: hook-demo1
spec:
containers:
- name: hook-demo1
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
kubectl apply -f poststart.yaml
kubectl get pod
kubectl exec post-nginx -it -- cat /usr/share/message
使用prestop优雅关闭
当用户请求删除含有 pod 的资源对象时(如Deployment等),K8S 为了 让应用程序优雅关闭(即让应用程序完成正在处理的请求后,再关闭软 件),K8S提供两种信息通知:
1.默认:K8S 通知 node 执行docker stop命令,docker 会先向容器 中PID 为1的进程发送系统信号SIGTERM,然后等待容器中的应用程序 终止执行,如果等待时间达到设定的超时时间,或者默认超时时间 (30s),会继续发送SIGKILL的系统信号强行 kill 掉进程。 (即为 kill -15 )
2.使用 pod 生命周期(利用PreStop回调函数),它执行在发送终止信 号之前
vim prestop.yaml
apiVersion: v1
kind: Pod
metadata:
name: pre-nginx1
spec:
containers:
- name: pre-nginx1
image: nginx
lifecycle:
preStop:
exec:
command: ["/usr/sbin/nginx","-s","quit"]
---
apiVersion: v1
kind: Pod
metadata:
name: pre-nginx2
labels:
app: web
spec:
containers:
- name: pre-nginx2
image: nginx
ports:
- name: webport
containerPort: 80
volumeMounts:
- name: message
mountPath: /usr/share/
lifecycle:
preStop:
exec:
command: ['/bin/sh', '-c', 'echo Hello from the preStop Handler > /usr/share/message']
volumes:
- name: message
hostPath:
path: /usr/local/work/nginx/
kubectl create -f prestop.yaml
kubectl get po -o wide
kubectl delete pod hook-demo2
kubectl delete pod hook-demo3