VMware ESXi虚拟机快照功能非常好用,但是经常忘记打快照;导致有时候出问题回退时,很纠结快照时间与现在相隔过久,便想是否能每天自己打快照,并且还能自动清理旧的快照.

前提条件:VMware ESXi的SSH是开启状态

esxi 虚拟机快照保存位置 esxi虚拟机定时快照_开发语言


上图为SSH开启状态

思路如下:

1、 提前获取虚拟ID

2、 在通过ID获取对应虚机的快照ID

3、 通过获取的旧ID,删除最旧的快照,

4、 执行新的快照

5、 记录所有活动日志

6、 添加定时启动
  1. 获取虚拟机ID
  • 以 root 身份通过 DCUI 控制台或 SSH 会话登录到 ESXi 主机。
  • 运行以下命令以获取虚拟机和每个虚拟机的虚拟机 ID 列表:
vim-cmd vmsvc/getallvms

输出如下所示【图片已隐藏私密信息】:

esxi 虚拟机快照保存位置 esxi虚拟机定时快照_esxi 虚拟机快照保存位置_02


2. 编辑Python脚本,利用paramiko库远程连接ESXi进行操作

Paramiko属于python的一个第三方库,可以远程连接Linux服务器,进行通过python进行对Linux进行操作,可以实现进行对远程服务器进行下载和上传文件操作。既然是第三方库,我们可以通过pip进行安装:

pip install paramiko

esxi 虚拟机快照保存位置 esxi虚拟机定时快照_开发语言_03

具体Python脚本如下:

import re
import paramiko
import time
from datetime import datetime
import logging

filename = "./" + datetime.now().strftime("%Y%m%d") + "-" + "VMware Esxi Auto Snapshot"
logging.basicConfig(filename=filename, level=logging.INFO,
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')

logging.info("脚本开始运行...")

ip='192.168.1.2' #VMware ESXi 主机IP地址,也可以使用DNS名字
vms=['1','14','15'] #需要自动建立快照的VM的ID
vmnames=['NAME1','NAME2','NAME3'] #需要自动建立快照的VM对应的备注名称

ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(hostname=ip, username='***', password='******',port='22') #此处修改用户名密码
command = ssh_client.invoke_shell()
time.sleep(2)
logging.info(ip + " 连接成功...")

for i in range(len(vms)):
    print(vms[i])
    command.send(f'vim-cmd vmsvc/snapshot.get {vms[i]}\n')
    time.sleep(3)
    output = command.recv(65535).decode()
    snapids = re.findall(r'Id\D+(\d+)',str(output))

    if (len(snapids)>2): #始终保留至少2份快照在任何过程中,可根据自身需求更改
        logging.info(ip + " 开始删除"+vmnames[i]+"最旧的快照...")
        command.send(f'vim-cmd vmsvc/snapshot.remove {vms[i]} {snapids[0]} \n')
        time.sleep(5)
        while True: #等待快照删除
            command.send('vim-cmd vmsvc/snapshot.get {vms[i]}\n')
            time.sleep(3)
            output = command.recv(65535).decode()
            new_snapids = re.findall(r'Id\D+(\d+)',str(output))
            if (len(new_snapids) < len(snapids)):
                break
        logging.info(ip + " 删除"+vmnames[i]+"最旧的快照结束...")

    logging.info(ip + " 开始添加"+vmnames[i]+"最新的快照...")
    date = datetime.now().strftime("%Y%m%d%H%M%S")
    command.send(f'vim-cmd vmsvc/snapshot.create {vms[i]}  {date} "Daily automatic snapshot"\n')
    time.sleep(5)
    while True: #等待快照完成
        command.send(f'vim-cmd vmsvc/snapshot.get {vms[i]}\n')
        time.sleep(3)
        output = command.recv(65535).decode()
        new_snapids = re.findall(r'Id\D+(\d+)',str(output))
        if (len(new_snapids) > (len(snapids)-1)):
            break
    logging.info(ip + " 添加"+vmnames[i]+"最新的快照结束...")

ssh_client.close()
logging.info(ip + " 断开连接...")
logging.info("脚本结束运行...")
  1. 加入crontab中定时运行 (此处设置为每天凌晨2点运行脚本)

当然除了通过日志记录外还可以通过邮件形式或其他方式发送最终结果。