k8s的etcd备份脚本

注:在使用脚本前要安装etcdctl工具

#!/bin/bash
set -eo pipefail  # 脚本出错时立即退出,增强容错性

#######################################
# 配置参数(集中管理,便于修改)
#######################################
BACKUP_DIR="/etcd-backup"               # 备份目录
LOG_DIR="/var/log/backup"               # 日志目录
LOG_FILE="${LOG_DIR}/messages"          # 日志文件
RETENTION_DAYS=30                       # 备份保留天数
ETCDCTL_TIMEOUT=300                     # etcdctl超时时间(秒)
# etcd连接参数(根据实际环境调整)
ETCD_ENDPOINTS="https://127.0.0.1:2379"
ETCD_CACERT="/etc/kubernetes/pki/etcd/ca.crt"
ETCD_CERT="/etc/kubernetes/pki/apiserver-etcd-client.crt"
ETCD_KEY="/etc/kubernetes/pki/apiserver-etcd-client.key"
# 显式定义PATH(解决crontab环境变量问题)
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

#######################################
# 开始:脚本使用前准备
#######################################

echo -e "\033[31m注意事项:因为脚本会写到计划任务中,如果脚本路径移动请在移动后重新执行添加新任务\033[0m"

echo "脚本需要在安装etcdctl工具后才可执行"

# 定义函数:检查 etcdctl 是否存在
check_etcdctl() {
    # 使用 command -v 检查命令是否存在,避免别名/函数干扰
    # >/dev/null 2>&1 :屏蔽命令的标准输出和错误输出(仅保留退出码判断)
    if ! command -v etcdctl >/dev/null 2>&1; then
        # 输出错误信息到标准错误流(>&2),避免与正常输出混淆
        echo "错误:未检测到 etcdctl 工具,请先安装或配置环境变量。" >&2
        # 退出脚本,退出码 1 表示执行失败(非 0 均为失败)
        exit 1
    fi
}

# 执行检查(脚本入口:先检查工具,再执行后续逻辑)
check_etcdctl

# ---------------------- 以下是脚本后续业务逻辑(示例)----------------------
echo "成功:etcdctl 工具已存在,开始执行后续操作..."


#######################################
# 第一步:优先创建日志目录和文件
#######################################
if [ ! -d "$LOG_DIR" ]; then
    echo "[$(date +%Y%m%d_%H%M%S)] 日志目录 $LOG_DIR 不存在,正在创建..."
    mkdir -p "$LOG_DIR" || {
        echo "[$(date +%Y%m%d_%H%M%S)] 错误:无法创建日志目录 $LOG_DIR,脚本退出" >&2
        exit 1
    }
    echo "[$(date +%Y%m%d_%H%M%S)] 日志目录 $LOG_DIR 创建成功"
fi

if [ ! -f "$LOG_FILE" ]; then
    echo "[$(date +%Y%m%d_%H%M%S)] 日志文件 $LOG_FILE 不存在,正在创建..."
    touch "$LOG_FILE" || {
        echo "[$(date +%Y%m%d_%H%M%S)] 错误:无法创建日志文件 $LOG_FILE,脚本退出" >&2
        exit 1
    }
    echo "[$(date +%Y%m%d_%H%M%S)] 日志文件 $LOG_FILE 创建成功"
fi


#######################################
# 第二步:定义日志函数
#######################################
log() {
    local timestamp=$(date +%Y%m%d_%H%M%S)
    echo "[$timestamp] $1" | tee -a "$LOG_FILE"
}


#######################################
# 第三步:检查root权限
#######################################
if [ "$(whoami)" != "root" ]; then
    log "错误:必须以root用户运行此脚本!"
    exit 1
fi


#######################################
# 第四步:确保备份目录存在
#######################################
if [ ! -d "$BACKUP_DIR" ]; then
    log "备份目录 $BACKUP_DIR 不存在,正在创建..."
    mkdir -p "$BACKUP_DIR" || {
        log "错误:目录 $BACKUP_DIR 创建失败"
        exit 1
    }
else
    log "备份目录 $BACKUP_DIR 已存在"
fi


#######################################
# 第五步:执行备份
#######################################
BACKUP_FILE="${BACKUP_DIR}/etcd-snapshot-$(date +%Y%m%d_%H%M%S).db"

log "开始执行etcd备份(超时时间:${ETCDCTL_TIMEOUT}秒)..."
if timeout "${ETCDCTL_TIMEOUT}" etcdctl \
    --endpoints="${ETCD_ENDPOINTS}" \
    --cacert="${ETCD_CACERT}" \
    --cert="${ETCD_CERT}" \
    --key="${ETCD_KEY}" \
    snapshot save "${BACKUP_FILE}"; then

    if etcdctl snapshot status "${BACKUP_FILE}" >/dev/null 2>&1; then
        log "备份成功,文件路径:${BACKUP_FILE}(大小:$(du -h "${BACKUP_FILE}" | awk '{print $1}'))"
    else
        log "错误:备份文件 ${BACKUP_FILE} 无效,已删除"
        rm -f "${BACKUP_FILE}"
        exit 1
    fi
else
    log "错误:etcd备份超时或失败(超时时间${ETCDCTL_TIMEOUT}秒)"
    rm -f "${BACKUP_FILE}"
    exit 1
fi


#######################################
# 第六步:清理过期备份 + 检测所有非规范文件(核心修改)
#######################################
log "开始清理${RETENTION_DAYS}天前的备份文件..."
ago=$(date -d "-${RETENTION_DAYS} day" +%Y%m%d)

# 匹配备份目录下所有文件(仅文件,不包括子目录),然后逐个检查
find "$BACKUP_DIR" -maxdepth 1 -type f | while read -r file; do
    # 提取文件名(不含路径)
    filename=$(basename "$file")
    
    # 严格匹配规范格式:etcd-snapshot-YYYYMMDD_HHMMSS.db
    if [[ "$filename" =~ ^etcd-snapshot-[0-9]{8}_[0-9]{6}\.db$ ]]; then
        # 符合规范的文件:提取日期并判断是否过期
        datestamp=$(echo "$filename" | sed -n 's/etcd-snapshot-\([0-9]\{8\}\)_[0-9]\{6\}\.db/\1/p')
        if [ "$datestamp" -lt "$ago" ]; then
            if [ -f "$file" ]; then
                rm -f "$file" && log "已删除过期备份:$file"
            fi
        fi
    else
        # 不符合规范的文件:统一输出警告(包括22222、etcd-snapshot-233.db等)
        log "警告:文件 $file 不符合备份命名规范(需为 etcd-snapshot-YYYYMMDD_HHMMSS.db 格式),未清理"
    fi
done


#######################################
# 第七步:添加计划任务
#######################################
SCRIPT_ABSOLUTE_PATH=$(cd "$(dirname "$0")" && pwd)/$(basename "$0")
CRON_TASK="0 1 * * * export PATH=\"${PATH}\"; ${SCRIPT_ABSOLUTE_PATH}"

if ! crontab -l 2>/dev/null | grep -qxF "$CRON_TASK"; then
    (crontab -l 2>/dev/null; echo "$CRON_TASK") | crontab - && \
    log "计划任务已添加:每天凌晨1点自动执行备份,计划任务内容:$CRON_TASK"
else
    log "计划任务已存在,无需重复添加"
fi


log "备份及清理操作完成"
exit 0

没有工具的情况下执行提示
在这里插入图片描述
有工具的情况下执行
在这里插入图片描述
查看执行结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虚伪的空想家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值