K8s探针实战:存活、就绪与启动三重保障

Kubernetes 提供了三种类型的容器探针(Probe)来精细化管理容器的生命周期、就绪状态和启动过程,它们是实现高可用性和服务弹性的关键机制 。下表清晰对比了三种探针的核心目的、工作机制和典型应用场景:

探针类型 核心目的 执行时机与频率 探测失败后的典型行为 典型应用场景
存活探针 (Liveness Probe) 判断容器是否仍在正常运行。如果失败,kubelet 会杀死并重启容器。 容器启动后,按 periodSeconds 持续定期执行。 重启 (Restart) 容器。 检测应用死锁、长时间无响应或内部严重错误,确保异常实例被自动恢复 。
就绪探针 (Readiness Probe) 判断容器是否已准备好接收外部流量。如果失败,从所有关联的 Service 的端点列表中移除该 Pod。 容器启动后,按 periodSeconds 持续定期执行。 将 Pod 标记为 "未就绪",断开其与服务的网络连接,但 不重启 容器。 应用启动慢、需要预热(如加载缓存、连接池初始化)、临时过载或依赖外部服务暂不可用 。
启动探针 (Startup Probe) 判断容器内的应用是否已成功启动。仅在启动阶段使用。 容器启动后立即开始,直到首次成功或 failureThreshold * periodSeconds 超时。 在启动探针成功之前,禁用 存活和就绪探针的执行。若启动探针失败,kubelet 会杀死并重启容器。 管理启动非常缓慢的旧有应用或特定中间件,为其争取足够的启动时间,避免被存活探针误杀 。

这三种探针是 Pod 生命周期管理的重要组成部分,它们共同协作确保了服务从启动到运行再到终止的整个过程都处于受控状态 。

三种探活方式(探测处理器)

每种探针都可以通过三种不同的"探活方式"(即 handler)来执行具体的健康检查逻辑 。

  1. HTTP GET 探针

通过向容器内指定的 IP 地址、端口和路径发送 HTTP GET 请求进行探测。返回的 HTTP 状态码在 200 到 399 之间视为成功,其他状态码或连接失败视为失败 。

yaml 复制代码
# 示例:一个使用 HTTP GET 的存活探针配置
apiVersion: v1
kind: Pod
metadata:
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/liveness
    ports:
    - containerPort: 8080
    livenessProbe: # 定义存活探针
      httpGet: # 使用 HTTP GET 方式
        path: /healthz # 健康检查的路径
        port: 8080 # 容器内监听的端口
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3 # 容器启动后等待3秒开始第一次探测
      periodSeconds: 3 # 每隔3秒执行一次探测
      timeoutSeconds: 1 # 探测超时时间设置为1秒
      failureThreshold: 3 # 连续失败3次后判定为最终失败

此方式适用于任何提供 HTTP 服务的应用,是最常见和便捷的探测方式 。

  1. TCP Socket 探针

通过尝试与容器指定的端口建立 TCP 连接来进行探测。如果能够成功建立连接,则视为成功;连接失败则视为失败 。

yaml 复制代码
# 示例:一个使用 TCP Socket 的就绪探针配置
apiVersion: v1
kind: Pod
metadata:
  name: readiness-tcp
spec:
  containers:
  - name: myapp
    image: myapp:latest
    readinessProbe: # 定义就绪探针
      tcpSocket: # 使用 TCP Socket 方式
        port: 3306 # 尝试连接容器的 3306 端口(例如数据库)
      initialDelaySeconds: 5
      periodSeconds: 10
      failureThreshold: 2

这种方式适用于不提供 HTTP 服务但开放了网络端口的应用,如数据库、缓存或自定义的 TCP 服务 。

  1. Exec 探针

通过在容器内执行一个自定义的命令来进行探测。如果命令的退出状态码为 0,则视为成功;非 0 则视为失败 。

yaml 复制代码
# 示例:一个使用 Exec 的存活探针配置,检查特定文件是否存在
apiVersion: v1
kind: Pod
metadata:
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe: # 定义存活探针
      exec: # 使用 Exec 方式
        command: # 在容器内执行的命令列表
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

这种方式最为灵活,可以执行任何脚本或命令来检查应用内部状态,例如检查特定进程是否存在、日志文件内容或磁盘空间等 。

相关面试问题详解

以下是围绕 Kubernetes 探针的几个典型面试问题及其解答思路。

1. 问题:Kubernetes 中存活探针 (Liveness Probe) 和就绪探针 (Readiness Probe) 的主要区别是什么?在什么场景下应该使用哪一种?

  • 核心区别 :主要在于探测失败后的处理动作。存活探针失败会导致 容器被重启 ,旨在恢复故障实例。就绪探针失败会导致 Pod 被 从 Service 的流量负载均衡池中移除,旨在防止流量被导向尚未准备好或暂时无法服务的实例 。
  • 场景举例
    • 使用存活探针 :一个 Web 服务器因内存泄漏逐渐僵死,不再响应任何请求。存活探针(例如对 /health 的 HTTP 检查)持续失败后,kubelet 会重启该容器,尝试恢复服务 。
    • 使用就绪探针:一个应用启动后需要 30 秒来从数据库加载配置或建立连接池。在此期间,就绪探针会失败,Kubernetes 不会将外部请求路由给它。待加载完成后,就绪探针成功,Pod 才被加入服务端点 。

2. 问题:启动探针 (Startup Probe) 解决了什么问题?它与存活探针的关系是什么?

  • 解决问题 :启动探针专门解决 启动缓慢 的应用的痛点。对于这类应用,如果配置了存活探针且初始延迟 (initialDelaySeconds) 设置较短,应用可能在完成启动前就被存活探针判定为失败并被重启,陷入"启动 -> 被杀死 -> 重启"的循环 。
  • 与存活探针的关系 :启动探针在容器启动期间临时"接管"健康检查。在启动探针首次成功之前,存活探针和就绪探针都不会生效 。这为慢启动应用提供了一个受保护的启动窗口。一旦启动探针成功,其使命完成,后续的健康检查将完全交由存活探针和就绪探针负责。如果启动探针一直失败(超过 failureThreshold),容器同样会被重启 。

3. 问题:如何为一个刚部署的、启动需要2分钟的 Java 应用配置探针,以确保它不会在启动过程中被误杀,并且只有在完全就绪后才接收流量?

这是一个综合应用三种探针的典型场景。

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: slow-java-app
spec:
  template:
    spec:
      containers:
      - name: app
        image: my-java-app:latest
        ports:
        - containerPort: 8080
        startupProbe: # 启动探针:给予足够的启动时间
          httpGet:
            path: /actuator/health
            port: 8080
          failureThreshold: 30 # 尝试30次
          periodSeconds: 5 # 每5秒一次,总共提供 30*5=150秒 (>2分钟) 的启动时间
        livenessProbe: # 存活探针:应用启动后检查其是否存活
          httpGet:
            path: /actuator/health
            port: 8080
          initialDelaySeconds: 150 # 等待启动探针成功后再开始(约2分半后)
          periodSeconds: 10
          failureThreshold: 3
        readinessProbe: # 就绪探针:检查应用是否准备好服务(可不同于存活检查接口)
          httpGet:
            path: /actuator/ready # 可能是一个更严格的就绪检查端点
            port: 8080
          initialDelaySeconds: 150
          periodSeconds: 5
          failureThreshold: 1

配置思路 :使用 startupProbe 保护长达 2.5 分钟的启动期。livenessProbereadinessProbeinitialDelaySeconds 至少设置为启动探针的最大可能耗时(failureThreshold * periodSeconds),确保它们只在应用启动完成后才开始工作。readinessProbe 的检查可以更严格(如检查依赖的外部服务),确保流量只在应用完全就绪后才进入 。

4. 问题:探针配置中的 initialDelaySecondsperiodSecondstimeoutSecondsfailureThreshold 这几个参数分别代表什么意义?

  • initialDelaySeconds:容器启动后,等待多少秒才开始执行第一次探测。对于启动慢的应用至关重要 。
  • periodSeconds:执行两次连续探测之间的间隔秒数,即探测频率 。
  • timeoutSeconds:单次探测执行的超时时间。超过此时间未返回结果,本次探测即被视为失败 。
  • failureThreshold:当探测连续失败多少次后,Kubernetes 才会最终判定探测失败(对于存活探针意味着重启,对于就绪探针意味着标记未就绪)。这个参数提供了对瞬时故障的容忍度 。

参考来源

相关推荐
恋红尘2 小时前
K8S 配置与调度-叩丁狼
云原生·容器·kubernetes
掘根3 小时前
【微服务即时通讯】用户管理子服务1
微服务·云原生·架构
恋红尘3 小时前
K8S Pod 基础解析-分篇-叩丁狼
云原生·容器·kubernetes·pod
阿里云云原生3 小时前
极速导入,便捷无忧!LoongCollector 一次性文件采集能力上线
云原生
丘桔4 小时前
k8s01:容器运行时之争
云原生·容器·kubernetes
2401_891655814 小时前
开源项目吐槽大会技术文章大纲
数据库·云原生
步步为营DotNet4 小时前
#.NET Aspire在云原生应用部署与管理中的深度实践
云原生·.net
掘根6 小时前
【微服务即时通讯】用户管理子服务2
微服务·云原生·架构
一直都在5726 小时前
K8s详解
云原生·容器·kubernetes