本文目录导读:

针对不同云平台(阿里云、腾讯云、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 jq或sudo 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。
关键注意事项
- 权限最小化:用于执行脚本的 AccessKey 只有“创建/删除快照”的权限(在云平台的 RAM 角色中设置)。
- 快照费用:快照会按存储空间收费,请务必设置自动清理旧快照(如上脚本中的
RETENTION_DAYS),避免费用暴涨。 - 磁盘状态:创建快照前最好让文件系统静止(如数据库服务先锁表),大部分情况下在线快照可用,但追求数据一致性时,可以在脚本前加入
sync命令。 - 跨地域备份:如果需要跨地域备份,脚本需要先创建快照,再调用
CopySnapshotAPI。 - 脚本日志:建议将输出重定向到日志文件,方便排错(如
/var/log/snapshot.log)。
选择建议
| 场景 | 推荐方案 |
|---|---|
| 单个云服务器,快速简单 | 方案一/二 (CLI + Crontab) |
| 管理大量服务器,需要标准化 | 方案三 (Ansible) |
| 不想自建脚本,希望可视化 | 使用云平台自带的 自动快照策略(如阿里云“自动快照策略”,免费且原生) |
小结:如果你用的是阿里云/腾讯云/华为云,云平台本身就提供了“自动快照”功能(控制台里设置策略,不需要写脚本)。仅在云平台不支持自动策略或需要定制逻辑(如按周/月备份)时,才考虑写脚本。