【问题标题】:configuration of readiness probe for my webapp为我的 webapp 配置就绪探针
【发布时间】:2026-01-06 14:30:01
【问题描述】:

我正在 Kubernetes 中运行示例 webapp python。 我无法弄清楚我如何在这里使用探针。

  1. 我希望应用通过自动重启 pod 从损坏状态中恢复

  2. 仅将流量路由到健康的 pod。

  3. 确保数据库在应用程序(在我的例子中是 Redis)之前启动并运行。

我对探针有所了解,但不确定如何/确切地寻找什么值

我的定义文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  labels:
     env: production
     app: frontend
spec:
  selector:
    matchLabels:
      env: production
      app: frontend
  replicas: 1
  template:
    metadata:
      name: myapp-pod 
      labels:
        env: production
        app: frontend
    spec:
      containers:
      - name: myapp-container
        image: myimage:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 5000

现在我正在做这样的事情

        readinessProbe:
          httpGet:
            path: /
            port: 5000
          initialDelaySeconds: 20
          periodSeconds: 5
        livenessProbe:
        httpGet:
          path: /
          port: 5000
        intialDelaySeconds: 10
        periodSeconds: 5

【问题讨论】:

  • 您是使用 Helm 还是 Kubectl 作为客户端?
  • 因为我正在使用 kubectl 进行此操作,稍后一旦我准备好项目,然后将为整个创建掌舵图
  • 嗨 Waseem,您能否使用建议的方法为您的 python 应用程序和 redis 运行探针?
  • 嗨 Waseem,如果 accepting 回答了您最初的问题,请考虑将其作为答案之一。

标签: kubernetes


【解决方案1】:

您需要同时定义两者

  • readinessProbe:允许判断您的Deployment 是否准备好在其生命周期的任何时间点为流量提供服务。此配置项可以支持不同的命令,但在您的情况下,这将是您将在 Web 应用程序中实现的 httpGet 匹配和端点(大多数现代堆栈默认定义端点,因此请检查您所使用的任何框架的文档使用)。请注意,端点处理程序需要检查任何所需依赖项的 准备情况,在您的情况下,您需要检查 http[s]://redis-host:redis-port 是否成功响应
  • livenessProbe:允许控制平面持续检查您的 Pod 运行状况,并决定使集群达到所需状态所需的操作,推出任何未能报告处于活动状态的 Pod。这个探针也支持不同的定义,对于readinessProbe,大多数现代框架都默认提供响应此类请求的端点

您可以在下面看到两个探针的示例,您的 Web 应用程序中有两个相应的 HTTP 端点:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  labels:
     env: production
     app: frontend
spec:
  selector:
    matchLabels:
      env: production
      app: frontend
  replicas: 1
  template:
    metadata:
      name: myapp-pod 
      labels:
        env: production
        app: frontend
    spec:
      containers:
      - name: myapp-container
        image: myimage:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 5000
      readinessProbe:
        httpGet:
          path: /health
          port: 5000
      livenessProbe:
        httpGet:
          path: /health
          port: 5000

【讨论】:

  • 这会按原样工作还是我会对其进行更改?
  • 我在使用这个探针时遇到了这个错误Warning Unhealthy 0s (x11 over 50s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 404
  • 我忘了说应用程序是在python中的
  • 我在回答中提到,您的应用程序中需要有一个端点(HTTP 路由),在验证数据存储区(redis)启动后,该端点(HTTP 路由)会以成功的(200 OK)HTTP 响应进行响应。
【解决方案2】:

在 Kubernetes 中,您有三种探针:

  • Liveness - 我的应用程序还在运行吗?如果失败,应用程序将重新启动
  • 准备就绪 - 我的应用程序准备好为流量提供服务了吗?如果此操作失败,则当前 pod 不会获得流量(例如通过服务)。
  • 启动(自 1.18 起)- 为需要长时间启动的应用程序引入了这种探针类型。其他两种探测类型在启动探测第一次报告成功后启动。

因此,在您的情况下,您的应用程序应该提供一个探针来检查它是否仍在运行,另一个探针是否可以处理流量(也检查 Redis)。请注意liveness probes may be dangerous - 只能从就绪探测开始。

如果您的应用在 /healthz 下提供运行状况检查(包括 Redis),那么您将定义您的就绪探测。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  labels:
     env: production
     app: frontend
spec:
  selector:
    matchLabels:
      env: production
      app: frontend
  replicas: 1
  template:
    metadata:
      name: myapp-pod 
      labels:
        env: production
        app: frontend
    spec:
      containers:
      - name: myapp-container
        image: myimage:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 5000
        readinessProbe:
          httpGet:
            path: /healthz
            port: 5000
          initialDelaySeconds: 3
          periodSeconds: 3

【讨论】:

  • 我的应用程序是一个非常简单的应用程序,它是基本的 hello world。它不提供/healthz。我还读到 /healthz 已被弃用?
  • 为什么要弃用 /healthz - 这是特定于框架/应用程序的。
  • 如果您没有健康端点,只需使用“/”
【解决方案3】:

众所周知,Kubernetes 中有 Liveness、Readiness 和 Startup Probes。查看官方Kubernetes Documentation page on this topic

Kubelet Node 代理可以使用 3 种不同的方法对正在运行的 Pod 执行这​​些探测:

  • HTTP:Kubelet 探针针对端点(如/health)执行 HTTP GET 请求,如果响应状态介于 200 和 399 之间,则成功
  • 容器命令:Kubelet 探针在正在运行的容器内执行命令。如果退出代码为 0,则探测成功。
  • TCP:Kubelet 探针尝试连接到指定端口上的容器。如果可以建立 TCP 连接,则探测成功。

我正在 Kubernetes 中运行示例 webapp python。我无法弄清楚我如何在这里使用探针。

1。我希望应用程序通过自动重新启动 pod 从损坏的状态中恢复。 2. 仅将流量路由到健康的 Pod。

为此,您应该同时使用就绪和活跃度探针。它们都可以使用相同的探测方法并执行相同的检查,但包含就绪探测将确保 Pod 在探测开始成功之前不会接收流量。

例如,您可以为烧瓶 python 应用添加最小健康端点,如下所示:

@app.route('/health')
def return_ok():
    return 'Ok!', 200

然后像这样指定你的 k8s liveness 和 readiness probe:

...
    spec:
      containers:
      - name: myapp-container
        image: myimage:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 5000
        readinessProbe:                      # extra section for your Deployment 
          httpGet:
            path: /health
            port: 5000
          initialDelaySeconds: 20
          periodSeconds: 5
        livenessProbe:
          httpGet:
            path: /health
            port: 5000
          initialDelaySeconds: 10
          periodSeconds: 5                  # end of the section

如果您愿意,可以定义 liveness probe 命令(替换额外部分):

livenessProbe:
  exec:
    command:
    - cat
    - /tmp/healthy
  initialDelaySeconds: 10
  periodSeconds: 5

为了执行探测,kubelet 在目标容器中执行命令cat /tmp/healthy。如果命令成功,则返回 0,并且 kubelet 认为容器处于活动状态且健康。如果命令返回一个非零值,kubelet 会杀死容器并重新启动它。

另一种选择是定义一个TCP liveness/readiness probe

livenessProbe:
  tcpSocket:
    port: 5000
  initialDelaySeconds: 10
  periodSeconds: 5

这将尝试连接到您的容器的 5000 端口。如果探测成功,Pod 将被标记为就绪。

3。确保数据库在应用程序(在我的例子中是 Redis)之前启动并运行。

为了检查 Redis pod 的运行状况,您可以将 bash 脚本文件放在 Redis pod 中的 /health/ping_liveness_local.sh:

#!/bin/bash
[[ -f $REDIS_PASSWORD_FILE ]] && export REDIS_PASSWORD="$(< "${REDIS_PASSWORD_FILE}")"
[[ -n "$REDIS_PASSWORD" ]] && export REDISCLI_AUTH="$REDIS_PASSWORD"
response=$(
 timeout -s 3 $1 \
 redis-cli \
  -h localhost \
  -p $REDIS_PORT \
  ping 
)
if [ $? == 124 ]; then
 echo "Timed out"
 exit 1
fi
responseFirstWord=$(echo $response | head -n1 | awk '{print $1;}')
if [ "$response" != "PONG" ] && [ "$responseFirstWord" != "LOADING" ] && [ "$responseFirstWord" != "MASTERDOWN" ]; then
 echo "$response"
 exit 1
fi

将此部分用于您的 redis pod:

livenessProbe:
  exec:
    command: 
    - sh 
    - -c 
    - /health/ping_liveness_local.sh 5
  failureThreshold: 5
  initialDelaySeconds: 20
  periodSeconds: 5
  successThreshold: 1
  timeoutSeconds: 6

如果这看起来太复杂,那么我建议安装Redis packaged by Bitnami。使用 Helm 包管理器很容易将它安装在 Kubernetes 集群上。 Bitnami 的家伙为 Redis 配置了所有需要的 liveness 和 readiness 探针。

关于如何确保数据库在您的应用程序之前启动并运行,请查看answer。本方案使用K8sInit Containers

【讨论】: