下面脚本用于检测指定命名空间下以svc-pod-*开头的Pod日志是否停止更新,并在不更新时重启对应Pod。集群服务如果时间戳一直获取不到,可能是日志中无时间戳、时间戳格式不匹配或日志获取方式问题导致。以下是针对性的排查步骤和优化脚本,帮助解决问题。
- 确认日志中是否包含时间戳
kubectl logs -n namespace svc-pod-xxxxxx --tail=20
优化脚本:兼容无时间戳/时间戳格式不确定场景
#!/bin/bash
# 配置参数
NAMESPACE="namespace"
WAIT_TIME=10 # 检测间隔(秒)
LOG_CMP_LINES=50 # 对比日志的行数(取最后N行对比)
MAX_LOG_AGE=30 # 日志无更新的最大允许时间(秒,仅当有时间戳时生效)
TIMEZONE="Asia/Shanghai" # 服务器时区(与日志时间戳时区一致)
# 临时设置时区(确保date命令按指定时区解析)
export TZ="$TIMEZONE"
# 获取所有符合通配符的Pod名称(svc-pod-*)
pods=$(kubectl get pods -n "$NAMESPACE" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null | tr ' ' '\n' | grep '^svc-pod-')
# 无目标Pod时退出
if [ -z "$pods" ]; then
echo "No pods matching 'svc-pod-*' found in namespace: $NAMESPACE"
exit 0
fi
# 遍历每个Pod检测
for pod in $pods; do
echo "===== Checking pod: $pod ====="
# 检查Pod状态是否为Running(非Running状态跳过)
pod_status=$(kubectl get pod -n "$NAMESPACE" "$pod" -o jsonpath='{.status.phase}' 2>/dev/null)
if [ "$pod_status" != "Running" ]; then
echo "Pod status is $pod_status (not Running), skip."
continue
fi
# --------------------------
# 步骤1:尝试提取日志时间戳(优先)
# --------------------------
log_has_timestamp=false
last_log_line=$(kubectl logs -n "$NAMESPACE" "$pod" --tail=20 2>/dev/null) # 获取最后20行日志(避免缓冲)
if [ -n "$last_log_line" ]; then
# 尝试匹配常见时间戳格式(可根据实际日志调整正则)
# 示例1:[2025-08-21 11:22:12] 或 [2025-08-21T11:22:12+08:00]
timestamp_regex='\[[0-9]{4}-[0-9]{2}-[0-9]{2}(T| )[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?([+-][0-9]{2}:[0-9]{2}|Z)?\]'
# 示例2:08/21/2025 11:22:12
# timestamp_regex='\[[0-9]{2}/[0-9]{2}/[0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2}\]'
# 提取时间戳字符串(取最后一个匹配项)
last_log_time_str=$(echo "$last_log_line" | grep -oE "$timestamp_regex" | tail -n 1 | tr -d '[]')
if [ -n "$last_log_time_str" ]; then
log_has_timestamp=true
# 转换时间戳为秒级(兼容含毫秒/时区的格式)
last_epoch=$(date -d "$(echo "$last_log_time_str" | sed 's/\.[0-9]\+//g; s/[+-][0-9]\{2\}:[0-9]\{2\}//g')" +%s 2>/dev/null)
if [ -z "$last_epoch" ]; then
echo "Warning: Failed to parse timestamp '$last_log_time_str', fallback to content check."
log_has_timestamp=false
else
current_epoch=$(date +%s)
time_diff=$((current_epoch - last_epoch))
echo "Last log timestamp: $last_log_time_str (age: ${time_diff}s)"
fi
fi
fi
# --------------------------
# 步骤2:根据是否获取到时间戳选择检测方式
# --------------------------
if [ "$log_has_timestamp" = true ]; then
# 方式1:基于时间戳检测(日志有时间戳但解析成功)
if [ "$time_diff" -gt "$MAX_LOG_AGE" ]; then
echo "Pod logs not updated for ${time_diff}s (exceed ${MAX_LOG_AGE}s), restart: $pod"
kubectl delete pod -n "$NAMESPACE" "$pod" --grace-period=0 --force
continue
else
echo "Pod logs updated recently (${time_diff}s ago)."
continue
fi
else
# 方式2:基于日志内容变化检测(无时间戳或解析失败)
echo "No valid timestamp found in logs, fallback to content change check."
# 获取初始日志的最后N行(增加--tail避免缓冲)
initial_logs=$(kubectl logs -n "$NAMESPACE" "$pod" --tail="$LOG_CMP_LINES" 2>/dev/null)
if [ -z "$initial_logs" ]; then
echo "Pod has no logs, restart: $pod"
kubectl delete pod -n "$NAMESPACE" "$pod" --grace-period=0 --force
continue
fi
# 等待一段时间(让日志有机会更新)
echo "Waiting $WAIT_TIME seconds for log update..."
sleep "$WAIT_TIME"
# 获取等待后的日志最后N行
current_logs=$(kubectl logs -n "$NAMESPACE" "$pod" --tail="$LOG_CMP_LINES" 2>/dev/null)
if [ -z "$current_logs" ]; then
echo "Pod has no new logs, restart: $pod"
kubectl delete pod -n "$NAMESPACE" "$pod" --grace-period=0 --force
continue
fi
# 对比日志是否有变化(忽略末尾空行)
if [ "$(echo "$initial_logs" | sed '/^$/d')" = "$(echo "$current_logs" | sed '/^$/d')" ]; then
echo "Pod logs not updated (last $LOG_CMP_LINES lines same), restart: $pod"
kubectl delete pod -n "$NAMESPACE" "$pod" --grace-period=0 --force
else
echo "Pod logs updated normally."
fi
fi
done
echo "===== Detection completed ====="
确保执行脚本的环境已配置kubectl且能正常访问Kubernetes集群。
脚本需有足够权限(如cluster-admin或对应角色的get pods、delete pods权限)
使用方式:
- 保存脚本为check_pod_logs.sh。
- 赋予执行权限:chmod +x check_pod_logs.sh。
- 执行脚本:./check_pod_logs.sh。
789

被折叠的 条评论
为什么被折叠?



