首页 > 其他分享 >【云原生】K8s pod优雅退出(postStart、terminationGracePeriodSeconds、preStop)

【云原生】K8s pod优雅退出(postStart、terminationGracePeriodSeconds、preStop)

时间:2022-09-03 12:12:26浏览次数:90  
标签:容器 hook exec terminationGracePeriodSeconds preStop pod postStart

目录

一、概述

  • 更新部署服务时,旧的 Pod 会终止,新 Pod 上位。
  • 如果在这个部署过程中老 Pod 有一个很长的操作,我们想在这个操作成功完成后杀死这个 pod(优雅关闭),如果无法做到的话,被杀死的 pod 可能会丢失一定的流量,或者外界无法感知到该 Pod 被杀死。
  • 特别是,如果我们有一个接收大量流量的 API,错误率在部署过程中会显著增加。这时就必须要设置一些预处理操作让pod的优雅退出,先来了解一下pod的生命周期。

二、Pod 的 生命周期

在这里插入图片描述
我们一般将pod对象从创建至终这段时间范围成为pod的生命周期,它主要包含以下的过程:

  • pod创建;
  • 运行初始化容器(init container);
  • 运行主容器(main container);
  • pod终止过程,pod完全退出之前执行pre stop操作,也就是收尾工作。

三、pod的终止过程

  • 在 Pod 退出时,kubelet 删除容器之前会先执行 pod 的 preStop,允许 pod 在退出前执行一段脚本用以清除必要的资源等。
  • 然而 preStop 也有执行失败或者直接 hang 住的情况,这个时候 preStop 并不会阻止 pod 的退出,kubelet 也不会重复执行,而是会等一段时间,超过这个时间会直接删除容器,保证整个系统的稳定。

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

  • 【第一步】用户发出删除 pod 命令
  • 【第二步】K8S 会给旧POD发送SIGTERM信号;将 pod 标记为“Terminating”状态;pod 被视为“dead”状态,此时将不会有新的请求到达旧的pod;
  • 【第三步】并且等待宽限期(pod.spec.terminationGracePeriodSeconds 参数定义,默认情况下30秒)这么长的时间
  • 第三步同时运行,监控到 pod 对象为“Terminating”状态的同时启动 pod 关闭过程
  • 第三步同时进行,endpoints 控制器监控到 pod 对象关闭,将pod与service匹配的 endpoints 列表中删除
  • 如果 pod 中定义了 preStop 处理程序,则 pod 被标记为“Terminating”状态时以同步的方式启动执行preStop;若宽限期结束后,preStop 仍未执行结束,第二步会重新执行并额外获得一个2秒的小宽限期(最后的宽限期,所以定义preStop 注意时间,和terminationGracePeriodSeconds 参数配合使用),
  • Pod 内对象的容器收到 TERM 信号
  • 宽限期结束之后,若存在任何一个运行的进程,pod 会收到 SIGKILL 信号
    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: #uri地址
        port:
        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: 5 # 设置5秒宽限时间,默认是30s
      nodeName: local-168-182-110 # 为了测试方便,指定调度机器
      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/pod-hook-exec.log
          subPath: pod-hook-exec.log
      containers:
      - name: main-container
        image: busybox
        command: ["sh","-c","echo main-container...|tee -a /tmp/pod-hook-exec.log;sleep 3600s"] # 只有这个才会输出到屏幕,也就是通过logs只能查看主容器日志
        volumeMounts:
        - name: logs
          mountPath: /tmp/pod-hook-exec.log
          subPath: pod-hook-exec.log
        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: /opt/k8s/test/
kubectl apply -f test.yaml ;kubectl get pods -w |grep pod-hook-exec

在这里插入图片描述
在这里插入图片描述

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

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

关于K8s pod优雅退出优雅退出,执行先后顺序就先到这里了,有疑问的小伙伴欢迎给我留言哦,后续会持续分享关于【大数据与云原生】相关的文章,请小伙伴耐心等待哦~

标签:容器,hook,exec,terminationGracePeriodSeconds,preStop,pod,postStart
From: https://www.cnblogs.com/liugp/p/16652330.html

相关文章

  • pod概念,部署pod应用
    pod概念,部署pod应用zoukankan     html  css  js  c++  javapod概念,部署pod应用一:kubectl工具的使用kubectl是操作k8s的命令行工......
  • pod中进行vi操作导致内存异常触发重启
    前天应用反馈说有个集群的访问异常抖动,于是查看了一下配置。发现pod异常重启了。于是怀疑是jmv异常,于是在pod中查看相关的日志。结果又重启了2次。于是对这二次进行分析......
  • K8S 设置node最大pod数量
    1.默认情况下k8s一个node最多起110个pod。2.在node上设置打开文件/var/lib/kubelet/config.yaml3.修改参数maxPods为指定的值。4.node端重启kubelet:systemctlrest......
  • Cocoapods的简单介绍和使用
    1、Cocoapods运行环境和gem命令1.1Ruby运行环境和gem命令Mac自带Ruby环境。如果gem版本太旧,可以使用以下指令升级到最新: sudogemupdate--system检查Ruby版本指......
  • podman用脚本和dockerfile做apache编译安装镜像(alpine版)
    podman用脚本和dockerfile做apache编译安装镜像(alpine版)alpine系统是什么AlpineLinux是一个基于musllibc和busybox的面向安全的轻量级Linux发行版。alpine系统......
  • pod QoS等级(A)
    一、了解PodQos等级一个节点不一定能提供所有pod所指定的资源limits之和那么多的资源量。假设有两个pod,podA使用了节点内存的90%,podB突然需要比之前更多的内存,这时......
  • k8s之 pod调度
    案例:确保Pod分配到具有SSD硬盘的节点上第一步:给节点添加标签格式:kubectllabelnodes<node-name><label-key>=<label-value>例如:kubectllabelnodesk8s-node1dis......
  • 解析OCC几何体(TopoDS_Shape)生成自定义off文件(转)
    voidParseTopoDSShapeToOff(constTopoDS_Shape&aShape){//0计算顶点和顶点索引//std::vector<osg::Vec3d>vertexArray;BRepMesh_IncrementalMesh(aSh......
  • Pod生命周期和重启策略
    Pod在整个生命周期过程中被系统定义为各种状态,具体如下*Pending:APIServer已经创建该pod,但pod中有一个或多个容器镜像没有创建,包括正在下载镜像的过程*Running:P......
  • Kubernetes Container、Pod、Namespace内存及CPU限制
        如果运行的容器没有定义资源(memory、CPU)等限制,那么该容器可以使用宿主机的最大可用资源,直到无资源可用而触发宿主机(OOMKiller),为保证容器资源合理利用,需要在nam......