本文目录导读:

在Shell脚本中实现容器应用版本回滚,主要有以下几种方法:
基于Docker容器的回滚
使用Docker Compose的回滚脚本
#!/bin/bash
# 回滚脚本 - rollback.sh
# 配置
APP_NAME="myapp"
COMPOSE_FILE="docker-compose.yml"
BACKUP_DIR="./backups"
ROLLBACK_VERSION=$1 # 从命令行参数获取回滚版本
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查参数
if [ -z "$ROLLBACK_VERSION" ]; then
log_error "请指定回滚版本号"
echo "用法: $0 <版本号>"
echo "可用版本:"
ls -1 "$BACKUP_DIR" 2>/dev/null || echo "无可用备份"
exit 1
fi
# 检查备份是否存在
if [ ! -d "${BACKUP_DIR}/${ROLLBACK_VERSION}" ]; then
log_error "版本 ${ROLLBACK_VERSION} 的备份不存在"
exit 1
fi
# 停止当前应用
log_info "停止当前应用..."
docker-compose -f "$COMPOSE_FILE" down || {
log_error "停止应用失败"
exit 1
}
# 恢复备份的配置文件
log_info "恢复版本 ${ROLLBACK_VERSION} 的配置..."
cp -r "${BACKUP_DIR}/${ROLLBACK_VERSION}/." ./
# 重新部署指定版本
log_info "部署版本 ${ROLLBACK_VERSION}..."
docker-compose -f "$COMPOSE_FILE" up -d || {
log_error "部署失败"
exit 1
}
# 健康检查
log_info "执行健康检查..."
sleep 10
if docker-compose -f "$COMPOSE_FILE" ps | grep -q "Up"; then
log_info "回滚成功: 应用已恢复到版本 ${ROLLBACK_VERSION}"
else
log_error "回滚失败: 应用未正常启动"
exit 1
fi
基于Kubernetes的Pod回滚
Kubernetes回滚脚本
#!/bin/bash
# Kubernetes回滚脚本 - k8s_rollback.sh
# 配置
NAMESPACE="production"
DEPLOYMENT_NAME="myapp-deployment"
ROLLBACK_REVISION=$1
# 颜色输出
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
# 检查kubectl是否安装
check_kubectl() {
if ! command -v kubectl &> /dev/null; then
log_error "kubectl未安装"
exit 1
fi
}
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# 获取部署历史
list_revisions() {
log_info "可用的回滚版本:"
kubectl rollout history deployment/"${DEPLOYMENT_NAME}" -n "${NAMESPACE}"
}
# 执行回滚
rollback_deployment() {
local revision=$1
if [ -z "$revision" ]; then
log_warn "未指定版本,回滚到上一个版本"
kubectl rollout undo deployment/"${DEPLOYMENT_NAME}" -n "${NAMESPACE}"
else
log_info "回滚到版本: ${revision}"
kubectl rollout undo deployment/"${DEPLOYMENT_NAME}" \
-n "${NAMESPACE}" \
--to-revision="${revision}"
fi
# 监控回滚状态
log_info "监控回滚状态..."
kubectl rollout status deployment/"${DEPLOYMENT_NAME}" \
-n "${NAMESPACE}" \
--timeout=120s
}
# 主函数
main() {
check_kubectl
# 如果不带参数,显示版本列表
if [ $# -eq 0 ]; then
list_revisions
echo ""
read -p "请输入要回滚到的版本号: " revision
rollback_deployment "$revision"
else
rollback_deployment "$ROLLBACK_REVISION"
fi
# 验证回滚结果
log_info "当前运行版本:"
kubectl get deployment "${DEPLOYMENT_NAME}" \
-n "${NAMESPACE}" \
-o jsonpath='{.spec.template.metadata.labels.version}'
}
main "$@"
多版本管理回滚脚本
#!/bin/bash
# 多版本管理回滚 - multi_version_rollback.sh
# 配置
APP_NAME="myapp"
IMAGE_REGISTRY="registry.example.com"
CURRENT_VERSION_FILE="/var/lib/${APP_NAME}/current_version"
BACKUP_DIR="/var/backups/${APP_NAME}"
COMPOSE_FILE="/opt/${APP_NAME}/docker-compose.yml"
# 初始化
init() {
mkdir -p "${BACKUP_DIR}"
mkdir -p "$(dirname ${CURRENT_VERSION_FILE})"
}
# 记录当前版本
record_version() {
local version=$1
echo "$version" > "$CURRENT_VERSION_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') - 部署版本: $version" >> "${BACKUP_DIR}/deploy_history.log"
}
# 备份当前配置
backup_current_config() {
local version=$(cat "$CURRENT_VERSION_FILE" 2>/dev/null)
if [ -n "$version" ]; then
log_info "备份当前版本 ${version} 的配置..."
tar -czf "${BACKUP_DIR}/config_${version}_$(date +%Y%m%d_%H%M%S).tar.gz" \
-C "$(dirname ${COMPOSE_FILE})" .
fi
}
# 执行回滚
rollback_to_version() {
local target_version=$1
local backup_file="${BACKUP_DIR}/config_${target_version}_*.tar.gz"
# 查找备份文件
local latest_backup=$(ls -t $backup_file 2>/dev/null | head -1)
if [ -z "$latest_backup" ]; then
log_error "未找到版本 ${target_version} 的备份文件"
return 1
fi
# 备份当前版本
backup_current_config
# 停止当前服务
log_info "停止当前服务..."
docker-compose -f "$COMPOSE_FILE" down
# 恢复目标版本配置
log_info "恢复版本 ${target_version} 的配置..."
tar -xzf "$latest_backup" -C "$(dirname ${COMPOSE_FILE})"
# 拉取特定版本镜像
log_info "拉取版本 ${target_version} 的镜像..."
docker pull "${IMAGE_REGISTRY}/${APP_NAME}:${target_version}"
# 启动服务
log_info "启动服务..."
docker-compose -f "$COMPOSE_FILE" up -d
# 等待服务启动
sleep 5
# 健康检查
if curl -s http://localhost:8080/health | grep -q "OK"; then
record_version "$target_version"
log_info "回滚成功!当前版本: ${target_version}"
return 0
else
log_error "回滚失败,启动自动恢复..."
# 自动恢复到上一个版本
docker-compose -f "$COMPOSE_FILE" down
tar -xzf "${BACKUP_DIR}/config_${target_version}_*.tar.gz" -C "$(dirname ${COMPOSE_FILE})"
docker-compose -f "$COMPOSE_FILE" up -d
return 1
fi
}
# 主函数
main() {
local target_version=$1
init
case "${target_version}" in
"list")
echo "可用版本列表:"
ls -1 "${BACKUP_DIR}"/*.tar.gz | while read file; do
basename "$file" | cut -d'_' -f2
done | sort -u
;;
"current")
cat "$CURRENT_VERSION_FILE" 2>/dev/null || echo "无记录"
;;
*)
if [ -z "${target_version}" ]; then
echo "用法: $0 <版本号|list|current>"
exit 1
fi
rollback_to_version "${target_version}"
;;
esac
}
# 日志函数
log_info() { echo -e "\033[0;32m[INFO]\033[0m $1"; }
log_error() { echo -e "\033[0;31m[ERROR]\033[0m $1"; }
main "$@"
API方式回滚(带数据库迁移)
#!/bin/bash
# API版本回滚带数据库迁移 - api_rollback.sh
# 配置
API_ENDPOINT="https://api.example.com"
API_KEY="your-api-key"
SERVICE_NAME="user-service"
DB_MIGRATIONS_DIR="/opt/migrations"
# 回滚函数
rollback_api_version() {
local old_version=$1
local new_version=$2
# 1. 执行数据库迁移回滚
log_info "执行数据库迁移回滚..."
if [ -f "${DB_MIGRATIONS_DIR}/rollback_${old_version}_to_${new_version}.sql" ]; then
mysql -u root -p${DB_PASSWORD} ${DB_NAME} < \
"${DB_MIGRATIONS_DIR}/rollback_${old_version}_to_${new_version}.sql"
fi
# 2. 调用API回滚
log_info "通过API执行服务回滚..."
curl -X POST "${API_ENDPOINT}/api/v1/deploy/rollback" \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"service": "'${SERVICE_NAME}'",
"from_version": "'${old_version}'",
"to_version": "'${new_version}'"
}'
# 3. 验证回滚
sleep 10
local current_version=$(curl -s "${API_ENDPOINT}/api/v1/version" | jq -r '.version')
if [ "$current_version" == "$new_version" ]; then
log_info "API回滚成功"
return 0
else
log_error "API回滚失败"
return 1
fi
}
使用建议
- 版本标记:始终为每个部署版本添加明确的标签或标记
- 备份机制:在更新前备份当前配置和数据
- 灰度回滚:对于生产环境,建议先在小范围内验证
- 自动回滚:如果健康检查失败,自动触发回滚
- 日志记录:记录所有回滚操作,便于审计
选择合适的回滚策略取决于你的部署环境:
- Docker: 使用docker-compose和备份文件
- Kubernetes: 使用kubectl rollout命令
- 自定义: 使用API和多版本管理
脚本应该包含:版本检查、备份、执行回滚、健康验证等关键步骤。