如何编写自动创建虚拟机快照脚本

wen 实用脚本 1

本文目录导读:

如何编写自动创建虚拟机快照脚本

  1. 目录导读
  2. 为什么需要自动化虚拟机快照脚本?
  3. 主流虚拟化平台的快照API概览
  4. 脚本语言选型与核心逻辑设计
  5. VMware vSphere环境自动快照脚本编写(Python+pyVmomi)
  6. Hyper-V环境自动快照脚本编写(PowerShell)
  7. KVM/libvirt环境自动快照脚本编写(Bash+virsh)
  8. 快照生命周期管理:自动删除过期快照
  9. 异常处理与日志记录最佳实践
  10. 常见问题与解答(Q&A)
  11. 脚本安全与合规性注意事项

自动化备份与运维实战指南

目录导读

  1. 为什么需要自动化虚拟机快照脚本?
  2. 主流虚拟化平台的快照API概览
  3. 脚本语言选型与核心逻辑设计
  4. VMware vSphere环境自动快照脚本编写(Python+pyVmomi)
  5. Hyper-V环境自动快照脚本编写(PowerShell)
  6. KVM/libvirt环境自动快照脚本编写(Bash+virsh)
  7. 快照生命周期管理:自动删除过期快照
  8. 异常处理与日志记录最佳实践
  9. 常见问题与解答(Q&A)
  10. 脚本安全与合规性注意事项

为什么需要自动化虚拟机快照脚本?

在虚拟化环境中,快照是一个关键的数据保护工具,手动创建快照在管理少量虚拟机时尚可接受,但当环境扩展到数十甚至数百个虚拟机时,手动操作将变得低效且容易出错。
自动化脚本的价值体现在:

  • 定时备份:无需人工值守,确保关键业务虚拟机的状态被定期记录
  • 一致性保证:结合静默机制(Quiesce),确保数据库或文件系统的一致性
  • 批量操作:一次脚本运行,可对多台虚拟机执行快照创建、删除或恢复
  • 回溯容错:在升级、补丁安装或配置变更前自动拍照,提供安全回滚点

示例场景
某企业每周日凌晨2点需对20台生产数据库虚拟机创建快照,保留最近7天的快照,过期自动删除,手动执行需30分钟,而脚本仅需2分钟且零遗漏。


主流虚拟化平台的快照API概览

平台 核心API/工具 主要操作命令/方法
VMware vSphere pyVmomi(Python) / PowerCLI(PowerShell) CreateSnapshot_TaskRemoveSnapshot_Task
Microsoft Hyper-V Hyper-V WMI / PowerShell模块 Checkpoint-VMRemove-VMCheckpoint
KVM/QEMU + libvirt virsh命令 / libvirt Python绑定 snapshot-create-assnapshot-delete
Proxmox VE Proxmox REST API POST /nodes/{node}/qemu/{vmid}/snapshot
Nutanix AHV acropolis CLI / REST API acli vm.snapshot_create

选择依据
如果环境混合,建议采用Python作为胶水语言,通过不同库或REST API调用各平台,若纯粹管理Hyper-V,PowerShell是最佳选择。


脚本语言选型与核心逻辑设计

推荐语言与理由

  • Python:跨平台,库丰富(如pyVmomi、ansible、requests),适合混合虚拟化环境
  • PowerShell:Hyper-V原生支持,管道操作简洁,Windows管理员首选
  • Bash + virsh:轻量级,适合纯KVM/Linux环境

核心逻辑流程图(伪代码)

加载配置(虚拟机列表、快照名称模板、保留天数)
2. 遍历每个虚拟机:
   a. 检查当前快照数量(若超过最大限制则先删除最旧的)
   b. 执行快照创建(带描述、静默标志、内存状态等参数)
   c. 记录操作日志(时间、虚拟机名、结果)
3. 如果启用过期清理:
   a. 获取所有快照的创建时间戳
   b. 删除早于保留天数的快照
4. 发送通知(邮件、企业微信、Slack等)

VMware vSphere环境自动快照脚本编写(Python+pyVmomi)

脚本示例:创建带描述的定时快照

#!/usr/bin/env python3
from pyVmomi import vim
from pyVim.connect import SmartConnect, Disconnect
import ssl, datetime, os
def create_snapshot(vm, snapshot_name, description="Auto backup", memory=True, quiesce=True):
    try:
        task = vm.CreateSnapshot_Task(
            name=snapshot_name,
            description=description,
            memory=memory,
            quiesce=quiesce
        )
        print(f"[{datetime.datetime.now()}] 创建快照 {snapshot_name} 在虚拟机 {vm.name}")
        return True
    except vim.fault.NoPermission as e:
        print(f"权限不足: {e.msg}")
        return False
# 主程序
context = ssl._create_unverified_context()
si = SmartConnect(host='vcenter.example.com', user='admin', pwd='password', sslContext=context)
content = si.RetrieveContent()
for datacenter in content.rootFolder.childEntity:
    # 获取所有虚拟机并过滤需要备份的(可按标签或名称模式)
    vm_list = [vm for vm in datacenter.vmFolder.childEntity if vm.name.startswith('prod-')]
    for vm in vm_list:
        snap_name = f"auto_{datetime.datetime.now().strftime('%Y%m%d_%H%M')}"
        create_snapshot(vm, snap_name, quiesce=True)
Disconnect(si)

关键参数说明

  • memory=True:保存虚拟机内存状态(快照更完整但文件更大)
  • quiesce=True:让虚拟机内的VSS(Volume Shadow Copy)将数据刷新到磁盘,确保应用一致

Hyper-V环境自动快照脚本编写(PowerShell)

脚本示例:批量创建标准检查点

$VMs = Get-VM | Where-Object {$_.Name -like "Web*"}
$RetentionDays = 7
$SnapPrefix = "PrePatch_"
ForEach ($vm in $VMs) {
    $snapName = "$SnapPrefix$(Get-Date -Format 'yyyyMMdd_HHmm')"
    # 创建检查点(快照)
    Checkpoint-VM -Name $vm.Name -SnapshotName $snapName -Description "自动补丁前快照"
    Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] 已为 $($vm.Name) 创建检查点 $snapName"
    # 删除过期快照
    $snapshots = Get-VMSnapshot -VMName $vm.Name | Where-Object {$_.CreationTime -lt (Get-Date).AddDays(-$RetentionDays)}
    $snapshots | ForEach-Object {
        Remove-VMSnapshot -VMName $vm.Name -Name $_.Name -Confirm:$false
        Write-Host "删除过期快照: $($_.Name)"
    }
}

Hyper-V要点

  • Windows Server 2016+默认使用“标准检查点”(标准快照),如果希望与应用一致,需启用“生产检查点”(需集成服务支持)
  • 使用 -AsJob 参数可并行执行,加速大规模环境

KVM/libvirt环境自动快照脚本编写(Bash+virsh)

脚本示例:内部快照创建(支持qcow2格式)

#!/bin/bash
VM_LIST=("vm-db1" "vm-web2")
DATE=$(date +%Y%m%d_%H%M)
SNAPSHOT_DIR="/var/lib/libvirt/images/snapshots"
for vm in "${VM_LIST[@]}"; do
    snap_name="${vm}_auto_${DATE}"
    echo "[`date`] 创建内部快照 $snap_name 于 $vm"
    # 创建磁盘内部快照(要求磁盘格式为qcow2)
    virsh snapshot-create-as --domain "$vm" --name "$snap_name" --description "自动快照"
    if [ $? -eq 0 ]; then
        echo "成功"
    else
        echo "失败" >&2
    fi
done

注意

  • 内部快照与磁盘文件绑定,会增大磁盘大小,如果创建大量快照,建议使用外部快照--disk-only)以节省空间
  • 使用 virsh snapshot-list $vm 查看快照列表,virsh snapshot-delete $vm --name $snap_name 删除

快照生命周期管理:自动删除过期快照

快照不是永久备份,长期保留会消耗大量存储空间并影响性能,一个健壮的脚本必须包含自动清理逻辑

通用清理算法(以vSphere为例)

def clean_old_snapshots(vm, retention_days=7):
    now = datetime.datetime.now(datetime.timezone.utc)
    snapshots = vm.snapshot.rootSnapshotList if vm.snapshot else []
    for snap in snapshots:
        age = now - snap.createTime.replace(tzinfo=datetime.timezone.utc)
        if age.days > retention_days:
            snap_obj = vm.snapshot.CurrentSnapshot if vm.snapshot.CurrentSnapshot else None
            if snap_obj and snap.name == snap_obj.name:
                continue  # 避免删除当前正在使用的快照(虽然不推荐处于快照中太久)
            task = snap.snapshot.RemoveSnapshot_Task(removeChildren=False)
            print(f"删除过期快照: {snap.name}, 创建于 {snap.createTime}")

最佳实践

  • 保留期为7~30天,根据合规要求调整
  • 在删除前先检查该快照是否包含子虚拟机(如链接克隆)
  • 执行删除操作前,强制发送一次通知以人工确认

异常处理与日志记录最佳实践

常见的异常场景

异常类型 典型错误 处理方法
连接超时 无法连接到vCenter 重试3次,间隔30秒,失败后发告警
虚拟机已关闭 快照创建失败(需开机) 跳过并记录状态,或唤醒虚拟机后再执行
磁盘空间不足 快照文件无法创建 检查数据存储剩余空间,提前预警
权限不足 403 Forbidden 检查服务账号权限,记录到安全事件日志

日志记录模板(Python示例)

import logging, sys
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('/var/log/vm_snapshot.log'),
        logging.StreamHandler(sys.stdout)
    ]
)
try:
    create_snapshot(vm, snap_name)
    logging.info(f"成功创建快照 {snap_name} 于 {vm.name}")
except vim.fault.VmConfigFault as e:
    logging.error(f"配置错误: {vm.name} - {e.msg}")
except Exception as e:
    logging.critical(f"未知错误: {vm.name} - {str(e)}")

输出示例

2025-03-15 02:00:12,456 - INFO - 成功创建快照 auto_20250315_0200 于 prod-db1
2025-03-15 02:00:45,789 - ERROR - 虚拟机 prod-web5 处于已关闭状态,跳过

常见问题与解答(Q&A)

Q1:快照创建后,虚拟机性能会下降吗?

A:短期内的快照(如 24小时)影响甚微,但长期保留大量快照链,会导致磁盘I/O下降30%~50%,因此脚本应限制快照数量(如最多3个),并定期删除。

Q2:如何确保备份的应用一致性?

A:在Hyper-V中使用生产检查点(-SnapshotType Production),在vSphere中启用quiesce=True,对于数据库虚拟机,建议配合数据库自己的备份工具(如SQL Server的VSS写入器)。

Q3:脚本是否可以跨平台使用?

A:可以,但需要抽象一层,例如使用Python的requests库调用REST API(如Proxmox、AHV),或使用Ansible的vmware_guest_snapshot模块统一管理不同平台,但核心逻辑需要适配各自的API差异。

Q4:如何防止快照脚本被误执行?

A:添加安全守卫:

  • 加上 --dry-run 参数做测试运行
  • 要求脚本接收配置文件而不是硬编码虚拟机列表
  • 对生产环境脚本增加“二次确认”(如输入“YES”才执行)

Q5:快照占用的存储空间如何监控?

A:在脚本中添加存储空间检查步骤,例如vSphere中通过datastore.Summary.FreeSpace判断可用空间是否低于20%,低于则停止创建并告警。


脚本安全与合规性注意事项

  1. 凭据管理:绝不在脚本中硬编码密码,使用环境变量、密钥管理器(如Hashicorp Vault)或Windows凭据管理器。

    • 在vSphere中:使用 SmartConnectNoSSL 并传入 -p 参数(不推荐明文)
    • 在PowerShell中:使用 Export-Clixml 加密存储凭据文件
  2. 最小权限原则:为运行脚本的服务账号授予仅创建/删除快照的权限,而不是管理员权限。

    • vCenter:创建一个角色,仅包含 VirtualMachine.Provisioning.CreateSnapshotDeleteSnapshot
    • Hyper-V:将账号加入 Hyper-V Administrators 本地组
  3. 审计与合规

    • 所有快照操作记录到日志,并存放到独立的审计服务器
    • 定期(如每月)手动抽查快照的可恢复性
    • 确保快照存储位置满足数据保护法规(如GDPR、HIPAA)
  4. 错误回滚:如果批量创建快照时某个虚拟机失败,应记录但不中断其余任务,整体完成后,发送汇总报告。


编写自动创建虚拟机快照脚本并非难事,但一个生产可用的脚本需要涵盖配置管理、异常处理、清理策略、监控告警和安全控制,通过本文提供的示例和最佳实践,你可以根据自身环境(vSphere、Hyper-V或KVM)快速搭建一个可靠的快照自动化系统,建议从小批量测试开始,逐步扩展到全部虚拟机,并在正式使用前进行灾难恢复演练,确保快照真正可用。

延伸阅读

  • 考虑集成Terraform或Ansible实现基础设施即代码(IaC)的快照管理
  • 利用Prometheus + Grafana监控快照数量和存储空间
  • 为关键虚拟机设置“锁保护”,禁止自动脚本删除最后一份快照

(全文完)

上一篇自动调整屏幕文本大小的脚本

下一篇当前分类已是最新一篇

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