本文目录导读:

在 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,确保容器在完全启动后才开始接收流量。