K8s Liveness/Readiness/Startup 探针机制

2023-11-18

k8s-cert

官方参考文档



前言

玩过 Docker Swarm 的应该都知道,有一种功能叫自愈功能,当集群检测到节点或服务故障时回进行自动故障转移,从而保障业务的可用性。而 K8s 集群相对于其他集群体系,其自愈能力更加强大,这也是 K8s 容器编排引擎的一重要特性。自愈从某种角度上来讲,其实现了以下几几种功能特性:

  • 零停机部署;
  • 避免无效镜像;
  • 实现滚动升级与回退。

K8s 有三种探针,分别是:存活(Liveness)就绪(Readiness)启动(Startup)

  • 存活(Liveness):kubelet 使用存活探针来确定什么时候要重启容器。 例如,存活探针可以探测到应用死锁(应用程序在运行,但是无法继续执行后面的步骤)情况。 重启这种状态下的容器有助于提高应用的可用性,即使其中存在缺陷。

  • 就绪(Readiness):kubelet 使用就绪探针可以知道容器何时准备好接受请求流量。当一个 Pod 内的所有容器都就绪时,才能认为该 Pod 就绪。 这种信号的一个用途就是控制哪个 Pod 作为 Service 的后端。 若 Pod 尚未就绪,会被从 Service 的负载均衡器中剔除。

  • 启动(Startup):kubelet 使用启动探针来了解应用容器何时启动。 如果配置了这类探针,你就可以控制容器在启动成功后再进行存活性和就绪态检查, 确保这些存活、就绪探针不会影响应用的启动。 启动探针可以用于对慢启动容器进行存活性检测,避免它们在启动运行之前就被杀掉。

K8s 探针有三种探测方式,分别是:ExecActionHTTPGetActionTCPSocketAction

注意,这三种探测方式只能同时使用一种,不能两种或三种同时使用。

  • ExecAction:在容器中执行指定的命令,如果执行成功,退出码为0则探测成功。
  • HTTPGetAction:通过容器的IP地址、端口号及路径调用HTTP Get方法,如果响应的状态码大于等于200且小于400,则认为容器健康。
  • TCPSocketAction:通过容器的IP地址和端口号执行TCP检查,如果能够建立TCP连接,则表明容器健康。

探针探测的结果有以下值:

  • Success:表示通过检测。
  • Failure:表示未通过检测。
  • Unknown:表示检测没有正常进行。

一、默认健康检测

1.1 restartPolicy

了解 Docker 的都知道,每个容器启动时都会执行一个进程,该进程由 Dockerfile 的 CMD 或 ENTRYPOINT 指定。如果进程退出或返回状态码为非零时,则认为容器发生故障,这个时候 K8s 就会根据 restartPolicy 重启容器。restartPolicy 有三种重启策略:

  • Always

    Pod 中容器不论如何停止都将自动重启;

  • OnFailure
    Pod 中容器非正常停止会自动重启,正常停止不会重启;

  • Never
    Pod 中容器不论以任何方式停止,都不会自动重启。

K8s 的 restartPolicy 默认为 Always。如果探针超过失败重试的次数,则 Pod 就会根据 restartPolicy 策略进行选择是否重启。

1.2 测试案例

1、创建一个 Pod

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: healthcheck
  name: healthcheck
spec:
  restartPolicy: OnFailure
  containers:
  - name: healthcheck
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 10;exit 1

2、观察 Pod 状态

这个容器启动 10s 后会发生故障,接下来执行 kubectl apply 创建 Pod,Pod Name 为 healthcheck。过几分钟后看看 Pod 的状态:

image-20221222110433382

可看到已经重启了三次,该案例中容器进程返回值为非零,k8s 则认为容器发生故障,需要重启。但可能有些情况下发生了故障进程不退出的现象,如访问 Web 服务器时返回 500 错误代码,这可能是系统负荷较大或资源锁死,此时 httpd 进程并没有异常退出,这种情况下可直接重启容器。而 K8s 的 Liveness 机制刚好能解决此类问题(即出现此类问题会直接 Kill 掉容器并重新启动)。

二、Liveness

Liveness 探针让用户可以自定义判断容器是否健康的条件,如果探测失败,K8s 就会重启容器,如下案例:

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

在这个配置文件中,可以看到 Pod 中只有一个 ContainerperiodSeconds 字段指定了 kubelet 应该每 5 秒执行一次存活探测。 initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 5 秒(即 5 秒后才开始启动探针)。 kubelet 在容器内执行命令 cat /tmp/healthy 来进行探测。 如果命令执行成功并且返回值为 0,kubelet 就会认为这个容器是健康存活的。 如果这个命令返回非 0 值,kubelet 会杀死这个容器并重新启动它。当容器启动时,会执行如下的命令:

/bin/sh -c "touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600"

这个容器生命的前 30 秒,/tmp/healthy 文件是存在的。 所以在这最开始的 30 秒内,执行命令 cat /tmp/healthy 会返回成功代码。 30 秒之后,执行命令 cat /tmp/healthy 就会返回失败代码。

执行 kubectl apply 创建 Pod 。

kubectl apply -f liveness.yml

查看 Pod 启动日志:

kubectl describe pod liveness-exec

前 30s /tmp/healthy 文件是存在的:

image-20221222113744208

35s 后检测到/tmp/healthy 文件已经不存在:

image-20221222114051362

再过十几秒后容器被重启:

image-20221222114308594

三、Readiness

除了可以自定义判断容器是否健康的条件外,用户也可以通过 Readiness 探针告诉 K8s 什么时候可以重启容器实现自愈,Readiness 探针则告诉 K8s 什么时候可以将容器加入到 Service 负载均衡池中,对外提供服务。就绪探针的配置和存活探针的配置相似。 唯一区别就是要使用 readinessProbe 字段,而不是 livenessProbe 字段。

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: readiness
  name: readiness-exec
spec:
  containers:
  - name: liveness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
    readinessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

看看启动日志,与 Liveness 探针类似

kubectl describe pod readiness-exec

image-20221222121220005

Probe 有很多配置字段,可以使用这些字段精确地控制启动、存活和就绪检测的行为:

  • initialDelaySeconds:容器启动后要等待多少秒后才启动启动、存活和就绪探针, 默认是 0 秒,最小值是 0。
  • periodSeconds:执行探测的时间间隔(单位是秒)。默认是 10 秒。最小值是 1。
  • timeoutSeconds:探测的超时后等待多少秒。默认值是 1 秒。最小值是 1。
  • successThreshold:探针在失败后,被视为成功的最小连续成功数。默认值是 1。 存活和启动探测的这个值必须是 1。最小值是 1。
  • failureThreshold:当探测失败时,Kubernetes 的重试次数。 对存活探测而言,放弃就意味着重新启动容器。 对就绪探测而言,放弃意味着 Pod 会被打上未就绪的标签。默认值是 3。最小值是 1。

注意:存活探针 不等待 就绪性探针成功。如果要在执行存活探针之前等待就绪性探针,应该使用 initialDelaySecondsstartupProbe

四、Startup

Startup 是 k8s 1.16+ 版本后新加的探测方式,用于判断容器内应用程序是否已经启动,如果同时配置了 startuprobeLivenessprobeReadinessprobe,K8s 就会先禁用其他的探针,而首先使用 startuprobe 探测直到它成功为止,成功后将不再进行探测。

startupProbe 探针与另两种区别?

  • 如果三个探针同时存在,先执行startupProbe探针,其他两个探针将会被暂时禁用,直到pod满足startupProbe探针配置的条件,其他2个探针启动,如果不满足按照规则重启容器。

  • 另外两种探针在容器启动后,会按照配置,直到容器消亡才停止探测,而startupProbe探针只是在容器启动后按照配置满足一次后,不在进行后续的探测。

那 Startup 存在的意义又是什么呢?

试想一个问题,如果启动一个服务需要 1 分钟,如果没有 Startup 的情况下,且假设我们配置了 livenessProbe 探针,具体如下:

livenessProbe:
  httpGet:
    path: /test
    prot: 80
failureThreshold: 6
initialDelay:40
periodSeconds: 5

我们设置了失败重试次数为 6,每 5 秒探测一次,加上我们探测前等待的 40 秒,总时间就是:40 + 6 x 5 = 70s,这样 Pod 确实能够启动起来。那问题又来了,如果这个配置用于生产配置上,将会导致我们比较晚的收到服务不可用的情况,也就是说我的服务可能在 5s 时已经不可用,但是由于我们探测机制(有 6 次失败重试的机会),我们在至少 6 x 5 = 30s 才会发现服务不可用的情况,这在生产上一般是不被允许的。那该如何解决类似这样的问题呢?答案是 startupProbe

注意上面这个案例,如果 failureThreshold 设置为 1 或 2,那这个服务是永远起不起来的,因为你把 initialDelay 的时间算上也不足 1 分钟,因为我们说启动至少需要 1 分钟,那超过失败重试次数后,就会根据 Pod 的 restartPolicy 来重启容器。

接着我们引入 startupProbe,继续优化:

livenessProbe:
  httpGet:
    path: /test
    prot: 80
failureThreshold: 1
initialDelay:5
periodSeconds: 5

startupProbe:
  httpGet:
    path: /test
    prot: 80
failureThreshold: 60
initialDelay:5
periodSeconds: 5

前面说了,startupProbe 会在探测成功后停止探测,而其他两种探针则是随着 Pod 的生命周期一直在探测的。因此上面的配置功能就是:K8s 部署服务后会在 5s 后启动 startupProbe,在 5 x 60 = 300s 的时间内只要成功探测到服务则停止探测(否则需接受 Pod 的重启策略进行重启),并启用 livenessProbe 探针,此时livenessProbe 探针就会伴随着 Pod 的生命周期每 5s 检测一次,且我们只设置了 1 次失败重试的机会,这就意味着我们只需要在 1 x 5 = 5s 时间就可以发现服务不可用。因此,你配置了 startupProbe,那其他2种探针如果配置了initialDelaySeconds,建议时间就不要给太长。这就是 Startup 探针存在的意义。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

K8s Liveness/Readiness/Startup 探针机制 的相关文章

随机推荐

  • [588]Grafana安装及简单使用

    简介 Grafana是一个跨平台的开源的度量分析和可视化工具 可以通过将采集的数据查询然后可视化的展示 并及时通知 它主要有以下六大特点 1 展示方式 快速灵活的客户端图表 面板插件有许多不同方式的可视化指标和日志 官方库中具有丰富的仪表盘
  • python中^是什么意思

    是什么意思 输入为 x 3 x x 2 print x 在python中 符号代表按位翻转 输出为 意思就是 按位异或 可以参考如下示例 In 4 2 2 Out 4 0 In 5 1 3 Out 5 2 In 6 333 333 Out
  • 【IEEE 13 节点分配系统中的THD降低】系统的谐波分析给出了各种总线上电流和电压的谐波频谱和THD(Simulink实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Simulink仿真实现 1 概述 IEEE 13 节点分配系统中的THD
  • 安装最新版greenplum6.10时报错:依赖检测失败。(详细解决步骤)

    报错原因 最新版本的greenplum6 10一些内部工具对系统环境的依赖有要求 故直接进行rpm包安装时会报依赖缺失 如果在装服务器系统的时候选则的最小化安装 那么必然会报这个错误 greenplum5及以下版本在安装的时候是不会报这个错
  • 第二周作业

    1 运行脚本可以显示出本机的ip地址 bin bash ifconfig eth0 sed n 2p awk print 2 ifconfig eth0 提取网卡eth0的配置信息 使用 传给sed sed n 2p 输出ifconfig
  • 【nodejs进阶之旅(2)】:使用koa2+mysql 实现列表数据分页

    1 展示效果 分页 2 分页主要字段 分页主要字段包括 pageSize 每页条数 pageNum 第几页 startRow 当前开始页编号 endRow 当前结束页编号 total 总数量 主要是根据前端分页的参数 进行处理后 返回前端正
  • javamail 发送邮件

    转自 http blog csdn net jbgtwang archive 2009 06 11 4259787 aspx 今天学习了一下JavaMail javamail发送邮件确实是一个比较麻烦的问题 为了以后使用方便 自己写了段代码
  • AcWing 1230. K倍区间

    给定一个长度为 N 的数列 A1 A2 AN 如果其中一段连续的子序列 Ai Ai 1 Aj 之和是 K 的倍数 我们就称这个区间 i j 是 K 倍区间 你能求出数列中总共有多少个 K倍区间吗 输入格式 第一行包含两个整数 N 和 K 以
  • 位运算举例

    从一个整数中把从右边开始的4 7位取出来 1 a右移4位 a gt gt 4 2 设置一个低4位为1 其余为全为0的数b 0 lt lt 4 0 000000000 0 0 1111111 1 0 lt lt 4 11111 0000 0
  • CH10-HarmonyOS原子化服务

    文章目录 前言 目标 原子化服务定义 原子化服务特性 原子化服务体验 服务中心 原子化服务流转 原子化服务分享 原子化开发基础 开发总体要求 服务卡片定义 运作机制 卡片提供方主要回调函数 JS卡片语法基础 原子化服务开发进阶 卡片结构目录
  • 实验吧-密码学-奇怪的短信(九键密码)

    短信里的一段密文 335321414374744361715332 一般来说是用手机接收短信的 于是可能是手机上的九键 将密文两个两个分隔开 33 53 21 41 43 74 74 43 61 71 53 32 然后对应着拼音九键来找出对
  • Android开发 关于避免切换主题时免闪屏的几种方式

    Android开发 关于避免切换主题时闪屏的几种方式 在activity中调用setTheme来切换夜间模式的方法可能大家有看过相关的文章了 但是调用setTheme设置的主题后界面并没有变化 这时需要调用activity的recreate
  • RAID 磁盘状态为foreign,怎么变成ready

    我们在关掉电源 插入三块硬盘 打开电源 这时候 首先启动服务器 出现 Press
  • Eclipse重命名Package,出现的四个选项的意思。

    1 update references 更新参考 2 Rename subpackages 重命名子包 3 Update textual occurrences in comments and strings forces preview
  • 51单片机SCT15数码管4321断灭长灭程序

    include
  • 第七章 yaml格式

    一 简单说明 yaml是一个可读性高 用来表达数据序列的格式 YAML 的意思其实是 仍是一种标记语言 但为了强调这种语言以数据做为中心 而不是以标记语言为重点 二 基本语法 缩进时不允许使用Tab键 只允许使用空格缩进的空格 数目不重要
  • 好分数阅卷3.0_网上阅卷系统是什么

    什么是网上阅卷系统 网上阅卷系统简称在线阅卷或阅卷系统 是一套集电子光学扫描技术和计算机网络技术于一体的纸答题卡电子处理的一套软硬件结合的现代计算机系统 系统特点及简介它主要实现了答题卡模板的智能化生产 由计算机自动对考生填写选择题段信息点
  • 追根究底,剖析MFC六大关键技术(1)

    题外话 我并不认为MFC减轻了程序员们的负担 MFC出现的目的虽然似乎是为了让程序员不用懂得太多就可以进行视窗编程 但本人在MFC里徘徊了很久很久 因为那时没有书本详细介绍MFC的原理 毫无收获 可能朋友们会说 怎么一定要了解MFC的具体呢
  • HBuilder X 上传git仓库

    首先安装git插件 HBuilder的左上方点击工具 点击插件安装 gt 安装新插件 gt 下滑找到 git 进行安装 安装easy git源码管理 HBuilder的左上方点击工具 点击插件安装 gt 安装新插件 gt 前往插件市场安装
  • K8s Liveness/Readiness/Startup 探针机制

    官方参考文档 目录 前言 一 默认健康检测 1 1 restartPolicy 1 2 测试案例 二 Liveness 三 Readiness 四 Startup 前言 玩过 Docker Swarm 的应该都知道 有一种功能叫自愈功能 当