脚本怎样定时创建服务器快照

wen 实用脚本 26

本文目录导读:

脚本怎样定时创建服务器快照

  1. 方案一:使用阿里云 CLI(通用性强,推荐)
  2. 方案二:使用 AWS EC2(AWS CLI)
  3. 方案三:使用 Ansible(企业级,复杂环境)
  4. 关键注意事项
  5. 选择建议

针对不同云平台(阿里云、腾讯云、AWS等)和不同环境(Linux/Windows),定时创建服务器快照的脚本通常有以下几种实现方式。

因为你需要的是“脚本”,我假设你使用的是Linux系统,并利用系统的crontab定时任务结合云平台的CLI命令行工具来实现。

以下是主流的实现方案(以阿里云AWS为例,其他云平台逻辑类似):

使用阿里云 CLI(通用性强,推荐)

阿里云提供了官方的命令行工具 aliyun

安装并配置阿里云 CLI

# 安装
wget https://aliyuncli.alicdn.com/aliyun-cli-linux-3.0.170-amd64.tgz
tar xzvf aliyun-cli-linux-3.0.170-amd64.tgz
sudo cp aliyun /usr/local/bin/
# 配置(需要你的 AccessKey ID 和 Secret)
aliyun configure
# 按提示输入: region, Access Key, Secret Key

编写快照脚本:snapshot.sh

以下脚本会创建一个带时间戳的磁盘快照,并自动清理7天前的旧快照。

#!/bin/bash
# --- 配置参数 ---
# 你的云服务器实例ID(ECS实例ID)
INSTANCE_ID="i-xxxxxxx"
# 需要快照的磁盘ID(系统盘或数据盘,可通过 aliyun ecs DescribeDisks 查询)
DISK_ID="d-xxxxxxx"
# 快照保留天数
RETENTION_DAYS=7
# --- 获取当前时间戳 ---
TIMESTAMP=$(date +%Y%m%d%H%M%S)
SNAPSHOT_NAME="auto_snapshot_${TIMESTAMP}"
# --- 1. 创建快照 ---
echo "[$(date)] 开始创建快照: ${SNAPSHOT_NAME}"
aliyun ecs CreateSnapshot \
    --DiskId ${DISK_ID} \
    --SnapshotName ${SNAPSHOT_NAME} \
    --Description "Auto backup by script"
if [ $? -eq 0 ]; then
    echo "[$(date)] 快照创建成功: ${SNAPSHOT_NAME}"
else
    echo "[$(date)] 快照创建失败"
    exit 1
fi
# --- 2. 清理旧快照(删除超过保留天数的快照)---
echo "[$(date)] 开始清理旧快照(保留最近 ${RETENTION_DAYS} 天)"
# 计算到期时间(秒级时间戳)
CUTOFF_TIME=$(date -d "-${RETENTION_DAYS} days" +%s)
# 获取所有自动快照(根据描述或名称过滤)
aliyun ecs DescribeSnapshots \
    --RegionId cn-hangzhou \
    --DiskId ${DISK_ID} \
    --SnapshotName "auto_snapshot_*" \
    --Status "accomplished" \
    --PageSize 100 \
    | jq -r '.Snapbacks.Snapshot[] | select(.Description == "Auto backup by script") | .SnapshotId + " " + .CreationTime' \
    | while read line; do
        SNAP_ID=$(echo $line | awk '{print $1}')
        CREATION_TIME=$(echo $line | awk '{print $2}')
        # 转换为时间戳
        CREATION_TS=$(date -d "${CREATION_TIME}" +%s)
        if [ ${CREATION_TS} -lt ${CUTOFF_TIME} ]; then
            echo "删除旧快照: ${SNAP_ID} (创建于: ${CREATION_TIME})"
            aliyun ecs DeleteSnapshot --SnapshotId ${SNAP_ID}
        fi
    done
echo "[$(date)] 快照任务完成"

注意:阿里云的 jq 用于解析 JSON,需要先安装:sudo yum install jqsudo apt install jq

设置定时任务(Crontab)

# 编辑当前用户的 crontab
crontab -e
# 添加以下内容(示例:每天凌晨2点执行)
0 2 * * * /path/to/your/snapshot.sh >> /var/log/snapshot.log 2>&1

使用 AWS EC2(AWS CLI)

AWS 的脚本逻辑类似,但工具是 aws

安装配置 AWS CLI

pip install awscli
aws configure
# 输入 Access Key, Secret Key, Region

编写脚本:aws_snapshot.sh

#!/bin/bash
# --- 配置 ---
INSTANCE_ID="i-xxxxxxxx"
RETENTION_DAYS=7
TIMESTAMP=$(date +%Y%m%d%H%M%S)
# --- 获取实例的所有磁盘 ID ---
DISK_IDS=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=${INSTANCE_ID} --query "Volumes[*].VolumeId" --output text)
# --- 为每个磁盘创建快照并打标签 ---
for VOLUME_ID in ${DISK_IDS}; do
    echo "正在为磁盘 ${VOLUME_ID} 创建快照..."
    # 创建快照
    SNAPSHOT_ID=$(aws ec2 create-snapshot \
        --volume-id ${VOLUME_ID} \
        --description "AutoBackup ${VOLUME_ID} ${TIMESTAMP}" \
        --query "SnapshotId" \
        --output text)
    # 添加标签以便识别和清理
    aws ec2 create-tags \
        --resources ${SNAPSHOT_ID} \
        --tags Key=AutoBackup,Value=true \
               Key=CreatedBy,Value=Script \
               Key=RetentionDays,Value=${RETENTION_DAYS}
    echo "快照创建成功: ${SNAPSHOT_ID}"
done
# --- 清理旧快照(删除超过7天的自动备份)---
echo "清理旧快照..."
CUTOFF_DATE=$(date -d "-${RETENTION_DAYS} days" +%Y-%m-%d)
aws ec2 describe-snapshots \
    --filters Name=tag:AutoBackup,Values=true Name=tag:CreatedBy,Values=Script \
    --query "Snapshots[?StartTime<'${CUTOFF_DATE}'].[SnapshotId]" \
    --output text \
    | while read SNAP_ID; do
        echo "删除旧快照: ${SNAP_ID}"
        aws ec2 delete-snapshot --snapshot-id ${SNAP_ID}
    done
echo "完成"

使用 Ansible(企业级,复杂环境)

如果你管理多台机器,可以用 Ansible 的 community.aws.ec2_snapshot 模块。

Playbook 示例 (snapshot.yml):

- name: 定时创建快照
  hosts: localhost
  gather_facts: no
  tasks:
    - name: 获取所有 EC2 实例的自定义标签
      community.aws.ec2_instance_info:
        region: ap-northeast-1
      register: ec2_info
    - name: 为指定实例的磁盘创建快照
      community.aws.ec2_snapshot:
        region: "{{ item.placement.region }}"
        volume_id: "{{ item.block_device_mapping[0].device_name }}"
        wait: yes
        tags:
          Name: "ScheduledBackup_{{ ansible_date_time.date }}"
      loop: "{{ ec2_info.instances | selectattr('tags.Name', 'equalto', 'MyServer') | list }}"

然后在你的 crontab 中定时执行 ansible-playbook snapshot.yml


关键注意事项

  1. 权限最小化:用于执行脚本的 AccessKey 只有“创建/删除快照”的权限(在云平台的 RAM 角色中设置)。
  2. 快照费用:快照会按存储空间收费,请务必设置自动清理旧快照(如上脚本中的 RETENTION_DAYS),避免费用暴涨。
  3. 磁盘状态:创建快照前最好让文件系统静止(如数据库服务先锁表),大部分情况下在线快照可用,但追求数据一致性时,可以在脚本前加入 sync 命令。
  4. 跨地域备份:如果需要跨地域备份,脚本需要先创建快照,再调用 CopySnapshot API。
  5. 脚本日志:建议将输出重定向到日志文件,方便排错(如 /var/log/snapshot.log)。

选择建议

场景 推荐方案
单个云服务器,快速简单 方案一/二 (CLI + Crontab)
管理大量服务器,需要标准化 方案三 (Ansible)
不想自建脚本,希望可视化 使用云平台自带的 自动快照策略(如阿里云“自动快照策略”,免费且原生)

小结:如果你用的是阿里云/腾讯云/华为云,云平台本身就提供了“自动快照”功能(控制台里设置策略,不需要写脚本)。仅在云平台不支持自动策略或需要定制逻辑(如按周/月备份)时,才考虑写脚本。

抱歉,评论功能暂时关闭!