• Kubernetes之Pod生命周期管理


    一、Pod完整生命周期

    在这里插入图片描述

    • 用户发起创建pod请求到apiserver,apiserver存储pod信息到etcd中。pod还未调度,pod的nodeName是空的,此时pod处于Pending状态
    • scheduler监听到 pending状态的pod,经过调度策略(资源请求,tolerations,亲和度等)选择一个节点,调度后此时pod处于ContainerCreating状态
    • node上的kublet调用CRI,CNI,CSI接口启动容器,启动后pod处于Running状态
    • 用户删除pod时,pod立即处于Terminating状态。停止容器进程,删除网络,卸载目录挂载,删除finalizer。即删除所有和pod有关的对象(gone)。
    • 假如pod中的所有容器进程都异常退出了,或者至少有一个容器进程exit非0,且重启策略为Never,那么pod处于Failed状态
    • 假如node由于网络原因,无法上报状态,那么pod处于Unknown状态
    • 假如pod中的所有容器进程都正常退出了,且重启策略为Never,那么pod处于Successd状态
    • 假如pod被kubelet驱逐了,那么pod处于Evicted状态

    下图就是上面pod状态流转步骤的简化,Pod状态机
    在这里插入图片描述

    1、Pod STATUS

    在这里插入图片描述
    kubectl get pod中的STATUS是由pod中status的conditions和phase计算得来的。
    在这里插入图片描述

    2、状态计算细节

    常见的比如CrashLoopBackOff:phase状态为running,但是容器进程退出了。
    最下面的Outofcpu/OutofMemory:由于kubelet有准入插件,当node的cpu或者内存不足时,就会出现这个状态。
    在这里插入图片描述

    二、Pod高可用与使用规范

    • 应用要想平稳的运行在k8s上,owner就必须知道应用的资源需求。
      🔥 设置合理的 resources.memory.request 防止容器进程被 OOMKill;
      🔥 设置合理的 emptydir.sizeLimit 并且确保数据写入不超过 emptyDir 的限制,防止 Pod 被驱逐。
    • 需要部署多少实例
    • 更新策略:二者不能同时为0。
      🔥 maxSurge:和期望ready的副本数比,超过期望副本数最大比例(或最大值),这个值调的越大,副本更新速度越快。
      🔥 maxUnavailable:和期望ready的副本数比,不可用副本数最大比例(或最大值),这个值越小,越能保证服务稳定,更新越平滑;

    1、容器可能遇到的故障

    在这里插入图片描述

    2、pod数据如何存储

    在这里插入图片描述

    3、QosClass

    在这里插入图片描述

    • Guaranteed
      Pod 的每个容器都设置了requests 和 limits 且是一致的
    • Burstable
      至少一个容器制定了 CPU 或内存需求,requests 和 limits 可以不一致
    • BestEffort
      Pod 中的所有容器都未指定 CPU 或内存需求

    当计算节点检测到内存压力时,Kubernetes 会按 BestEffort-> Burstable->Guaranteed的顺序驱逐podBurstable 适用于大多数场景。因为它既支持超卖,又锁定一定的资源,可以平衡资源利用率和应用的性能。

    4、tolerationSeconds

    当node状态异常时,nodeLifeCycleController会监听这种node和node上的pod。当node状态为notReady或unreachable时,这个node就会被打上如下的taint。

    • NoExecute:node上的pod被驱逐
    • NoSchedule:不往这个node上调度pod
    taints:
    - effect: NoSchedule
      key: node.kubernetes.io/unreachable
      timeAdded: "2022-03-09T11:25:10Z"
    - effect: NoExecute
      key: node.kubernetes.io/unreachable
      timeAdded: "2022-03-09T11:25:21Z"
    - effect: NoSchedule
      key: node.kubernetes.io/not-ready
      timeAdded: "2022-03-09T11:24:28Z"
    - effect: NoExecute
      key: node.kubernetes.io /not-ready
      timeAdded: "2022-03-09T11:24:32z"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    但是pod也有对应的tolerations。由于网络可能会抖动,所以需要tolerationSeconds,默认是300s。如果是依赖于本地存储状态的有状态应用应增大 toleration Seconds 比如900s以避免被驱逐。
    在这里插入图片描述

    5、health check

    (1)健康探针类型
    • startupProbe:应用没有起来,探活和就绪探测是失败的,由于不停的重试会导致应用压力过大。在初始化阶段(Ready 之前)进行的健康检查,startupPorbe运行后才运行liveness和readness。此Probe应该设置较长的间隔时间,避免过于频繁的监测影响应用启动。
    • readinessProbe:就绪状态检查,只在pod刚创建时才会有,标志着这个pod创建之后是否符合起来了的标准,通过之后,pod进入ready状态。
    • livenessProbe:存活探测,只在pod成功ready运行之后,才会进行的探测。确保pod一直处于正常可提供服务的状态,检查失败时,意味着该应用进程已经无法正常提供服务,kubelet会终止该容器进程,并按照 restartPolicy 决定是否重启
    (2)探测方法
    • Exec:在容器内部运行指定命令,当返回码为◎时,探测结果为成功。
    • TCPSocket:由 kubelet 发起,通过TCP 协议检查容器 1P 和端口,当端口可达时,探测结果为成功。
    • HTTPGet:由 kubelet 发起,对Pod 的IP 和指定端口以及路径进行HTTPGet 操作,当返回码为 200-400 之间时,探测结果为成功。
    (3)探针相关细节
    【1】探针属性
    • initialDelaySeconds 表示延迟5s开始第一次探测,默认值是0,最小值是0。
    • timeoutSeconds 表示每次探测的超时时间,5s后如果没返回结果就认为超时失败,默认值是1,最小值是1。
    • successThreshold 表示在探测失败后,最小的连续成功被认为是成功的,默认值是1,最小值是1。
    • failureThreshold 表示当探测失败时,Kubernetes将在认为失败前尝试次数。默认值是3,最小值是1。
    • periodSeconds 表示多久进行一次探测,默认是10S,最小值是1。
    【2】重启策略
    • Always: 当容器终止退出后,总是重启容器,默认策略
    • Onfailure: 当容器异常退出后(退出码非0)时,才重启容器
    • Never: 当容器终止退出时,不重启容器
    【3】ReadinessGates(还有疑问)
    • 使用了ReadinessGates,即使readiness就绪返回成功了,pod也不算就绪。
    • ReadinessGates condition status需要为 True 状态后,加上内置的 Conditions,Pod才可以为就绪状态。
    • 状态应该由某控制器修改
    apiVersion: v1
    kind: Pod
    ...
    spec:
      readinessGates:
      # 这个配置只是加了个conditions.type
      - conditionType: www.example.com/feature-1 
      dnsPolicy: ClusterFirst
    status:
      conditions:
      - lastProbeTime: null
        lastTransitionTime: "2022-09-12T09:14:26Z"
        message: corresponding condition of pod readiness gate "www.example.com/feature-1"
          does not exist.
        reason: ReadinessGatesNotReady
        status: "False"
        # 上面说加了个conditions.type,为什么type是ready?
        type: Ready 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    未解决疑问:为什么type是ready?

    【4】Post-start 和 Pre-Stop Hook

    Post-start:容器启动后还需要做一些额外的操作,可以执行Post-start script。无法保证script和容器的 Entrypoint谁先运行
    Pre-Stop:用户删除容器时,会先运行Pre-Stop script,这里面可以定义优雅终止。然后kubelet会发kill -SIGTERM不再接受新的连接,然后再发kill -SIGKILL。
    在这里插入图片描述

    【5】terminationGracePeriodSeconds
    • 当删除pod到kubelet强制kill容器进程的时间是terminationGracePeriodSeconds。默认是30s。可以防止应用突然被kill掉。
    • 如果30s内还没有执行完成,那么pod会被强制删除。
      在这里插入图片描述
      在这里插入图片描述
    【6】优雅启动和终止(代码示例)

    优雅的初始化进程应该:

    • 正确处理系统信号量,将信号量转发给子进程
    • 在主进程退出之前,需要先等待并确保所有子进程退出
    • 监控并清理孤儿子进程
    • 可以使用tini作为容器镜像的entrypoint。参考链接:https://qithub.com/kralin/tini
    func main() {
    	...
    	klog.Info("Server Started")
    	// 监听 OS shutdown 信号
    	signalChan := make(chan os.Signal, 1)
    	signal.Notify(signalChan, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
    	<-signalChan
    	klog.Info("Server Stopped")
    	ctx, concel := context.WithTimeout(context.Background(), 5*time.Second)
    	defer func {
    		// extra handling here
    		concel()
    	}
    	if err := svr.Shutdown(ctx); err != nil {
    		klog.Errorf("HTTP Server Shutdown Failed: %v", err)
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    Linux之(15)shell(7)常见命令
    无线智能振弦采集系统(NLM5或6多通道无线采集采发仪)
    网页大作业代码自取
    如何在使用avue-crud组件时写监听
    【数据结构】插入排序
    mysql中的utf8mb4、utf8mb4_unicode_ci、utf8mb4_general_ci
    最近看论文常见的几个术语
    网球场地预约
    jetson nano——ubuntu换源
    如何实现将拖动物体限制在某个圆形内--实现方式vue3.0
  • 原文地址:https://blog.csdn.net/weixin_44571270/article/details/126821406