本文目录导读:

在Shell脚本中配置容器停止前的清理操作,主要有以下几种方法:
使用 trap 捕获信号
#!/bin/bash
# 定义清理函数
cleanup() {
echo "正在执行清理操作..."
# 删除临时文件
rm -rf /tmp/app_*
# 关闭数据库连接
mysqladmin shutdown
# 清理缓存
sync
echo "清理完成"
}
# 捕获退出信号
trap cleanup EXIT
trap cleanup SIGTERM
trap cleanup SIGINT
trap cleanup SIGQUIT
# 主程序
echo "应用启动..."
# 你的应用代码
while true; do
sleep 1
done
Docker 容器的优雅停止
使用 docker stop 信号
#!/bin/bash
# 清理函数
cleanup() {
echo "收到停止信号,开始清理..."
# 停止后台服务
kill -TERM $child_pid 2>/dev/null
# 等待子进程结束
wait $child_pid
# 清理临时资源
rm -f /var/run/app.pid
rm -rf /tmp/app_data/*
echo "清理完成,容器退出"
exit 0
}
trap cleanup SIGTERM SIGINT
# 启动主进程
/usr/local/bin/app &
child_pid=$!
# 等待子进程
wait
配合 supervisord 或 s6-overlay
#!/bin/bash
# supervisord 退出时的清理脚本
cleanup_script() {
echo "Supervisor 正在停止服务..."
# 停止所有子服务
supervisorctl stop all
# 清理共享内存
ipcrm -a 2>/dev/null
# 清理临时文件
find /tmp -type f -mmin +5 -delete
echo "所有服务已停止并清理"
}
# 注册清理
trap cleanup_script EXIT
# 启动 supervisor
exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
Kubernetes Pod 的 PreStop Hook
在 Deployment 或 Pod 配置中使用:
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: myapp
image: myapp:latest
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- |
echo "PreStop Hook: 开始清理..."
# 清理数据库连接
/usr/bin/mysqladmin -u root shutdown
# 清理缓存
/usr/bin/redis-cli shutdown
# 清理临时文件
rm -rf /tmp/*
echo "PreStop Hook: 清理完成"
完整的实用案例
#!/bin/bash
# ================= 配置 =================
APP_NAME="myapp"
LOG_FILE="/var/log/${APP_NAME}.log"
PID_FILE="/var/run/${APP_NAME}.pid"
TEMP_DIR="/tmp/${APP_NAME}"
# ================= 清理函数 =================
cleanup() {
local exit_code=$?
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 开始清理操作..." >> "$LOG_FILE"
# 1. 保存当前状态
echo "保存应用状态..." >> "$LOG_FILE"
# 2. 停止子进程
if [ -f "$PID_FILE" ]; then
local pid=$(cat "$PID_FILE")
if kill -0 $pid 2>/dev/null; then
echo "停止主进程 (PID: $pid)..." >> "$LOG_FILE"
kill -TERM $pid
wait $pid 2>/dev/null
fi
rm -f "$PID_FILE"
fi
# 3. 清理临时文件
if [ -d "$TEMP_DIR" ]; then
echo "清理临时目录..." >> "$LOG_FILE"
rm -rf "$TEMP_DIR"
fi
# 4. 关闭网络连接
echo "关闭网络连接..." >> "$LOG_FILE"
# 清理端口转发
iptables -w -t nat -D PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80 2>/dev/null
# 5. 清理共享内存和信号量
ipcrm -a 2>/dev/null
# 6. 刷新文件系统缓冲区
sync
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 清理完成,退出代码: $exit_code" >> "$LOG_FILE"
# 退出时清理日志文件句柄
exec 3>&-
exit $exit_code
}
# ================= 信号处理 =================
# 捕获所有退出信号
trap cleanup EXIT
trap cleanup SIGTERM
trap cleanup SIGINT
trap cleanup SIGQUIT
trap cleanup SIGHUP
# ================= 主程序 =================
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ${APP_NAME} 启动..." | tee -a "$LOG_FILE"
# 创建必要的目录
mkdir -p "$TEMP_DIR"
# 启动主应用
/usr/local/bin/${APP_NAME} &
PID=$!
echo $PID > "$PID_FILE"
echo "主进程 PID: $PID" >> "$LOG_FILE"
# 保持容器运行
wait $PID
调试和验证
# 测试清理脚本是否正常工作 docker exec <container_id> /scripts/cleanup.sh # 发送信号测试 docker kill -s SIGTERM <container_id> # 查看日志确认清理执行 docker logs <container_id> --tail 50 # 强制停止测试 docker stop --time=30 <container_id>
注意事项
- 信号转发:确保容器内的进程能正确接收和转发信号
- 超时控制:设置合理的清理超时时间(Docker默认10秒)
- 幂等性:清理操作应该可以多次执行而不会出错
- 日志记录:记录清理操作的详细日志便于调试
- 资源释放:确保所有文件描述符、网络连接等资源都被释放
这样配置后,无论容器是正常退出还是收到停止信号,都能执行预定义的清理操作,确保容器优雅地停止。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播