Shell脚本如何配置容器启动探针

wen 实用脚本 1

本文目录导读:

Shell脚本如何配置容器启动探针

  1. 基础探针脚本结构
  2. 在 Kubernetes 中配置 Startup Probe
  3. 针对不同应用类型的探针脚本
  4. 最佳实践
  5. 调试探针
  6. 完整示例

在 Shell 脚本中配置容器启动探针(Startup Probe),通常需要实现一个健康检查逻辑,返回退出码 0(成功)或非 0(失败),以下是几种常见场景的配置方法和示例:


基础探针脚本结构

#!/bin/bash
# 启动探针脚本示例
# 返回 0 表示就绪,非 0 表示未就绪
# 检查关键进程是否运行
if pgrep -x "myapp" > /dev/null 2>&1; then
    # 检查应用是否监听指定端口
    if ss -tlnp | grep -q ":8080"; then
        exit 0  # 成功
    fi
fi
exit 1  # 失败

在 Kubernetes 中配置 Startup Probe

1 使用 exec 探针(推荐用于 Shell 脚本)

apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
  - name: myapp
    image: myapp:latest
    startupProbe:
      exec:
        command:
        - /bin/sh
        - -c
        - |
          # 等待数据库就绪
          until nc -z db-service 5432; do
            echo "Waiting for database..."
            sleep 2
          done
          # 检查应用进程
          if pgrep -x "myapp" > /dev/null 2>&1; then
            exit 0
          fi
          exit 1
      initialDelaySeconds: 10   # 初始延迟
      periodSeconds: 5          # 探测间隔
      timeoutSeconds: 3         # 超时时间
      failureThreshold: 30      # 最大失败次数(30*5=150秒等待)

2 更复杂的探针脚本示例

将探针逻辑写在独立的脚本文件中,并在 Dockerfile 中打包:

probe.sh:

#!/bin/bash
set -e
# 应用健康检查函数
check_health() {
    local app_port="${APP_PORT:-8080}"
    local health_url="http://localhost:${app_port}/health"
    # 方法1:检查端口
    if ! ss -tlnp | grep -q ":${app_port}"; then
        echo "Port ${app_port} not listening"
        return 1
    fi
    # 方法2:发送HTTP请求(如果有curl)
    if command -v curl &> /dev/null; then
        if ! curl -sf "${health_url}" > /dev/null 2>&1; then
            echo "Health endpoint not responding"
            return 1
        fi
    fi
    # 方法3:检查进程
    local required_processes=("myapp" "nginx" "redis")
    for proc in "${required_processes[@]}"; do
        if ! pgrep -x "$proc" > /dev/null 2>&1; then
            echo "Process $proc not running"
            return 1
        fi
    done
    return 0
}
# 执行检查
check_health
exit $?

Dockerfile:

FROM alpine:latest
COPY probe.sh /usr/local/bin/probe.sh
RUN chmod +x /usr/local/bin/probe.sh
CMD ["myapp"]

Kubernetes 配置:

startupProbe:
  exec:
    command:
    - /usr/local/bin/probe.sh
  initialDelaySeconds: 5
  periodSeconds: 10
  failureThreshold: 20

针对不同应用类型的探针脚本

1 Web 应用(等待端口+HTTP响应)

#!/bin/bash
PORT=3000
TIMEOUT=30
URL="http://localhost:${PORT}/api/health"
# 等待端口
for i in $(seq 1 $TIMEOUT); do
    if nc -z localhost $PORT; then
        echo "Port $PORT is ready"
        break
    fi
    sleep 1
done
# 检查HTTP响应
if curl -sf "$URL" -o /dev/null; then
    echo "Health check passed"
    exit 0
else
    echo "Health check failed"
    exit 1
fi

2 数据库服务

#!/bin/bash
# 等待数据库就绪
echo "Checking database connectivity..."
until psql -h localhost -U postgres -c "SELECT 1" > /dev/null 2>&1; do
    echo "Database not ready yet..."
    sleep 2
done
echo "Database is ready"
exit 0

3 消息队列(RabbitMQ)

#!/bin/bash
# 检查RabbitMQ
if rabbitmqctl status > /dev/null 2>&1; then
    echo "RabbitMQ is running"
    exit 0
fi
# 或者检查端口
if ss -tlnp | grep -q ":5672"; then
    echo "RabbitMQ port is listening"
    exit 0
fi
exit 1

最佳实践

1 探针脚本注意事项

#!/bin/bash
set -euo pipefail  # 错误立即退出、使用未定义变量报错、管道错误检测
# 给探针脚本设置超时(防止hang住)
timeout 5 bash -c '
    # 你的检查逻辑
    pgrep myapp && ss -tlnp | grep :8080
' || exit 1
# 支持环境变量配置
PORT=${HEALTH_CHECK_PORT:-8080}

2 不同探针的区别

探针类型 作用 何时停止
Startup Probe 检查应用是否启动完成 成功后不再执行
Liveness Probe 检查应用是否存活 失败则重启容器
Readiness Probe 检查应用是否就绪 失败则从Service移除

3 配置建议

startupProbe:  # 用于慢启动应用(如需要加载大量数据)
  exec:
    command: ["/startup-probe.sh"]
  failureThreshold: 30       # 允许30次失败
  periodSeconds: 10          # 每10秒检查一次
  timeoutSeconds: 5          # 超时5秒
  # 总等待时间:30 * 10 = 300秒
livenessProbe:  # 启动后开始检查
  exec:
    command: ["/liveness-probe.sh"]
  initialDelaySeconds: 15
  periodSeconds: 20
  timeoutSeconds: 3
  failureThreshold: 3
readinessProbe:  # 用于服务发现
  exec:
    command: ["/readiness-probe.sh"]
  initialDelaySeconds: 5
  periodSeconds: 5

调试探针

1 手动测试探针

# 在容器内手动运行探针脚本
kubectl exec -it mypod -- /startup-probe.sh
echo $?  # 查看返回码
# 调试输出
kubectl exec -it mypod -- bash -c "
    set -x
    pgrep -x myapp
    ss -tlnp | grep :8080
"

2 查看探针日志

# 查看探针事件
kubectl describe pod mypod | grep -A 10 -i probe
# 查看容器日志中的探针输出
kubectl logs mypod --previous

完整示例

startup-probe.sh:

#!/bin/bash
set -euo pipefail
APP_NAME="${APP_NAME:-myapp}"
APP_PORT="${APP_PORT:-8080}"
DB_HOST="${DB_HOST:-localhost}"
DB_PORT="${DB_PORT:-5432}"
echo "Starting probe check for $APP_NAME..."
# 1. 检查环境变量是否设置
if [ -z "$APP_NAME" ] || [ -z "$APP_PORT" ]; then
    echo "Required environment variables not set"
    exit 1
fi
# 2. 检查依赖服务(数据库)
echo "Checking database at $DB_HOST:$DB_PORT..."
if ! timeout 5 bash -c "echo > /dev/tcp/$DB_HOST/$DB_PORT" 2>/dev/null; then
    echo "Database not reachable"
    exit 1
fi
# 3. 检查应用进程
if ! pgrep -x "$APP_NAME" > /dev/null 2>&1; then
    echo "Application process not running"
    exit 1
fi
# 4. 检查端口监听
if ! ss -tlnp | grep -q ":$APP_PORT "; then
    echo "Application port $APP_PORT not listening"
    exit 1
fi
echo "All checks passed - application is ready"
exit 0

这个脚本可以用于 Kubernetes 的 startupProbe,确保容器在完全启动后才开始接收流量。

抱歉,评论功能暂时关闭!