Kubernetes 学习总结(42)—— Kubernetes 之 pod 健康检查详解
Kubernetes 入门
回想 2017 年刚开始接触 Kubernetes 时,碰到 Pod一直起不来的情况,就开始抓瞎。后来渐渐地掌握了一些排查方法之后,这种情况才得以缓解。随着时间推移,又碰到了问题。有一天在部署某个 springboot 微服务时,在开发测试环境部署了好多次,只有几次能成功启动,大部分的部署未能成功启动。但是生产环境却每次都能成功部署。当时这个问题困扰了我很久。由于应用启动时间较长,但是只配置了存活探针,没有配置启动探针。再加上存活探针配置的整体时间又太短了,每台机器的性能又不同,所以导致有时候能启动成功,有时候启动失败。现在想来也是蛮有意思的。要想 Kubernetes 里每个服务的可用性更高,那么对 Pod 的健康检查是少不了的。
Pod 生命周期
谈健康检查之前,首先得一起回顾下 Pod 的生命周期 或者 说是 Pod 的状态。Pod 的生命周期,从 Pending
状态开始, 如果 Pod 中至少有一个应用容器正常启动,则进入 Running
状态,之后,如果 Pod 中的容器正常退出则进入 Succeeded
状态,如果 Pod 中的容器非正常终止则进入 Failed
状态。
Pending 状态:此时 Pod 已经被 K8S 接受并且创建,但是 Pod 内还没有容器被创建,这个过程包括:等待 Pod 被调度的时间、下载镜像的时间。
Running 状态:此时 Pod 已经运行在某个节点上,Pod 内所有容器都已经创建,并且有容器处于如下状态:运行状态、正在启动状态 或 正在重启状态。
Succeeded 状态:此时 Pod 内所有容器都成功执行并且退出。
Failed 状态:此时 Pod 内所有容器都已终止,但是有容器是非正常终止的。
Unknown 状态:无法获取 Pod 状态,通常是因为 Pod 与所在主机通信失败,也可能是别的原因。
重启策略
Pod 的重启是由该 Pod 所处的 Node 节点上的 kubelet
进行判断和控制的。kubelet 会根据重启策略进行相应操作。Pod 的重启策略有 3 个:Always、OnFailure、Never,默认是 Always。
Always:重启策略是 Always 时,那么当容器运行状态是失效时,kubelet 会自动重启该容器,比如:存活探针检测到应用不健康了,就会自动重启 Pod。
OnFailure:重启策略是 OnFailure 时,那么当容器是 Failed 状态时,kubelet 会自动重启该容器。
Never:不论容器运行状态怎样,kubelet 都不会重启该容器。
健康检查
健康检查功能可以保障应用的可用性,以及控制何时可对外的访问。Kubernetes 有 3 种检查探针:LivenessProbe 存活探针、ReadinessProbe 就绪探针、StartupProbe 启动探针。
LivenessProbe 存活探针:判断容器是否存活(Running 状态),如果存活探针检测到容器不健康,则 kubelet 将 kill 掉该容器,并根据容器的重启策略做相应的处理。
ReadinessProbe 就绪探针:判断容器是否可用(Ready 状态),达到 Ready 状态的 Pod 才可以接收请求。kubelet 使用就绪探针检测容器什么时候可以接受请求。
StartupProbe 启动探针:某些应用启动比较慢,例如某个大的单体应用启动时间长达 3 分钟,此时如果只使用存活探针或者就绪探针,很可能应用还没起来,就被 kill 掉了。这种情况可以通过
启动探针
来解决。如果配置了启动探针,在存活探针和就绪探针成功之前不会重启容器。说白了就是只要配置了启动探针,那么在应用没成功启动之前,存活探针和就绪探针就不生效。
以上 3 种探针,每种都有 3 种实现方式:
ExecAction:在容器内运行一个命令,如果该命令的返回码为 0,则说明容器是健康的。
TCPSocketAction:通过容器的 IP 地址和端口号进行 TCP 检查,如果能够建立 TCP 连接,则说明容器是健康的。
HTTPGetAction:通过容器的 IP 地址、端口号以及路径,发起 HTTP 请求,如果 HTTP 响应的状态码大于等于 200 且小于 400,则说明容器是健康的。
在部署Java微服务应用时,我一般选用HTTPGetAction方式。
如何选择探针
既然有 3 种探针,那么如何选择呢?
如果你希望容器在检测到失败时,让它被 kill 掉并且自动重启,那就选择存活态探针。
如果你希望在检测成功时 Pod 才能接受请求,那就需要就绪态探针。如果某个应用 A 依赖 应用 B 的启动才能接受请求,那也需要就绪探针。
如果某个应用启动时间较长,那就需要加入启动探针。
成年人的世界不做选择题,3个字,全都要,比如:应用场景是 Spring 微服务时,3 种探针其实都会用上。一个应用启动分 3 个阶段:开始启动 → 成功启动(存活) → 可对外访问。那对应的探针使用顺序为:启动探针 → 存活探针 → 就绪探针。如下图:
如果只选择存活探针,就很尴尬:
如果配置的存活检测时间太短,那么碰到启动慢的应用,就彻底起不来了,因为应用还没起来就被 kill 掉了。
如果配置的存活检测时间太长,那么应用真到了出现问题的时候,又无法及时被重启,从而影响了整体的可用性。
如果不配置就绪探针的话,也很尴尬:
- 比如有的场景下本身应用起来了,但是依赖的应用还没起来,那么此时还无法对外提供访问能力,此时就不能让请求流量进来。
所以不做选择题,全都要,需要在每个阶段用上对应的探针。
实战
6.1、模拟不健康的应用场景
编排 yaml
比如:对 Pod 进行存活检测,30S 之后,如果不存活则 kill 掉,然后重启。
apiVersion: v1
kind: Pod
metadata:name: pod-lifecyclenamespace: demolabels:app: pod-lifecycle
spec:containers:- name: pod-lifecycleimage: busyboxargs:- /bin/sh- -c- touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600livenessProbe:exec:command:- cat- /tmp/healthy# 等待5秒执行第一次探测initialDelaySeconds: 5# 探针连续失败了 3 次之后,K8S认为检查已失败,然后触发重启failureThreshold: 3# 每5秒执行一次存活探测periodSeconds: 5
可以看到Pod被重启多次
排查异常
出现问题时也不用慌,可以通过 kubectl get pods -n demo -o wide
和kubectl describe pod pod-lifecycle -n demo
排查。可以清晰的看到异常的原因:存活检查失败。
6.2、模拟启动慢的应用
编排 yaml
比如:对 Pod 进行存活检测,30S 之后,如果不存活则kill掉,然后重启。由于模拟了启动比较耗时,所以在容器还未成功启动,就直接被kill掉了,紧接着反复被kill掉。
apiVersion: v1
kind: Pod
metadata:name: pod-lifecycle-2namespace: demolabels:app: pod-lifecycle-2
spec:containers:- name: pod-lifecycle-2image: busyboxargs:- /bin/sh- -c- sleep 20; touch /tmp/healthy; sleep 600livenessProbe:exec:command:- cat- /tmp/healthy# 等待5秒执行第一次探测initialDelaySeconds: 5# 探针连续失败了 2 次之后,K8S认为检查已失败,然后触发重启failureThreshold: 2# 每5秒执行一次存活探测periodSeconds: 5
执行 yaml 之后,可以看到,Pod 重复这样的动作:健康检查失败被重启。
引入 startupProbe 解决此问题
apiVersion: v1
kind: Pod
metadata:name: pod-lifecycle-3namespace: demolabels:app: pod-lifecycle-3
spec:containers:- name: pod-lifecycle-3image: busyboxargs:- /bin/sh- -c- sleep 20; touch /tmp/healthy; sleep 600startupProbe:exec:command:- cat- /tmp/healthy# 等待5秒执行第一次探测initialDelaySeconds: 5# 探针连续失败了 10 次之后,K8S认为检查已失败,然后触发重启failureThreshold: 5# 每5秒执行一次存活探测periodSeconds: 5livenessProbe:exec:command:- cat- /tmp/healthy# 等待5秒执行第一次探测initialDelaySeconds: 5# 探针连续失败了 2 次之后,K8S认为检查已失败,然后触发重启failureThreshold: 2# 每5秒执行一次存活探测periodSeconds: 5
总结
要想 Kubernetes 里每个服务的可用性更高,那么对 Pod 的健康检查是少不了的。本文重点如下:
Pod 生命周期:
Pending
、Running
、Succeeded
或Failed
、UnKnown
。Pod 重启策略:
Always
、OnFailure
、Never
。3 种探针类型:
启动探针
、存活探针
、就绪探针
。如何选择探针:一般情况下
全都要
。排查 Pod 问题:搭配使用
kubectl get pods -n demo -o wide
和kubectl describe pods webapp -n demo
。
相关文章:

Kubernetes 学习总结(42)—— Kubernetes 之 pod 健康检查详解
Kubernetes 入门 回想 2017 年刚开始接触 Kubernetes 时,碰到 Pod一直起不来的情况,就开始抓瞎。后来渐渐地掌握了一些排查方法之后,这种情况才得以缓解。随着时间推移,又碰到了问题。有一天在部署某个 springboot 微服务时&…...

【后端】Docker学习笔记
文章目录 Docker一、Docker安装(Linux)二、Docker概念三、Docker常用命令四、数据卷五、自定义镜像六、网络七、DockerCompose Docker Docker是一个开源平台,主要基于Go语言构建,它使开发者能够将应用程序及其依赖项打包到一个轻…...

UE5.1_Gameplay Debugger启用
UE5.1_Gameplay Debugger启用 重点问题: Gamplay Debugger启用不知道? Apostrophe、Tilde键不知道是哪个? Gameplay调试程序 | 虚幻引擎文档 (unrealengine.com) Gameplay Debugger...

【论文阅读+复现】SparseCtrl: Adding Sparse Controls to Text-to-Video Diffusion Models
SparseCtrl:在文本到视频扩散模型中添加稀疏控制。 (AnimateDiff V3,官方版AnimateDiffControlNet,效果很丝滑) code:GitHub - guoyww/AnimateDiff: Official implementation of AnimateDiff. paper:htt…...
速盾cdn:ddos防护手段
速盾CDN采用多种手段来进行DDoS防护,以确保网络和网站的正常运行。以下是速盾CDN可能采用的一些主要DDoS防护手段: 实时监测和分析: 速盾CDN实时监测网络流量,通过分析流量模式来检测异常行为,以迅速发现潜在的DDoS攻击…...

STL——queue容器
1.queue基本概念 概念:queue是一种先进先出(First In First Out,FIFO)的数据结构,它有两个出口。 队列容器允许从一端新增元素,从另一端移除元素。 队列中只有队头和队尾才可以被外界使用,因此队列不允许…...

gitLab页面打tag操作步骤
作者:moical 链接:gitLab页面打tag简单使用 - 掘金 (juejin.cn) 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 ---------------------------------------------------------------------…...

神秘的Cookie和Session
Cookie 1.Cookie是什么? Cookie是浏览器提供的持久化储存数据的方式。 2.从哪里来? Cookie从服务器中来,存储到客户端中。一个客户端就对应着一个浏览器。 服务器代码中决定了什么样的数据会储存到客户端中,通过HTTP相应的Se…...
springboot接口文档
Swagger 在Spring Boot中生成和维护接口文档的一个常用方法是使用Swagger。Swagger是一个开源软件框架,它帮助开发者设计、构建、记录和使用RESTful Web服务。下面是在Spring Boot项目中使用Swagger来创建接口文档的详细步骤:1. 添加Swagger依赖 在你的Spring Boot项目的pom…...

深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第一节 理解堆与栈
深入浅出图解C#堆与栈 C# HeapingVS Stacking第一节 理解堆与栈 [深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第一节 理解堆与栈](https://mp.csdn.net/mdeditor/101021023)[深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第二节 栈基本工作原理](https://mp.csdn.n…...
Maven的使用和配置
Maven的使用和配置 起源: Apache 软件基金会(非营业的组织,把一些开源软件维护管理起来) maven 是apache的一个开源项目,是一个优秀的项目构建(管理)工具, maven 管理项目中的jar,以及jar与jar之间的依赖 maven 可…...
MongoDB 数据类型
目录 BSON 类型 二进制数据(Binary Data) ObjectId ObjectId定义 文档中的ObjectId ObjectId的单调性 字符串(String) 时间戳(Timestamps) 日期(Date) BSON类型的排序 数…...
Java 将 List 转换为 String常见方式
将 List 转换为 String的几种方式 使用 List的toString()方法将 List 转换为 String;结果前后会带有英文的中括号[],如:[1, 2, 3, 4, 5]使用Java8 stream流中的Collections.joining()方法,带有逗号分隔符或自定义分隔符将集合转成…...

Redis(认识NoSQL,认识redis,安装redis,redis桌面客户端,redis常见命令,redis的Java客户端)
文章目录 Redis快速入门1.初识Redis1.1.认识NoSQL1.1.1.结构化与非结构化1.1.2.关联和非关联1.1.3.查询方式1.1.4.事务1.1.5.总结 1.2.认识Redis1.3.安装Redis1.3.1.依赖库1.3.2.上传安装包并解压1.3.3.启动1.3.4.默认启动1.3.5.指定配置启动1.3.6.开机自启 1.4.Redis桌面客户端…...

idea 出现Cannot resolve symbol ‘springframework‘解决方法
Maven手动重新加载 1)File–>Invalidate Caches / Restart… 清理缓存,重启idea客户端 2)File–>Maven–>Reload project重新从maven中加载工程依赖的组件...

ubuntu22.04安装anacoda遇到的坑
这几天把用了3年的windows10换成了ubuntu22.04 各种环境都得配置,本文记录下遇到的坑。 1、anacoda在ubuntu上也可以用官方也提供了安装包,但是没有图形界面,需要以命令行的方式安装和运行配置 1.1 安装:官网下载后,…...
window的OPen方法,弹窗的特征
文章目录 一、介绍二、弹窗的特征 一、介绍 window.open() 方法是 JavaScript 中的一个内置方法,用于在浏览器中打开一个新的窗口或标签页。 语法: window.open(url, name, features, replace)二、弹窗的特征 open方法参数说明: 参数说明url要载入窗…...
DFS算法查找所有路径详解
DFS算法查找所有路径详解 算法介绍 深度优先搜索(Depth-First Search,DFS)是一种图遍历算法,它从起始节点开始,沿着一条路径尽可能深入,直到达到最深的节点,然后回溯到前一节点,继…...

单片机的存储、堆栈与程序执行方式
一、单片机存储区域 如图所示位STM32F103ZET6的参数: 单片机的ROM(内部FLASH):512KB,用来存放程序代码的空间。 单片机的RAM:64KB,一般都被分配为堆、栈、变量等的空间。 二、堆和栈的概念 …...
Web3开发成本和主要特性
多年来,技术不断进步,可帮助您的业务领先于竞争对手。如今,您可以看到许多更新和变化,使技术更加先进,对企业更加有用。到现在为止,web1.2和2.0比较流行,但是要知道web 3才是技术之父࿰…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...