K8S-pod 生命周期,探针

Pod的生命周期

  1. pod状态 : pending 调度尚未完成
  2. runing 运行中
  3. failed 失败
  4. succeeded 成功
  5. unknow 未知 有可能某个组件进程挂掉 kubelet…

创建pod过程:

  • 请求–> apiserver–>保存请求到etcd中
  • apiserver–>scheduler–>将调度的结果保存在etcd的pod资源的状态信息中
  • 目标节点上的kubelet通过apiserver获取用户创建的清单
  • kubelet根据清单在当前节点上创建并运行pod并发送节点状态给apiserver
  • 再次保存信息到etcd当中

pod生命周期的重要行为

初始化容器

容器探针类型

liveness          用于探测容器内主程序或容器是否存活(存活性探测)存活未必就绪
readiness       用于提供容器内服务是否能提供服务,类似于进程 (就绪性探测)

  iveness的初始值为成功。这样防止在应用还没有成功启动前,就被误杀。如果在规定时间内还未成功启动,才将其设置为失败,从而触发容器重建。

  而readiness的初始值为失败。这样防止应用还没有成功启动前就向应用进行流量的导入。如果在规定时间内启动成功,才将其设置为成功,从而将流量向应用导入。

  livenessprobe:存活探针,用于探测容器是否健康,如果不健康,kubelet会删除掉,并根据容器的重启策略重启pod,如果不写,那永远默认是成功。

  存活不一定就绪!!!

  readinessprobe:就绪性探测。用于判断容器是否启动完成,且准备接受请求,如果探测到容器启动失败,pod状态会被修改,endpoint controller会从service endpoint删除掉这个pod ip的endpoint条目。

startupProbe

自1.6版本后,新增startupProbe探针,当pod启动,首先进行startupProbe探测,当startupProbe检测通过,再去执行livenessProbe探测,之后便不再执行startupProbe探测。

问题提出:

1. livenessProbe可以配置initialDelaySeconds来延迟检测,为什么还会依赖startupProbe ?

因为有的容器就绪性很慢,而initialDelaySeconds设置时长不好把控,设置太短:当达到这个时间后,容器仍未就绪,kubelet会停止pod并不断尝试重启pod,当下一次仍然超时,会造成死循环。设置太长:浪费时间。

解决方案:

使用startupProbe 灵活替代initialDelaySeconds 固定的延迟时间探测,解决了 固定延迟 的局限性。

startupProbe:
  httpGet:
    path: /api/successStart   # 检测路径
    port: 80
  periodSeconds: 3      # 检测间隔
  timeoutSeconds: 3    # 3秒未响应为失败,超时时间
  successThreshold: 1  # 检测成功1次就绪
  failureThreshold: 2    # 检测失败2次表示未就绪 

核心区别

  • initialDelaySeconds
    只提供单次固定的延迟,在延迟结束后立即开始执行 livenessProbe

    • 如果应用启动时间不确定或偶尔较长,initialDelaySeconds 可能不够用。
    • 一旦探测失败,容器将被重启,可能导致无限重启
  • startupProbe
    提供动态探测的灵活性,能够根据配置的 failureThresholdperiodSeconds 给应用充足时间完成启动。

    • 允许多次探测尝试(而不是固定时间后直接进入重启)。
    • 期间暂停 livenessProbereadinessProbe,避免误判导致容器重启。
总结
    • 如果应用启动时间较短且固定,initialDelaySeconds 就足够了。
    • 如果应用启动时间较长或不确定,推荐使用 startupProbe,避免误判重启,提高容器的稳定性。

探针检测方式有三种

  1. Execaction:在容器内部执行一个命令,如果返回状态码为0,则表示容器健康。
  2. TCPSocketAction:通过容器的IP地址和端口执行TCP检测。
  3. HTTPGetAction:通过应用程序暴漏的API接口返回状态码判断,大于200且小于400。

pod内容器探测重启策略

restartPolicy:  重启逻辑:时间叠加,最长为5分钟
      always   默认总是重启
      onfailure  当容器状态错误时重启,正常退出不会重启
      nerver   从不

Pod终止:宽限期默认为30s,若30秒后容器未终止,则强制杀死

startupProbe演示

写一个不存在的接口测试

容器探测-ExecAction探针demo

复制代码
apiVersion: v1
kind: Pod     //自主式Pod资源
metadata:
  name: liveness-exec-pod
  namespace: default
spec:
  containers:
  - name: liveness-exec-containers
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c","touch /heslthy; sleep 30; rm -f /tmp/healthy; sleep 3600"]
    livenessProbe:             # 指定为存活性探测
      exec:                         # 探针类型
        command: ["test","-e","/healthy"]       # 执行一段命令
      initialDelaySeconds: 5        # 容器启动后5秒开始探测,因为有的程序启动很慢,这个无法预估程序启动时间,短了会不断重启
      periodSeconds: 3              # 检测间隔
timeoutSeconds: 3 # 3秒未响应为失败,超时时间
    successThreshold: 1 # 检测成功1次就绪
failureThreshold: 2 # 检测失败2次表示未就绪
复制代码

花费时间计算:共检测2次,间隔3s,超时时间3s,所以失败总耗时为2*3*3=18s

HTTPGetAction 探针类型演示

复制代码
apiVersion: v1
kind: Pod      //自主式Pod资源
metadata:
  name: liveness-httpget-pod
  namespace: default
spec:
  containers:
  - name: liveness-httpget-containers
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 90      //指定不存在的端口用于测试
    livenessProbe:
      httpGet:                 //指定探针类型
        port: http             //指定名称为http的端口
        path: /index.html     //指定探测路径
      initialDelaySeconds: 5
      periodSeconds: 3
timeoutSeconds: 3
复制代码

就绪性探测demo

复制代码
apiVersion: v1
kind: Pod      //自主式Pod资源
metadata:
  name: readiness-httpget-pod
  namespace: default
spec:
  containers:
  - name: readiness-httpget-containers
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    readinessProbe:      //指定容器探测为就绪性探测
      httpGet:                //探针类型为httpGet方法
        port: http
        path: /index.html       //监控该文件是否就绪
      initialDelaySeconds: 5   # 
      periodSeconds: 3
timeoutSeconds: 3 //3秒未响应为失败
复制代码

livenessProbe-TCP

复制代码
apiVersion: v1
kind: Pod      //自主式Pod资源
metadata:
  name: liveness-httpget-pod
  namespace: default
spec:
  containers:
  - name: liveness-httpget-containers
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    livenessProbe:      //指定容器探测为就绪性探测
      initialDelaySeconds: 5
      periodSeconds: 3
      timeoutSeconds: 3   //3秒未响应为失败
      tcpSocket:
         port: 80 //80可以响应不代表就绪,因为可能后端存储挂了,端口仍然可以正常响应,适用于nginx使用
复制代码

pod hook

由kubelet发起,当容器中的进程启动前或者容器中的进程终止之前运行,这是包含在容器的生命周期之中。可以同时为pod中的所有容器都配置hook。

hook包含以下两种类型:

exec:执行一段命令

http:发送http请求

容器启动后钩子完整版

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: poststart-pod
  namespace: default
spec:
  containers:
  - name: busybox-httpd
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    readinessProbe:
      httpGet:                 //指定探针类型
        port: http             //指定名称为http的端口
        path: /index.html     //指定探测路径
      initialDelaySeconds: 5
      periodSeconds: 3
      timeoutSeconds: 3
    livenessProbe:
      httpGet:                 //指定探针类型
        port: http             //指定名称为http的端口
        path: /index.html     //指定探测路径
      initialDelaySeconds: 5
      periodSeconds: 3
      timeoutSeconds: 3
    - name: busybox-1
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    commad: ["/bin/bash", "-c", "touch /tmp/live; sleep 600; rm -rf /tmp/live; sleep 3600"]   //测试用,生产不需要
    livenessProbe:
      exec:                 //指定探针类型
        commad: ["test", "-e", "/temp/live"]   //-e 检测文件是否存在
      initialDelaySeconds: 5
      periodSeconds: 3
    readinessProbe:      //指定容器探测为就绪性探测
         exec:                 //指定探针类型
        commad: ["test", "-e", "/temp/live"]
      initialDelaySeconds: 5
      periodSeconds: 3
    lifecycle:   //生命周期,hook类型
      postStart:  //启动前操作,可以把这个步骤交给inic进行操作
        exec:     //hook类型
          command: ['/bin/sh','-c','echo haha >> /data/web/html/index.html']     //错误示范,此处明白原理即可,可以用作判断某个文件或者程序是否存在,如果不存在会怎么样
      postStart:  //启动后操作
        exec:     //hook类型
          command: ['/bin/sh','-c','echo haha >> /data/web/html/index.html']
    initContainers:       //init C 伴随应用程序启动,如果init C启动失败,应用pod会一直pending
    - name: init-myservice
      image: busybox:1.34.1
      commad: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']   //until表示解析myservice,当正常解析,退出,解析失败,休眠2s,循环
    - name: init-mydb
      image: busybox:1.34.1
      commad: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
复制代码

总结:容器探测 liveness 与 readiness 的原因
由于动态有生命周期的pod访问是由service转发至后端,当创建新的pod后由标签选择器立即关联至service,此时当用户请求立即被调度到此pod,但是由于pod内容器未初始化完成或未就绪,可能会导致客户访问失败

pod 退出流程

1、用户执行删除操作——进入宽限期terminatiing(terminationGracePeriodSeconds: 30)等待时间,pod内进程处理数据并进行收尾工作——删除完成
2、svc删除关联的endpoint
3、执行定义的 Prestop命令:比如zookeeper注册与自动发现中心,用于通知zookeeper服务下线,zookeeper从注册表删除该pod ip地址,然后容器进入等待状态。
  zookeeper通知调用方服务已下线,等待调用方停止调用后杀死pod。

pod 钩子

复制代码
lifecycle:
  preStop: # 停止前执行的操作
    #httpGet:
    # path: /
    # port: 80
  exec:
    commad:
    - sh
    - -c
    -  sleep 90
复制代码

 

posted @   不会跳舞的胖子  阅读(177)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示