k8s中pod的生命周期

Pod 是Kubernetes 集群中的最小单元,而 Pod 是由容器组成的,所以Pod 的生命周期可以先来讨论下容器的生命周期。

实际上 Kubernetes 为容器提供了生命周期钩子,就是Pod Hook,Pod Hook 是由 kubelet 发起的,当容器中的进程启动前或者容器中的进程终 止之前运行,这是包含在容器的生命周期之中。可以同时为 Pod 中的所有 容器都配置 hook

微信截图_20230829172258.pngpod的生命周期

根容器为基础容器负责网络及存储卷的共享

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