探究kubernetes 探针参数periodSeconds和timeoutSeconds
探究kubernetes 探针参数 periodSeconds和timeoutSeconds
问题起源
kubernetes probes的配置中有两个容易混淆的参数,periodSeconds和timeoutSeconds,其配置方式如下:
apiVersion: v1
kind: Pod
metadata:
name: darwin-app
spec:
containers:
- name: darwin-container
image: darwin-image
livenessProbe:
httpGet:
path: /darwin-path
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
官方对这两个参数的解释如下:
periodSeconds: How often (in seconds) to perform the probe. Default to 10 seconds. The minimum value is 1.timeoutSeconds: Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1.
意思是说periodSeconds表示执行探针的周期,而timeoutSeconds表示执行探针的超时时间。
网上有不少针对这两个参数的讨论(如下),其中涉及到一个问题,如果timeoutSeconds > periodSeconds 会怎么样?
其中在上面的第3篇中对timeoutSeconds>periodSeconds的情况有如下描述,即在这种情况下,如果探针超时,则探针周期等于timeoutSeconds。那么这种说法是否正确呢?
If you had the opposite (
timeoutSeconds=10,periodSeconds=5), then the probes would look as follows:0s: liveness probe initiated
10s: liveness probe times out
10s: liveness probe initiated again
源码探究
鉴于网上众说纷纭,我们通过源码来一探究竟。
kubernetes的探针机制是由kubelet执行的,目前支持exec、grpc、httpGet、tcpSocket这4种探针方式。
探针的代码逻辑并不复杂,以v1.30.2的代码为例,其入口函数如下,可以看到它会启动一个周期为w.spec.PeriodSeconds(即探针中定义的periodSeconds)定时器,周期性地执行探针。
// run periodically probes the container.
func (w *worker) run() {
ctx := context.Background()
probeTickerPeriod := time.Duration(w.spec.PeriodSeconds) * time.Second
...
probeTicker := time.NewTicker(probeTickerPeriod)
...
probeLoop:
for w.doProbe(ctx) {
// Wait for next probe tick.
select {
case <-w.stopCh:
break probeLoop
case <-probeTicker.C:
case <-w.manualTriggerCh:
// continue
}
}
}
现在已经找到periodSeconds的用途,下一步需要找到timeoutSeconds。
首先进入
doProbe函数,它调用了w.probeManager.prober.probe:// doProbe probes the container once and records the result.
// Returns whether the worker should continue.
func (w *worker) doProbe(ctx context.Context) (keepGoing bool) {
...
// Note, exec probe does NOT have access to pod environment variables or downward API
result, err := w.probeManager.prober.probe(ctx, w.probeType, w.pod, status, w.container, w.containerID)
if err != nil {
// Prober error, throw away the result.
return true
}
...
}
下面的
probe函数用于执行一个特定的探针。需要注意的是,它调用了pb.runProbeWithRetries,其中maxProbeRetries值为3,说明在一个周期(periodSeconds)中最多可以执行3次探针命令:// probe probes the container.
func (pb *prober) probe(ctx context.Context, probeType probeType, pod *v1.Pod, status v1.PodStatus, container v1.Container, containerID kubecontainer.ContainerID) (results.Result, error) {
var probeSpec *v1.Probe
switch probeType {
case readiness:
probeSpec = container.ReadinessProbe
case liveness:
probeSpec = container.LivenessProbe
case startup:
probeSpec = container.StartupProbe
default:
return results.Failure, fmt.Errorf("unknown probe type: %q", probeType)
}
...
result, output, err := pb.runProbeWithRetries(ctx, probeType, probeSpec, pod, status, container, containerID, maxProbeRetries)
...
}
runProbeWithRetries的注释说明,可能会执行多次探针,直到探针返回成功或全部尝试失败:// runProbeWithRetries tries to probe the container in a finite loop, it returns the last result
// if it never succeeds.
func (pb *prober) runProbeWithRetries(ctx context.Context, probeType probeType, p *v1.Probe, pod *v1.Pod, status v1.PodStatus, container v1.Container, containerID kubecontainer.ContainerID, retries int) (probe.Result, string, error) {
...
for i := 0; i < retries; i++ {
result, output, err = pb.runProbe(ctx, probeType, p, pod, status, container, containerID)
...
}
...
}
在
runProbe函数中,最终找到了timeoutSeconds对应的参数p.TimeoutSeconds,其作为各个探针命令的超时参数,如在httpGet类型的探针中,它作为了httpClient的请求超时时间:
func (pb *prober) runProbe(ctx context.Context, probeType probeType, p *v1.Probe, pod *v1.Pod, status v1.PodStatus, container v1.Container, containerID kubecontainer.ContainerID) (probe.Result, string, error) { timeout := time.Duration(p.TimeoutSeconds) * time.Second if p.Exec != nil {
command := kubecontainer.ExpandContainerCommandOnlyStatic(p.Exec.Command, container.Env)
return pb.exec.Probe(pb.newExecInContainer(ctx, container, containerID, command, timeout))
} if p.HTTPGet != nil {
req, err := httpprobe.NewRequestForHTTPGetAction(p.HTTPGet, &container, status.PodIP, "probe")
...
return pb.http.Probe(req, timeout)
} if p.TCPSocket != nil {
port, err := probe.ResolveContainerPort(p.TCPSocket.Port, &container)
...
host := p.TCPSocket.Host
if host == "" {
host = status.PodIP
}
return pb.tcp.Probe(host, port, timeout)
} if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.GRPCContainerProbe) && p.GRPC != nil {
host := status.PodIP
service := ""
if p.GRPC.Service != nil {
service = *p.GRPC.Service
}
return pb.grpc.Probe(host, service, int(p.GRPC.Port), timeout)
}
...
}
至此我们可以拼接出periodSeconds和timeoutSeconds的关系,其逻辑关系与如下代码类似。
probeTicker := time.NewTicker(periodSeconds)
for {
select {
case <-probeTicker.C:
for i := 0; i < 3; i++ {
if ok:=probe(timeoutSeconds);ok{
return
}
}
}
总结
periodSeconds用于启动一个周期性调用探针命令的定时器,而timeoutSeconds作为探针命令的超时参数timeoutSeconds和periodSeconds之间并没有明确的关系。如果timeoutSeconds=10s,periodSeconds=5s,则本次探针周期可能为[5s, 30s)之内的任意值,并不是该文中说的periodSeconds=timeoutSeconds(由于本文写于3年前,经查阅v1.19.10版本代码,逻辑上与现有版本代码相同。)- 由于健康检查的逻辑大部分都不会很复杂,如检查某个文件是否存在,检查服务的
/hleathzhttp endpoint是否可以访问等,因此建议将timeoutSeconds设置为一个小于periodSeconds的合理的值。
failureThreshold/successThreshold和maxProbeRetries的关系
maxProbeRetries用于定义一次探针周期内探针命令执行的最大尝试次数;- 如果在一个探针周期内,探针命令返回成功,则
successThreshold加1,反之failureThreshold加1;
探究kubernetes 探针参数periodSeconds和timeoutSeconds的更多相关文章
- Kubernetes探针原理详解
前言: 分布式系统和微服务体系结构的挑战之一是自动检测不正常的应用程序,并将请求(request)重新路由到其他可用系统,恢复损坏的组件.健康检查是应对该挑战的一种可靠方法.使用 Kubernetes ...
- Python装饰器探究——装饰器参数
Table of Contents 1. 探究装饰器参数 1.1. 编写传参的装饰器 1.2. 理解传参的装饰器 1.3. 传参和不传参的兼容 2. 参考资料 探究装饰器参数 编写传参的装饰器 通常我 ...
- Kubernetes探针踩坑记
1. 荒腔走板 最近一两个月生产K8s集群频繁出现短时503 Service Temporarily Unavailable,还不能主动复现,相当郁闷,压力山大. HTTP 5xx响应状态码用于定义服 ...
- 【七】Kubernetes 探针介绍 - 存活、就绪探针案例测试
一.探针概述 探针是有 kubelet 对容器执行的定期诊断,并不是由 Master 节点发起的探测,而是由每一个 Node 所在的 kubelet 进行探测,这样可以减轻 Master 节点系统负载 ...
- kubernetes容器探针检测
系列目录 kubernetes提供了livenessProbe(可用性探针)和readinessProbe(就绪性探针)对容器的健康性进行检测,当然这仅仅简单的关于可用性方面的探测,实际上我们不仅仅要 ...
- Kubernetes 存活、就绪探针
在设计关键任务.高可用应用程序时,弹性是要考虑的最重要因素之一. 当应用程序可以快速从故障中恢复时,它便具有弹性. 云原生应用程序通常设计为使用微服务架构,其中每个组件都位于容器中.为了确保Kuber ...
- 探针配置失误,线上容器应用异常死锁后,kubernetes集群未及时响应自愈重启容器?
探针配置失误,线上容器应用异常死锁后,kubernetes集群未及时响应自愈重启容器? 探针配置失误,线上容器应用异常死锁后,kubernetes集群未及时响应自愈重启容器? 线上多个服务应用陷入了死 ...
- Kubernetes YAML 文件全字段详解
Kubernetes YAML 文件全字段详解 Deployment yaml 其中主要参数都在podTemplate 中,DaemonSet StatefulSet 中的pod部分一样. apiVe ...
- Kubernetes学习笔记_尚硅谷
https://www.bilibili.com/video/BV1w4411y7Go?p=1 一.K8s介绍 k8s是一个编排容器的工具,其实也是管理应用的全生命周期的一个工具,从创建应用,应用的部 ...
- Kubernetes Deployment 最佳实践
零.示例 首先给出一个 Deployment+HPA+ PodDisruptionBudget 的完整 demo,后面再详细介绍其中的每一个部分: apiVersion: apps/v1 kind: ...
随机推荐
- 解析 ABP vNext 依赖注入实现【属性注入】的原理
前言 这几天闲来没事看看ABP vNext的文档和源码,关于关于依赖注入(属性注入)这块儿产生了兴趣. 我们都知道.Volo.ABP 依赖注入容器使用了第三方组件Autofac实现的.有三种注入方式, ...
- SpringCloud解决feign调用token丢失问题
背景讨论 feign请求 在微服务环境中,完成一个http请求,经常需要调用其他好几个服务才可以完成其功能,这种情况非常普遍,无法避免.那么就需要服务之间的通过feignClient发起请求,获取需要 ...
- python ddddocr图片验证码详解
安装 下载地址:https://pypi.tuna.tsinghua.edu.cn/simple/ddddocr/ 安装命令: pip install D:\ChromeCoreDownloads\d ...
- Pytorch:使用Tensorboard记录训练状态
我们知道TensorBoard是Tensorflow中的一个强大的可视化工具,它可以让我们非常方便地记录训练loss波动情况.如果我们是其它深度学习框架用户(如Pytorch),而想使用TensorB ...
- uniapp-vue3-oadmin手机后台实例|vite5.x+uniapp多端仿ios管理系统
原创vue3+uniapp+uni-ui跨端仿ios桌面后台OA管理模板Uni-Vue3-WeOS. uniapp-vue3-os一款基于uni-app+vite5.x+pinia等技术开发的仿ios ...
- ICESat-2 从ATL08中获取ATL03分类结果
ICESat-2 ATL03数据和ATL08数据的分段距离不一致,ATL08在ATL03的基础上重新分段,并对分段内的数据做处理得到一系列的结果,详情见数据字典: ATL08 Product Data ...
- EL表达式与JSTL简单入门
更多博文请关注:听到微笑的博客 EL概述 EL(Express Lanuage)表达式可以嵌入在jsp页面内部,减少jsp脚本的编写,EL出现的目的是要替代jsp页面中脚本的编写. 简单来说EL表达式 ...
- c#获取开机时间
public static DateTime OpenCom() { TimeSpan t = TimeSpan.FromMilliseconds(System.Environment.TickCou ...
- 7.20考试总结(NOIP模拟21)[Median·Game·Park]
雨滴降落的速度是每秒十米,我该用怎么样的速度,才能将你挽留? 前言 关于语文素养如何限制OI水平2,正好现在文化课巨佬们正在考语文(那我走???) T1 我以为整数是不用输出 .0 的,然后喜挂 30 ...
- MYSQL 移机重装步骤(windows11)
MYSQL 移机重装步骤(windows11) 目的:已有电脑 A,D盘安装有mysql(安装方式为免安装) , 准备在另一台电脑B上,复制安装电脑A上的mysql(8.0.23版本) . 要 ...