如何通过Cloud Function或gcloud命令每10分钟自动创建磁盘快照?
实现每10分钟自动创建GCP磁盘快照的方案
GCP默认快照计划最小间隔为1小时,要实现每10分钟的自动快照,可通过以下两种托管式方案实现,无需依赖本地运行的机器:
方案一:Cloud Function + Cloud Scheduler
1. 编写快照创建函数(Python示例)
创建HTTP触发的Cloud Function,调用Compute Engine API生成快照,同时加入旧快照清理逻辑避免存储溢出:
import os import datetime from googleapiclient import discovery from oauth2client.client import GoogleCredentials def create_snapshot(event, context): # 初始化Compute API客户端 credentials = GoogleCredentials.get_application_default() compute = discovery.build('compute', 'v1', credentials=credentials) # 从环境变量读取配置参数 project_id = os.environ['PROJECT_ID'] disk_zone = os.environ['DISK_ZONE'] target_disk = os.environ['TARGET_DISK'] retain_hours = int(os.environ.get('RETAIN_HOURS', 24)) # 生成唯一快照名称 timestamp = datetime.datetime.utcnow().strftime("%Y%m%d-%H%M%S") snapshot_name = f"{target_disk}-auto-snap-{timestamp}" # 发送创建快照请求 snapshot_body = { 'name': snapshot_name, 'description': f"Auto-snapshot every 10 minutes (retained for {retain_hours}h)" } create_req = compute.disks().createSnapshot( project=project_id, zone=disk_zone, disk=target_disk, body=snapshot_body ) create_req.execute() print(f"Created snapshot: {snapshot_name}") # 清理过期快照 cutoff_time = (datetime.datetime.utcnow() - datetime.timedelta(hours=retain_hours)).isoformat() + 'Z' list_req = compute.snapshots().list( project=project_id, filter=f"name~^{target_disk}-auto-snap- AND creationTimestamp<'{cutoff_time}'" ) snapshots = list_req.execute().get('items', []) for snap in snapshots: delete_req = compute.snapshots().delete( project=project_id, snapshot=snap['name'] ) delete_req.execute() print(f"Deleted expired snapshot: {snap['name']}")
2. 配置并部署函数
- 在GCP控制台创建Cloud Function,选择Python运行时,将上述代码粘贴到
main.py,设置入口函数为create_snapshot - 添加环境变量:
PROJECT_ID:你的GCP项目IDDISK_ZONE:目标磁盘所在区域(如us-central1-a)TARGET_DISK:需要快照的磁盘名称RETAIN_HOURS:可选,快照保留时长(默认24小时)
- 为函数的服务账号分配权限:至少需要
compute.snapshots.create、compute.snapshots.delete、compute.disks.get权限,或直接分配Compute Instance Admin (v1)角色
3. 创建Cloud Scheduler定时任务
- 在GCP控制台打开Cloud Scheduler,创建新任务
- 频率设置为
*/10 * * * *(Cron表达式,每10分钟执行一次) - 目标选择
HTTP,指向Cloud Function的触发URL,请求方法选POST - 保存任务,等待定时触发即可
方案二:gcloud脚本 + Cloud Run + Cloud Scheduler
如果更熟悉Shell脚本,可通过Cloud Run运行快照脚本,再用Cloud Scheduler定时触发:
1. 编写Shell快照脚本
创建script.sh:
#!/bin/bash set -e # 配置参数 PROJECT_ID="your-project-id" DISK_ZONE="your-disk-zone" TARGET_DISK="your-target-disk" RETAIN_HOURS=24 # 生成唯一快照名称 SNAPSHOT_NAME="${TARGET_DISK}-auto-snap-$(date -u +%Y%m%d-%H%M%S)" # 创建快照 gcloud compute disks snapshot "$TARGET_DISK" \ --zone "$DISK_ZONE" \ --project "$PROJECT_ID" \ --snapshot-names "$SNAPSHOT_NAME" \ --description "Auto-snapshot every 10 minutes" # 清理过期快照 CUTOFF_DATE=$(date -u -d "-${RETAIN_HOURS} hours" +%Y-%m-%dT%H:%M:%SZ) gcloud compute snapshots list \ --project "$PROJECT_ID" \ --filter="name~^${TARGET_DISK}-auto-snap- AND creationTimestamp<'${CUTOFF_DATE}'" \ --format="value(name)" | xargs -r gcloud compute snapshots delete -q
2. 构建Cloud Run镜像
创建Dockerfile:
FROM google/cloud-sdk:slim COPY script.sh /script.sh RUN chmod +x /script.sh CMD ["/script.sh"]
构建镜像并推送到GCR:
gcloud builds submit --tag gcr.io/[PROJECT_ID]/snapshot-scheduler
3. 部署Cloud Run服务
gcloud run deploy snapshot-scheduler \ --image gcr.io/[PROJECT_ID]/snapshot-scheduler \ --platform managed \ --region [REGION] \ --service-account [SERVICE_ACCOUNT_EMAIL]
确保服务账号拥有快照创建/删除的必要权限
4. 创建Cloud Scheduler任务
- 频率设为
*/10 * * * * - 目标选择
HTTP,指向Cloud Run服务的URL,请求方法GET - 保存任务即可
注意事项
- 频繁快照会占用额外存储资源,建议根据业务需求调整保留时长,避免存储成本过高
- 遵循权限最小化原则,不要给服务账号分配超出必要的权限
- 可通过GCP监控设置快照创建失败的告警规则,及时排查问题
内容的提问来源于stack exchange,提问作者hyunboo
相关产品推荐
相关产品推荐

