0
点赞
收藏
分享

微信扫一扫

k8s进阶5-应用无损发布之Pod生命周期管理

非衣所思 2023-06-25 阅读 66

一、Pod 的 生命周期

k8s进阶5-应用无损发布之Pod生命周期管理_Pod

1.1、Pod终止过程

终止过程主要分为如下几个步骤:

  1. 用户发出删除 pod 命令;
  2. K8S 会给旧POD发送SIGTERM信号;将 pod 标记为“Terminating”状态;pod 被视为“dead”状态,此时将不会有新的请求到达旧的pod;
  3. 等待宽限期(terminationGracePeriodSeconds 参数定义,默认情况下30秒)时间;
  4. 第三步同时运行,监控到 pod 对象为“Terminating”状态的同时启动 pod 关闭过程;
  5. 第三步同时进行,endpoints 控制器监控到 pod 对象关闭,将pod与service匹配的 endpoints 列表中删除;
  6. 如果 pod 中定义了 preStop 处理程序,则 pod 被标记为“Terminating”状态时以同步的方式启动执行;若宽限期结束后,preStop 仍未执行结束,第二步会重新执行并额外获得一个2秒的小宽限期(最后的宽限期,所以定义prestop 注意时间,和terminationGracePeriodSeconds 参数配合使用),
  7. Pod 内对象的容器收到 TERM 信号;
  8. 宽限期结束之后,若存在任何一个运行的进程,pod 会收到 SIGKILL 信号;
  9. Kubelet 请求 API Server 将此 Pod 资源宽限期设置为0从而完成删除操作;

二、钩子函数(postStart 和 preStop)

钩子函数能够感知自身生命周期中的事件,并在相应的时刻到来时运行用户指定的程序代码,k8s在主容器的 启动之后停止之前 提供了两个钩子函数。

  • post start:容器创建之后执行,如果失败了会重启容器。
  • pre stop:容器终止之前执行,执行完成之后容器将成功终止,在其完成之前会阻塞删除容器的操作。

钩子处理器支持使用下面三种方式定义动作:

  • exec命令(自定义):在容器内执行一次命令

......
  lifecycle:
    postStart:
      exec:
        command:
        - cat
        - /tmp/healthy
......

  • tcpSocket:在当前容器尝试访问指定的socket,监听端口,属于四层。

......
  lifecycle:
    postStart:
      tcpSocket:
        port: 8080
......

  • httpGet:在当前容器中向某url发起http请求,监听接口,属于七层。

......
  lifecycle:
    postStart:
      httpGet:
        path: /api/health
        port: 8080
        host: 
        scheme: HTTP  #支持的协议,http或者https
......

三、示例验证

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pod-hook-exec
spec:
  replicas: 1
  selector:
    matchLabels:
     app: pod-hook-exec
  template:
    metadata:
      labels:
        app: pod-hook-exec
    spec:
      terminationGracePeriodSeconds: 8 # 设置8秒宽限时间,默认是30s
      nodeName: cn-shanghai.172.25.36.200 # 为了测试方便,指定调度机器
      initContainers:   # 后续课程重点介绍
      - name: init-containers
        image: busybox
        command: ["sh","-c","echo init-containers...|tee -a /tmp/pod-hook-exec.log;sleep 5s"]
        volumeMounts:
        - name: logs
          mountPath: /tmp/
      containers:
      - name: main-container
        image: busybox
        command: ["sh","-c","echo main-container...|tee -a /tmp/pod-hook-exec.log;sleep 3600s"]
        volumeMounts:
        - name: logs
          mountPath: /tmp/
        startupProbe:
          exec:
            command: ["sh","-c","echo startupProbe...|tee -a /tmp/pod-hook-exec.log;sleep 5s"]
          timeoutSeconds: 10
        livenessProbe:
          exec:
            command: ["sh","-c","echo livenessProbe...|tee -a /tmp/pod-hook-exec.log;sleep 5s"]
          timeoutSeconds: 10
        readinessProbe:
          exec:
            command: ["sh","-c","echo readinessProbe...|tee -a /tmp/pod-hook-exec.log;sleep 5s"]
          timeoutSeconds: 10
        lifecycle:
          postStart:
            exec: #在容器启动的时候执行一个命令
              command: ["sh","-c","echo postStart...|tee -a /tmp/pod-hook-exec.log;sleep 5s"]
          preStop: # 在pod停止之前执行这个命令
            exec:
              command: ["sh","-c","echo preStop...|tee -a /tmp/pod-hook-exec.log"]
      volumes:
      - name: logs #和上面保持一致 这是本地的文件路径,上面是容器内部的路径
        hostPath:
          path: /tmp/logs/

从上图的日志就可看出,被分为6个执行阶段,执行的先后顺序:initContainers --> 【main-container、postStart】--> startupProbe--> readinessProbe --> livenessProbe --> preStop

main-containerpostStart 是同时执行,虽然readinessProbelivenessProbe 也是同时执行,但是他们不是真正的并行执行,也有先后顺序的。

举报

相关推荐

0 条评论