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

从HTTP到K8s探针:彻底搞懂HTTPGet健康检查

一、HTTP 通信的本质是什么?

不管是浏览器访问网站,还是 curl 发请求,甚至是 K8s 的 kubelet 做健康检查,本质上都是客户端给服务端发 HTTP 请求,服务端给客户端返回 HTTP 响应,这两个东西都有固定的格式

1.1 HTTP 请求的完整结构

举个最常见的例子:你要访问容器里的健康检查接口http://127.0.0.1:80/health,你发出去的 HTTP 请求,实际长这样:

# 第一行:请求行,固定格式 GET /health HTTP/1.1 # 接下来的部分:请求头,都是「键: 值」的格式,用来传递额外信息 Host: 127.0.0.1:80 User-Agent: curl/7.68.0 Accept: */* Custom-Header: Awesome # 这里必须有一个空行,用来分隔「请求头」和「请求体」 # 最后是请求体:GET 请求一般没有内容,POST 提交表单的时候才会有

我们逐行拆解,搞懂每一部分的作用:

  • 请求行:这是请求的第一行,告诉服务端最核心的信息

    • GET:请求方法,意思是我要从服务端获取数据,健康检查一般都用 GET 方法。

    • /health:我要访问的服务端的路径,也就是你要调用的接口地址。

    • HTTP/1.1:我们用的 HTTP 协议的版本,目前大部分服务都用这个版本。

  • 请求头:这就是我们常说的请求头,每一行都是一个键值对,用来给服务端传递额外的附加信息,比如:

    • Host:告诉服务端,我要访问的 IP 和端口是什么,用来区分同一个服务器上的不同站点。

    • User-Agent:告诉服务端,我用的是什么客户端,比如是 curl 还是 Chrome 浏览器。

    • Accept:告诉服务端,我能接收什么格式的返回内容,比如是 JSON 还是 HTML。

    • Custom-Header: Awesome:这就是自定义的请求头,是我们额外加给服务端的信息,用来适配服务的特殊要求。

  • 空行:这是 HTTP 协议规定必须有的,用来告诉服务端:「我的请求头已经发完了,接下来如果有内容就是请求体了」,没有这个空行,服务端就没办法正确解析你的请求。

  • 请求体:GET 请求一般不需要带额外的请求数据,所以这里是空的,只有 POST 提交表单、上传文件的时候,才会把要提交的内容放在这里。

1.2 HTTP 响应:状态码到底是什么?

服务端收到你的请求之后,会给你返回一个 HTTP 响应,格式和请求非常像:

# 第一行:响应行 HTTP/1.1 200 OK # 接下来的部分:响应头,也是键值对,给客户端传递额外信息 Date: Mon, 13 Apr 2026 08:00:00 GMT Server: Apache/2.4.41 (Ubuntu) Content-Length: 2 Content-Type: text/plain; charset=utf-8 # 同样的空行,分隔响应头和响应体 # 最后是响应体:服务端返回给你的具体内容 ok

这里最关键的,就是响应行里的状态码

  • 上面例子里的200就是状态码,OK是它的文字描述,用来标记这个请求的处理结果。

  • 状态码是 HTTP 协议里规定好的,有明确的分类,不同的范围代表不同的结果:

状态码范围

含义

常见例子

1xx

临时信息,请求还在处理中

100 Continue(服务端说你继续发剩下的内容)

2xx

请求成功,服务端正常处理了你的请求

200 OK(请求成功)、201 Created(资源创建成功)

3xx

重定向,需要你跳去别的地址访问

301 永久重定向、302 临时重定向

4xx

客户端错误,你发的请求有问题

404 Not Found(你访问的路径不存在)、403 Forbidden(你没权限访问)

5xx

服务端错误,服务端自己出问题了

500 Internal Server Error(服务内部出错了)


二、K8s 的 HTTPGet 探针:它到底在做什么?

搞懂了上面的 HTTP 基础,你再看 HTTPGet 探针,就会发现它的逻辑非常简单:kubelet 做的事情,和你在终端里用 curl 命令发 HTTP 请求,是完全一模一样的

具体来说,它的工作流程是这样的:

  1. 它会先拿到你容器的 IP 地址,然后按照你配置的端口、路径,给容器发一个 HTTP GET 请求,就相当于你在终端里执行了这么一条命令:

    curl http://容器的IP:你配置的端口/你配置的路径

  2. 然后它会等服务端返回响应,拿到响应的状态码。

  3. 最后它做判断:

    1. 如果状态码在200~399之间,就说明请求成功了,服务端正常处理了,那容器就是健康的。

    2. 如果是 4xx 或者 5xx,就说明请求出问题了,那检测就失败了。

这就是 HTTPGet 探针的全部逻辑,没有任何黑科技,本质上就是 kubelet 帮你自动定时 curl 一下你的健康接口而已。


三、自定义请求头:curl 的 - H 和 K8s 的 httpHeaders 是同一个东西

很多人搞不懂的httpHeaders配置,其实也非常好理解:它和你用 curl 的时候加的-H "xxx: xxx"参数,是完全一模一样的东西

举个例子,如果你在 K8s 的探针里这么配置:

livenessProbe: httpGet: path: /health port: 80 httpHeaders: - name: Custom-Header value: Awesome

那 kubelet 发出去的 HTTP 请求,就会自动带上Custom-Header: Awesome这个请求头,就和你在终端里执行下面这条 curl 命令的效果,100% 完全一样

curl -H "Custom-Header: Awesome" http://容器IP:80/health

为什么我们要加自定义请求头?

你可能会问,好好的为什么要加这个东西? 因为有些服务的健康检查接口,做了特殊的限制: 比如有些服务要求,只有带了X-Health-Check: true这个请求头的请求,才能访问健康接口,不然就会返回 403 没权限。 如果你不加这个请求头,kubelet 发的默认请求,就会被服务端拒绝,返回 403,探针就会误以为检测失败,然后把你的容器重启,这就造成了误判。 所以我们就需要配置httpHeaders,把这个要求的请求头加上,让 kubelet 的请求能正常访问健康接口。


四、实战案例:从 404 错误看探针的工作流程

我们用一个实际的测试案例,把上面的所有知识点串起来,你就能彻底搞懂了。

我们做这么一个测试:用 httpd 镜像(一个常用的 Web 服务器),配置存活探针,访问一个不存在的路径/httppage,看看会发生什么。

我们的配置文件

apiVersion: v1 kind: Pod metadata: labels: test: liveness name: liveness-http spec: containers: - name: liveness image: httpd imagePullPolicy: IfNotPresent args: - /bin/sh - -c - while true; do echo ok > /usr/local/apache2/htdocs/index.html; sleep 1; done ports: - containerPort: 80 livenessProbe: httpGet: path: /httppage port: 80 httpHeaders: - name: Custom-Header value: Awesome initialDelaySeconds: 3 periodSeconds: 3 restartPolicy: OnFailure

整个流程的拆解

  1. 容器启动之后,过了 3 秒,kubelet 开始第一次探测。

  2. kubelet 给容器的 80 端口,发了一个 GET 请求,访问/httppage,并且带上了我们配置的Custom-Header: Awesome请求头。

  3. httpd 服务收到请求之后,发现自己根本没有/httppage这个路径,所以它返回了一个 404 的状态码。

  4. kubelet 拿到响应,发现状态码是 404,属于 4xx 的客户端错误,不在 200~399 的成功范围内,所以它判定:探针检测失败了。

  5. 连续几次检测都失败之后,K8s 就把这个容器杀掉,然后重启它。

最后我们看 Pod 的事件,就能看到这个提示:

Warning Unhealthy 9m2s (x9 over 10m) kubelet Liveness probe failed: HTTP probe failed with statuscode: 404

这个提示正好对应了我们上面的整个流程:因为状态码是 404,所以探针失败了。


五、总结

  1. HTTP 请求和响应都有固定的格式,请求头是用来传递附加信息的键值对,状态码是用来标记请求处理结果的。

  2. K8s 的 HTTPGet 探针,本质上就是 kubelet 帮你定时 curl 你的健康接口,和你自己用 curl 发请求没有任何区别。

  3. httpHeaders配置,和 curl 的-H参数是同一个东西,用来给请求加自定义的请求头,适配服务的特殊要求。

  4. 探针会根据响应的状态码判断健康状态,200~399 算成功,4xx、5xx 算失败。

http://www.cnnetsun.cn/news/1876770.html

相关文章:

  • 全网最全:零基础学深度学习需要学哪些框架?PyTorch 和 TensorFlow 选哪个?
  • 告别手写脚本!用Frida-Trace自动Hook Android App的Java方法(附实战Demo)
  • ToClaw真的能让AI Agent落地吗?先看清它的代价与边界
  • Python语言的12个基础知识点小结
  • 基于STM32的智能家居安防系统设计与实现
  • LangChain4j 1.0.0-beta2踩坑记:从社区版DashScope依赖到SpringBoot自动配置的完整避坑指南
  • 扣子(Coze)实战:10万+治愈奶奶图文,Coze一键生成
  • Simulink信号解析避坑指南:为什么你的‘蓝色鱼叉’图标不出现?
  • [Unity] ShaderGraph实战:动态水面倒影与镜面反射效果优化
  • SDXL 1.0电影级绘图工坊:Mathtype公式渲染与科学图表生成
  • SQL如何获取分组最后一条数据_LAST_VALUE的滑动窗口陷阱
  • Kubernetes v1.36 云原生架构新特性详解:生产级集群升级指南
  • devops系列(二) Git 工作流与版本控制:团队协作不踩坑
  • Java 从入门到精通(十五):线程同步与 synchronized,为什么多个线程改同一个变量时结果总会乱?
  • 收藏 | 零基础小白也能看懂:Transformer大模型是如何炼成的
  • HJ175 小红的整数配对
  • 短视频商城APP源码开发:技术、功能与运营全链路解决方案
  • 华为OD机试 - 魔法收积木 - 二进制(Python/JS/C/C++ 新系统 200分)
  • VS Code 插件系统深度剖析
  • SpringCloud微服务进阶-Nacos更加全能的注册中心澈
  • 消息队列Kafka与RabbitMQ深度解析:把分布式消息核心讲透,吊打面试官
  • ASTM D4169视网膜下注射套件的包装运输验证方案
  • 三相UVW的时间分配
  • MT6826S磁编码器:高精度与强抗干扰的工业级解决方案
  • AI Agent岗位面试通过率有多低:真实数据
  • 三维地图可视化 ThreeJS vue 开源项目
  • CV算法工程师成长路线:从入门到面试的25个关键节点
  • AI编程工具对比:Claude Code vs Devin vs Copilot
  • 模型解析 | GPT-3:开启上下文学习的1750亿参数巨兽(上)
  • 从模型装配到参数化:HFSS局部坐标系与面坐标系的进阶实战