当前位置: 首页 > news >正文

kubernetes的三种探针ReadinessProbe、LivenessProbe和StartupProbe,以及使用示例

前言

k8s中的Pod由容器组成,容器运行的时候可能因为意外情况挂掉。为了保证服务的稳定性,在容器出现问题后能进行重启,k8s提供了3种探针

k8s的三种探针

为了探测容器状态,k8s提供了两个探针: LivenessProbe和ReadinessProbe

  • LivenessProbe 存活性探针, 如果探测失败, 就根据Pod重启策略,判断是否要重启容器。
  • ReadinessProbe 就绪性探针,如果检测失败,将Pod的IP:Port从对应endpoint列表中删除,防止流量转发到不可用Pod上

对于启动非常慢的应用, LivenessProbe和ReadinessProbe可能会一直检测失败,这会导致容器不停地重启。 所以k8s设计了第三种探针StartupProbe解决这个问题

  • StartupProbe探针会阻塞LivenessProbe和ReadinessProbe, 直到满足StartupProbe(Pod完成启动),再启用LivenessProbe和ReadinessProbe

LivenessProbe和ReadinessProbe支持三种探测方法

  • ExecAction 容器中执行指定的命令,退出码为0表示探测成功。
  • HTTPGetAction 通过HTTP GET请求容器,如果HTTP响应码在【200,400),认为容器健康。
  • TCPSocketAction 通过容器的IP地址和端口号执行TCP检查。如果建立TCP链接,则表明容器健康。

可以给探针配置可选字段,用来更精确控制LivenessProbe和ReadinessProbe的行为

  • initialDelaySeconds: 容器启动后等待多少秒后探针才开始工作,默认是0秒
  • periodSeconds: 执行探测的时间间隔,默认为10秒
  • timeoutSeconds: 探针执行检测请求后,等待响应的超时时间,默认为1秒
  • failureThreshold: 探测失败的重试次数,重试一定次数后认为失败。
  • successThreshold: 探针在失败后,被视为成功的最小连续成功数。默认值是 1。 存活和启动探测的这个值必须是 1。最小值是 1。

实例: 添加一个LivenessProbe探针

需求: 给Squid Pod添加一个livenessProbe, 每隔10秒检测一次Squid进程启动状态,如果连续3次检测进程异常, 就重启Pod

首先创建一个Squid Pod, 参考: 【k8s实践】 部署Squid

添加一个ExecAction类型的livenessProbe探针

可以通过squid -k check命令检测Squid进程运行状态,返回0说明正常, 返回非0值说明进程异常。
实例: 定义一个ExecAction类型的livenessProbe, deployment配置如下:

containers:- name: squidlivenessProbe:exec:command: ["squid","-k","check"]initialDelaySeconds: 5periodSeconds: 10failureThreshold: 3

完整的squid-deployment.yaml如下:

apiVersion: apps/v1
kind: Deployment
metadata:name: squidnamespace: squidlabels:name: squid
spec:replicas: 1selector:matchLabels:app: squidtemplate:metadata:labels:app: squidspec:volumes:- name: squid-volumepersistentVolumeClaim:claimName: squid-claimdnsPolicy: ClusterFirstWithHostNethostNetwork: truecontainers:- name: squidimage: squid:2.0imagePullPolicy: IfNotPresentlivenessProbe: # 添加一个ExecAction类型的探针exec:command: ["squid","-k","check"] # 如果Squid进程运行, `squid -k check`返回0; 否则返回非0值initialDelaySeconds: 5periodSeconds: 10failureThreshold: 3resources:limits:memory: "4Gi"volumeMounts:- mountPath: /var/log/squidname: squid-volume

重新部署deployment, 通过kubectl -n squid get deploy squid -o yaml, 确认探针已配置到deployment.

测试
kubectl exec进入容器, 使用squid -k shutdown手动停止Squid。 等30秒左右,可以观察到容器自动退出重启, 并且从日志中能看到健康检测失败结果:

[root@k8s-master ~]# kubectl -n squid exec -it squid-8674587b79-29mq8 -- /bin/bash
[root@k8s-master /]# squid -k shutdown
...
[root@k8s-master /]# squid -k check
2024/12/14 04:53:31| FATAL: failed to open /run/squid.pid: (2) No such file or directoryexception location: File.cc(190) open
[root@k8s-master /]# echo $?
1# 等待半分钟左右, 容器自动退出
[root@k8s-master /]# command terminated with exit code 137
[root@k8s-master ~]## 此时宿主机上查看Pod,发现RESTARTS次数变为1
[root@k8s-master /]# kubectl -n squid get pods  
squid         squid-8674587b79-29mq8                     1/1     Running   1 (45s ago)     11m# 通过`kubectl describe`,可以查到探针检测失败的LOGkubectl -n squid describe pod squid-8674587b79-29mq8 | grep UnhealthyWarning  Unhealthy         2m49s  kubelet            Liveness probe failed: 2024/12/14 04:53:19| FATAL: failed to open /run/squid.pid: (2) No such file or directoryWarning  Unhealthy  2m39s  kubelet  Liveness probe failed: 2024/12/14 04:53:29| FATAL: failed to open /run/squid.pid: (2) No such file or directoryWarning  Unhealthy  2m29s  kubelet  Liveness probe failed: 2024/12/14 04:53:39| FATAL: failed to open /run/squid.pid: (2) No such file or directory

添加一个HttpGet类型的livenessProbe探针

HttpGet探针要求Pod里有一个HTTP的server。 例如:请求http://localhost:5000/healthz 探测Pod健康状态,deployment设置如下

livenessProbe:httpGet:path: /healthzport: 5000initialDelaySeconds: 5periodSeconds: 10failureThreshold: 3

在Pod里写一个HTTP的server, 我这里用的Flask

#!/usr/bin/env python3# logging
import logging
logger = logging.getLogger(__name__)
file_handler = logging.FileHandler('/var/log/squid/agent.log')
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)import subprocess
import traceback# Flask
from flask import Flask, jsonify, request
app = Flask(__name__)@app.route('/healthz', methods=['GET'])
def health_check():retCode = 0try:result = subprocess.run(['/usr/sbin/squid', '-k', 'check'])retCode = result.returncodeif retCode == 0:return (jsonify({'code': 0, 'msg': 'OK'}), 200)except:logger.error("health_check %r", traceback.format_exc())return (jsonify({'code': -1, 'msg': 'Fail', 'msg': 'Service Unavailable'}), 500)return (jsonify({'code': retCode, 'msg': 'Fail'}), 400)if __name__ == '__main__':app.run(host='0.0.0.0', port=5000)

再把脚本做到镜像里,安装python3和pip依赖(flask,requests),重新打包部署

测试

curl localhost:5000/healthz
{"code":0,"msg":"OK"}

参考

[1] Correct use of k8s probe
[2] Configure Liveness, Readiness and Startup Probes

http://www.lryc.cn/news/503771.html

相关文章:

  • 掌握线性回归:从简单模型到多项式模型的综合指南
  • Java:183 基于SSM的高校食堂系统
  • 光谱相机
  • AI绘图:开源Stable Diffusion 3 ComfyUI下载安装方法
  • 一区向量加权算法优化INFO-CNN-SVM卷积神经网络结合支持向量机多特征分类预测
  • AES笔记整理
  • Jmeter 性能压测-Tomcat连接数
  • 基于Vue3的组件封装技巧分享
  • python中r代表什么意思
  • 《量子计算对人工智能发展的深远影响》
  • 12.2【JAVA EXP4]next.js的各种问题,DEBUG,前端补强,前后端交互,springSecurity ,java 配置,h2数据库
  • docker启动一个helloworld(公司内网服务器)
  • 使用 Netty 实现 RPC 通信框架
  • 【机器学习06--贝叶斯分类器】
  • 创建vue3项目步骤以及安装第三方插件步骤【保姆级教程】
  • [146 LRU缓存](https://leetcode.cn/problems/lru-cache/)
  • 【Java Nio Netty】基于TCP的简单Netty自定义协议实现(万字,全篇例子)
  • 【JavaWeb后端学习笔记】Redis常用命令以及Java客户端操作Redis
  • pdb调试器详解
  • 项目15:简易扫雷--- 《跟着小王学Python·新手》
  • Flink CDC实时同步mysql数据
  • 题解 - 自然数无序拆分
  • dfs_bool_void 两种写法感悟
  • MySQL 主从复制与 Binlog 深度解析
  • 大连理工大学《2024年845自动控制原理真题》 (完整版)
  • Java性能调优 - 多线程性能调优
  • 行为树详解(4)——节点参数配置化
  • 计算机网络中的三大交换技术详解与实现
  • 《杨辉三角》
  • ARM学习(35)单元测试框架以及MinGW GCC覆盖率报告