自动化运维
脚本库
概述
脚本库:脚本库集中存储和管理自动化脚本文件。对云主机执行脚本,可以完成复杂的运维操作和自动化任务。

功能优势
- 简单易用
- 支持以可视化方式快速创建脚本,并通过自定义参数实现脚本灵活配置。
- 脚本内可以包含复杂命令,为云主机一键执行脚本,即可完成复杂的运维操作,例如:应用健康检查、平台电源负载均衡 (节能) 与调度、应用程序批量更新、灰度发布等,提高管理便利性,降低人工运维成本。
- 便捷运维
- 提供专门的脚本库页面,对脚本进行集中生命周期管理。用户可以在脚本库中灵活地创建、修改或删除脚本。
- 创建好的脚本可以长期保存,重复使用;一个脚本可以同时在多台云主机执行、互不影响,有效提升大规模场景运维效率。
- 提供丰富、详细的脚本执行记录,包括运行过该脚本的云主机、运行时间、结束时间、运行时配置和结果返回,便于操作回溯和问题定位。
- 类型丰富:支持多种命令类型,包括:Shell、Python、Perl、Bat、Powershell,用户可根据实际需求,灵活选用。
创建脚本
在ZStack Cloud主菜单,点击。在脚本库界面,点击创建脚本,弹出创建脚本界面。
- 名称:输入脚本名称。命名规则:命名规则:长度限制1~128字符,输入内容只能包含中文汉字、英文字母、数字、空格和以下7种英文字符
- _ . ( ) : +且不支持以空格开头或结尾 - 简介:可选项,可留空不填
- 平台类型:选择脚本适用的操作系统平台类型,目前支持两种类型:Linux、Windows。脚本只能在使用对应类型操作系统的云主机执行
- 脚本类型:选择脚本命令类型
- Linux支持以下命令类型:Shell、Python、Perl
- Windows支持以下命令类型:Bat、Powershell
- 脚本内容:输入脚本内容。如需传递自定义参数,请遵循Jinja2模板语法Note: ZStack Cloud将对脚本内容进行Base64编码,确保数据存储和传输安全。
- 超时时间:设置脚本执行超时时间,默认为60秒,单位:秒、分钟、小时
- 自定义参数:可选项,为脚本添加自定义参数,一个脚本最多可添加20个自定义参数,如需添加,请点击添加自定义参数,并设置以下内容:
- 参数名:填写参数名,长度限制1~64字符
- 参数值:填写参数值,长度限制1~64字符
- 简介:填写参数简介

管理脚本
在ZStack Cloud主菜单,点击,进入脚本库界面。
| 操作 | 描述 |
|---|---|
| 创建脚本 | 创建一个新的脚本。 |
| 编辑名称简介 | 修改脚本的名称、简介信息。 |
| 修改脚本 | 修改脚本内容、超时时间和自定义参数。 |
| 执行脚本 | 在指定云主机执行脚本。 Note:
|
| 删除脚本 | 将脚本删除。 |
脚本详情
- 查看平台内所有脚本执行记录:在ZStack Cloud主菜单,点击。在脚本库界面,点击执行记录标签,即可查看平台内所有脚本执行记录。
- 查看单个脚本执行记录:在脚本库界面,点击需要查看的脚本名称,进入该脚本详情页。在脚本详情页,点击执行记录标签,即可查看该脚本的所有执行记录。Note: 如脚本已被删除,用户仍然可以在平台内所有脚本执行记录中查看其相关的执行记录。
- 总览包含执行记录的基本信息,包括:执行状态、执行记录UUID、脚本名称、操作员、开始时间、结束时间、云主机执行明细。
- 如查看记录时,对应的脚本已被删除,则脚本名称栏将显示该脚本UUID。
- ZStack Cloud支持同时在多台云主机上执行同一个脚本,如本次执行记录发生时,用户选择多台云主机同时执行脚本,则开始时间以第一台云主机开始执行脚本的时间为准、结束时间以最后一台云主机执行脚本结束时间为准。
- 执行状态分为执行中、成功、失败、异常四种:
- 执行中:本次执行记录中的全部或部分云主机正在执行脚本。
- 成功:本次执行记录中的所有云主机均执行脚本成功。
- 失败:本次执行记录中的所有云主机均执行脚本失败。
- 异常:本次执行记录中的部分云主机执行脚本成功、部分云主机执行脚本失败。
- 云主机执行明细列明本次执行该脚本的全部云主机信息,用户可点击查看详情,以云主机为粒度了解脚本执行情况,包括该云主机的脚本执行状态、执行开始时间、结束时间,和执行结果。
如图 3所示:图 3. 执行记录详情-总览 
- 脚本信息展示执行记录生成时,该脚本的详细配置信息,包括脚本内容、自定义参数和其他基本配置,便于用户进行操作回溯。Note: 执行记录中的脚本信息为执行时的脚本配置记录,可能和脚本最新配置不一致,仅供回溯参考。如图 4所示:
图 4. 执行记录详情-脚本信息 
脚本执行记录
- 查看平台内所有脚本执行记录:在ZStack Cloud主菜单,点击。在脚本库界面,点击执行记录标签,即可查看平台内所有脚本执行记录。
- 查看单个脚本执行记录:在脚本库界面,点击需要查看的脚本名称,进入该脚本详情页。在脚本详情页,点击执行记录标签,即可查看该脚本的所有执行记录。Note: 如脚本已被删除,用户仍然可以在平台内所有脚本执行记录中查看其相关的执行记录。
- 总览包含执行记录的基本信息,包括:执行状态、执行记录UUID、脚本名称、操作员、开始时间、结束时间、云主机执行明细。
- 如查看记录时,对应的脚本已被删除,则脚本名称栏将显示该脚本UUID。
- ZStack Cloud支持同时在多台云主机上执行同一个脚本,如本次执行记录发生时,用户选择多台云主机同时执行脚本,则开始时间以第一台云主机开始执行脚本的时间为准、结束时间以最后一台云主机执行脚本结束时间为准。
- 执行状态分为执行中、成功、失败、异常四种:
- 执行中:本次执行记录中的全部或部分云主机正在执行脚本。
- 成功:本次执行记录中的所有云主机均执行脚本成功。
- 失败:本次执行记录中的所有云主机均执行脚本失败。
- 异常:本次执行记录中的部分云主机执行脚本成功、部分云主机执行脚本失败。
- 云主机执行明细列明本次执行该脚本的全部云主机信息,用户可点击查看详情,以云主机为粒度了解脚本执行情况,包括该云主机的脚本执行状态、执行开始时间、结束时间,和执行结果。
如图 3所示:图 3. 执行记录详情-总览 
- 脚本信息展示执行记录生成时,该脚本的详细配置信息,包括脚本内容、自定义参数和其他基本配置,便于用户进行操作回溯。Note: 执行记录中的脚本信息为执行时的脚本配置记录,可能和脚本最新配置不一致,仅供回溯参考。如图 4所示:
图 4. 执行记录详情-脚本信息 
XML Hook
概述
XML Hook:一种脚本程序,用于在云主机XML文件中灵活插入或修改参数,从而实现定制化配置并扩展云主机功能。

功能优势
- 灵活性
- XML Hook以单独的脚本文件形式管理和维护,将临时或个性化配置需求与程序核心逻辑代码分离,云主机绑定/解绑XML Hook,即可实现配置动态调整和灵活扩展,无需手动修改代码。
- XML Hook可长期保存、重复使用,一个XML Hook可同时绑定到多台云主机,有效提高大规模场景运维效率。
- 可扩展性
通过定义并使用XML Hook,用户可按实际需求灵活修改云主机XML参数,实现部分无法通过界面操作直接完成的配置,有效扩展云主机能力,满足个性化场景需求,例如:修改QEMU自定义参数、关闭vNIC TSO等。XML Hook为用户现场、第三方软硬件测试与应用提供了更便捷的适配途径。
注意事项
- 使用XML Hook需熟悉云主机配置和XML编写规则,如XML Hook中包含语法错误或导致云主机配置错误,云主机将无法启动。
- 如需对已绑定XML Hook的云主机需进行QEMU/Libvirt升级,请提前确认预期QEMU/Libvirt是否兼容该XML Hook,避免升级后因不兼容导致云主机启动/重启失败。
创建XML Hook
在ZStack Cloud主菜单,点击,进入XML Hook界面。点击创建XML Hook,弹出创建 XML Hook界面。
- 名称:设置XML Hook名称。命名规则:长度限制1~128字符,输入内容只能包含中文汉字、英文字母、数字、空格和以下7种英文字符
- _ . ( ) : +且不支持以空格开头或结尾 - 简介:可选项,可留空不填
- 脚本内容:填写XML Hook内容,为确保脚本内容安全、合规,填写前可点击查看示例,详细编写方法可查看XML Hook编写方法

管理XML Hook
在ZStack Cloud主菜单,点击,进入XML Hook界面。
| 操作 | 描述 |
|---|---|
| 创建XML Hook | 创建一个新的XML Hook。 |
| 编辑名称简介 | 修改XML Hook的名称、简介信息。 |
| 修改XML Hook | 修改XML Hook内容。 Note:
|
| 绑定云主机 | 将XML Hook绑定到云主机,在云主机XML文件中插入或修改参数,实现定制化配置。 Note:
|
| 解绑云主机 | 将XML Hook从云主机解绑。 Note:
|
| 删除XML Hook | 将XML Hook删除。 Note: 已绑定云主机的XML
Hook不支持删除。如需删除,请先从所有云主机解绑。 |
XML Hook编写方法
本章介绍如何编写XML Hook内容并提供XML Hook示例。
XmlHook类方法释义
class XmlHook:
def get_value_of_element(self, xmlbranch):
""" 获取XML元素的文本内容 """
# Params:
xmlbranch: Element,表示XML元素对象
# Return: 字符串,表示元素的文本内容
return
def get_value_of_attribute(self, xmlbranch, attribute):
""" 获取XML元素的指定属性的值 """
# Params:
xmlbranch: Element,表示XML元素对象
attribute: 字符串,表示属性名称
# Return: 字符串,表示属性的值
return
def get_value_of_attribute_from_parent(self, parent_xmlbranch, element, attribute):
""" 从父元素中获取指定子元素的指定属性的值 """
# Params:
parent_xmlbranch: Element,表示父XML元素对象
element: 字符串,表示子元素标签名
attribute: 字符串,表示属性名称
# Return: 字符串,表示属性的值
return
def found_attribute(self, xmlbranch, attribute):
""" 检查XML元素是否包含指定的属性 """
# Params:
xmlbranch: Element,表示XML元素对象
attribute: 字符串,表示属性名称
# Return: 布尔值,表示属性是否存在
return
def modify_value_of_element(self, xmlbranch, value):
""" 修改XML元素的文本内容 """
# Params:
xmlbranch: Element,表示XML元素对象
value: 字符串,表示新的文本内容
# Return: 无
return
def add_value_of_element(self, xmlbranch, value):
""" 添加或修改XML元素的文本内容 """
# Params:
xmlbranch: Element,表示XML元素对象
value: 字符串,表示新的文本内容
# Return: 无
return
def set_value_of_attribute(self, xmlbranch, attribute, attribute_value):
""" 设置XML元素的指定属性的值(如不存在则创建)"""
# Params:
xmlbranch: Element,表示XML元素对象
attribute: 字符串,表示属性的名称
attribute_value: 字符串,表示属性的值
# Return: 无
return
def modify_value_of_attribute(self, xmlbranch, attribute, attribute_value):
""" 修改XML元素的指定属性的值(如不存在则不修改)"""
# Params:
xmlbranch: Element,表示XML元素对象
attribute: 字符串,表示属性名称
attribute_value: 字符串,表示属性的值
# Return: 无
def add_attribute(self, xmlbranch, attribute, attribute_value):
""" 添加XML元素的指定属性 """
# Params:
xmlbranch: Element,表示XML元素对象
attribute: 字符串,表示属性名称
attribute_value: 字符串,表示属性的值
# Return: 无
return
def delete_attribute(self, xmlbranch, attribute):
""" 删除XML元素的指定属性 """
# Params:
xmlbranch: Element,表示XML元素对象
attribute: 字符串,表示属性名称
# Return: 无
return
def get_index_of_element(self, root, element_key):
""" 获取指定元素在父元素中的索引 """
# Params:
root: Element,表示父元素对象
element_key: 字符串,表示元素的标签名
# Return: 整数,表示元素的索引,如果不存在则返回 - 1
return
def found_element(self, root, element_key):
"""检查父元素中是否包含指定标签名的子元素 """
# Params:
root: Element,表示父元素对象
element_key: 字符串,表示元素的标签名
# Return: 布尔值,表示元素是否存在
return
def delete_element_from_parent(self, child_xmlbranch, parent_xmlbranch):
""" 从父元素中删除指定的子元素 """
# Params:
child_xmlbranch: Element,表示子元素对象
parent_xmlbranch: Element, 表示父元素对象
# Return: 无
return
def add_element_to_parent(self, child_xmlbranch, parent_xmlbranch, index=-1):
""" 将子元素添加到父元素中(可选指定索引位置)"""
# Params:
child_xmlbranch: Element,表示子元素对象
parent_xmlbranch: Element,表示父元素对象
index: 整数,表示插入的索引位置,默认为 - 1(追加到末尾)
# Return: 根元素对象
return
def get_changed_xmlstr(self, root_xmlbranch):
""" 获取修改后的XML字符串,并格式化输出 """
# Params:
root_xmlbranch: Element,表示根元素对象
# Return: 字符串,表示格式化后的XML字符串
return
def create_element(self, element_name):
""" 创建一个新的XML元素 """
# Params:
element_name: 字符串,表示元素的标签名
# Return: 新的XML元素对象
return
XML Hook示例
- root:Element类型,表示根XML对象,一般指云主机的完整XML。
- hook:表示XmlHook类型对象。
以下示例将展示XML Hook内容以及云主机绑定XML Hook前后的XML配置变化。
- 修改前XML
<domain> <devices> <hostdev mode='subsystem' type='pci' managed='no'> <source> <address domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/> </source> </hostdev> </devices> </domain> - XML
Hook
def config_gpu_passthrough(root, hook, gpu_uuid): for devices in root.findall("devices"): for hostdev in devices.findall("hostdev"): hostdev_type = hook.get_value_of_attribute(hostdev, "type") if hostdev_type == "pci": hook.modify_value_of_attribute(hostdev, "type", "mdev") hook.add_attribute(hostdev, "model", "vfio-pci") hook.add_attribute(hostdev, "display", "on") for source in hostdev.findall("source"): for address in source.findall("address"): hook.delete_element_from_parent(address, source) source_address = hook.create_element("address") hook.add_attribute(source_address, "uuid", gpu_uuid) hook.add_element_to_parent(source_address, source) config_gpu_passthrough(root, hook, "4162a71b-f41e-4b06-b9ee-c503114dff29") - 通过XML
Hook修改后的XML
<domain> <devices> <hostdev display="on" managed="no" mode="subsystem" model="vfio-pci" type="mdev"> <source> <address uuid="4162a71b-f41e-4b06-b9ee-c503114dff29"/> </source> </hostdev> </devices> </domain>
- 修改前XML
<domain> <cpu mode='custom' match='exact' check='full'> <topology sockets='1' cores='1' threads='1'/> <feature policy='require' name='hypervisor'/> </cpu> </domain> - XML
Hook
def config_cpu_mode(root, cpu_mode, hook): for cpu in root.findall("cpu"): hook.modify_value_of_attribute(cpu, "mode", cpu_mode) config_cpu_mode(root, "host-model", hook) - 通过XML
Hook修改后的XML
<domain> <cpu mode='host-model' match='exact' check='full'> <topology sockets='1' cores='1' threads='1'/> <feature policy='require' name='hypervisor'/> </cpu> </domain>
- 修改前XML
<domain> <devices> <disk type="file" device="disk"> <driver name='qemu' type='qcow2'/> <target bus="virtio" dev="vda"/> </disk> <disk type="file" device="cdrom"> <target bus="ide" dev="hdc"/> <driver name='qemu' type='raw'/> </disk> <disk type="file" device="disk"> <driver name='qemu' type='qcow2'/> <target bus="ide" dev="vdb"/> </disk> <disk type="file" device="disk"> <driver name='qemu' type='qcow2'/> <target bus="virtio" dev="vdc"/> </disk> </devices> </domain> - XML
Hook
def config_virtio_disk_queue_number(root, queue_number, hook): def config_disk_queue_number(disk): for driver in disk.findall("driver"): hook.set_value_of_attribute(driver, "queues", str(queue_number)) # find virtio_disks from all_disks for devices in root.findall("devices"): for disks in devices.findall("disk"): for target in disks.findall("target"): bus = hook.get_value_of_attribute(target, "bus") if bus == "virtio": config_disk_queue_number(disks) config_virtio_disk_queue_number(root, 4, hook) - 通过XML
Hook修改后的XML
<domain> <devices> <disk type="file" device="disk"> <driver name='qemu' type='qcow2' queues="4"/> <target bus="virtio" dev="vda"/> </disk> <disk type="file" device="cdrom"> <target bus="ide" dev="hdc"/> <driver name='qemu' type='raw'/> </disk> <disk type="file" device="disk"> <driver name='qemu' type='qcow2'/> <target bus="ide" dev="vdb"/> </disk> <disk type="file" device="disk"> <driver name='qemu' type='qcow2' queues="4"/> <target bus="virtio" dev="vdc"/> </disk> </devices> </domain>
示例四:根据MTU值配置MAC地址
- 修改前XML
<domain> <devices> <interface type='default'> <mac address='fa:af:36:ba:c2:00'/> <mtu size='1500'/> </interface> <interface type='bridge'> <mac address='fa:88:98:8e:73:01'/> <mtu size='8888'/> </interface> </devices> </domain> - XML
Hook
def config_mac_address_by_mtu(root, hook, mac_address, expect_mtu_number): def config_mac_address(interface): for mac in interface.findall("mac"): hook.modify_value_of_attribute(mac, "address", mac_address) # find network (interface) card with specific mtu for devices in root.findall("devices"): for interface in devices.findall("interface"): for mtu in interface.findall("mtu"): mtu_number = hook.get_value_of_attribute(mtu, "size") if mtu_number == str(expect_mtu_number): config_mac_address(interface) config_mac_address_by_mtu(root, hook, "23:1a:d0:4e:3b:1e", 8888) - 通过XML
Hook修改后的XML
<domain> <devices> <interface type='default'> <mac address='fa:af:36:ba:c2:00'/> <mtu size='1500'/> </interface> <interface type='bridge'> <mac address='23:1a:d0:4e:3b:1e'/> <mtu size='8888'/> </interface> </devices> </domain>
示例五:配置云主机CPU拓扑
- 修改前XML
<domain> <cpu mode='custom' match='exact' check='full'> <topology sockets='32' dies='1' cores='4' threads='1'/> </cpu> </domain> - XML
Hook
def config_cpu_topology(root, sockets, dies, cores, threads, hook): for cpu in root.findall("cpu"): for topology in cpu.findall("topology"): hook.modify_value_of_attribute(topology, "sockets", str(sockets)) hook.modify_value_of_attribute(topology, "dies", str(dies)) hook.modify_value_of_attribute(topology, "cores", str(cores)) hook.modify_value_of_attribute(topology, "threads", str(threads)) config_cpu_topology(root, sockets=2, dies=1, cores=64, threads=1, hook=hook) - 通过XML
Hook修改后的XML
<domain> <cpu mode='custom' match='exact' check='full'> <topology sockets='2' dies='1' cores='64' threads='1'/> </cpu> </domain>
示例六:修改云主机CPU特性
- 修改前XML
<domain> <cpu mode='custom' match='exact' check='full'> <feature policy='require' name='x2apic'/> <feature policy='require' name='hypervisor'/> <feature policy='require' name='lahf_lm'/> </cpu> </domain> - XML
Hook
def config_cpu_feature(root, hook): for cpu in root.findall("cpu"): feature = hook.create_element("feature") hook.add_attribute(feature, "policy", "disable") hook.add_attribute(feature, "name", "svm") hook.add_element_to_parent(feature, cpu) config_cpu_feature(root, hook) - 通过XML
Hook修改后的XML
<domain> <cpu mode='custom' match='exact' check='full'> <feature policy='require' name='x2apic'/> <feature policy='require' name='hypervisor'/> <feature policy='require' name='lahf_lm'/> <feature policy='disable' name='svm'/> </cpu> </domain>
示例七:配置云主机QEMU参数
- 修改前XML
<domain> <cpu mode='host-passthrough' check='none'> <topology sockets='2' cores='2' threads='1'/> </cpu> <qemu:commandline> <qemu:arg value='-qmp'/> <qemu:arg value='unix:/var/lib/libvirt/qemu/zstack/af45d04006114268a7ed0801fc46e961.sock,server,nowait'/> </qemu:commandline> </domain> - XML
Hook
def hide_cpu_emulator(root, hook): for cpu in root.findall("cpu"): for child in list(cpu): cpu.remove(child) cpu.set("mode", "host-passthrough") cpu.set("check", "none") feature = hook.create_element("feature") hook.add_attribute(feature, "policy", "disable") hook.add_attribute(feature, "name", "hypervisor") hook.add_element_to_parent(feature, cpu) def config_namespace(root, hook): import xml.etree.ElementTree as etree etree.register_namespace("zs", "http://zstack.org") etree.register_namespace("qemu", "http://libvirt.org/schemas/domain/qemu/1.0") def hide_hardware_vendor(root, hook): qemu_namespace = {'qemu': 'http://libvirt.org/schemas/domain/qemu/1.0'} for cmd in root.findall('qemu:commandline', qemu_namespace): # for CPU if not cmd.find("qemu:arg[@value='-cpu']", qemu_namespace): cpu_cfg = hook.create_element("qemu:arg") hook.add_attribute(cpu_cfg, "value", "-cpu") hook.add_element_to_parent(cpu_cfg, cmd) # for HOST KVM if not cmd.find("qemu:arg[@value='host,kvm=off']", qemu_namespace): host_kvm_cfg = hook.create_element("qemu:arg") hook.add_attribute(host_kvm_cfg, "value", "host,kvm=off") hook.add_element_to_parent(host_kvm_cfg, cmd) # for BIOS-VENDOR if not cmd.find("qemu:arg[@value='-smbios']", qemu_namespace): bios_cfg = hook.create_element("qemu:arg") hook.add_attribute(bios_cfg, "value", "-smbios") hook.add_element_to_parent(bios_cfg, cmd) # for VENDOR type0_value = "type=0,vendor=LENOVO,version=FBKTB4AUS,date=07/01/2015,release=1.180" xpath_type0 = "qemu:arg[@value='{}']".format(type0_value) if not cmd.find(xpath_type0, qemu_namespace): vendor_cfg = hook.create_element("qemu:arg") hook.add_attribute(vendor_cfg, "value", type0_value) hook.add_element_to_parent(vendor_cfg, cmd) # for BIOS-FACTORY smbios_args = cmd.findall("qemu:arg[@value='-smbios']", qemu_namespace) if len(smbios_args) < 2: bios_cfg_2 = hook.create_element("qemu:arg") hook.add_attribute(bios_cfg_2, "value", "-smbios") hook.add_element_to_parent(bios_cfg_2, cmd) # for FACTORY type1_value = "type=1,manufacturer=LENOVO,product=30AH001GPB,version=ThinkStation P300,serial=S4M88119,uuid=cecf333d-6603-e511-97d5-6c0b843f98ba,sku=LENOVO_MT_30AH,family=P3" xpath_type1 = "qemu:arg[@value='{}']".format(type1_value) if not cmd.find(xpath_type1, qemu_namespace): factory_cfg = hook.create_element("qemu:arg") hook.add_attribute(factory_cfg, "value", type1_value) hook.add_element_to_parent(factory_cfg, cmd) config_namespace(root, hook) hide_cpu_emulator(root, hook) hide_hardware_vendor(root, hook) - 通过XML
Hook修改后的XML
<domain> <cpu mode='host-passthrough' check='none'> <topology sockets='2' cores='2' threads='1'/> <feature name="hypervisor" policy="disable"/> </cpu> <qemu:commandline> <qemu:arg value="-qmp"/> <qemu:arg value="unix:/var/lib/libvirt/qemu/zstack/af45d04006114268a7ed0801fc46e961.sock,server,nowait"/> <qemu:arg value="-cpu"/> <qemu:arg value="host,kvm=off"/> <qemu:arg value="-smbios"/> <qemu:arg value="type=0,vendor=LENOVO,version=FBKTB4AUS,date=07/01/2015,release=1.180"/> <qemu:arg value='-smbios'/> <qemu:arg value="type=1,manufacturer=LENOVO,product=30AH001GPB,version=ThinkStation P300,serial=S4M88119,uuid=cecf333d-6603-e511-97d5-6c0b843f98ba,sku=LENOVO_MT_30AH,family=P3"/> </qemu:commandline> </domain>
定时任务
概述
ZStack Cloud提供两种定时运维服务:定时任务和定时器。定时器和定时任务完全解耦,用户可按需创建不同规则的定时器、以及不同的定时任务,并将定时任务灵活加载到定时器或从定时器上卸载。
定时运维相关定义
- 定时任务:一种预设任务,在指定时间执行指定行为。与定时器配合使用。
- 加载到定时器上的任务条目。
- 支持选择性停用/启用/加载/卸载,可灵活处理生产环境中的特殊情况。
- 删除定时器后,该定时器上的定时任务将被卸载,定时任务可重新加载到其它定时器上。
- 定时任务的操作支持完整计入审计服务中。
- 定时器:承载定时任务的容器,尤其适用于长时间运行的操作。
- 承载定时任务的容器。
- 非常适用于长时间运行的操作,例如,为某个云主机定时创建快照。
- 删除定时器后,该定时器上的定时任务将被卸载,定时任务可重新加载到其它定时器上。
- 定时器的操作支持完整计入审计服务中。
注意事项
在生产环境中,建议单块磁盘的快照数量尽量控制在5以内,快照过多会影响云主机/云盘的IO性能、数据安全以及主存储容量,不建议进行高频的定时快照备份。如需长期备份,请选择灾备相关功能。
创建定时任务
在ZStack Cloud主菜单,点击,进入定时任务界面。点击创建定时任务,弹出创建定时任务界面。
- 名称:设置定时任务名称
- 简介:可选项,可留空不填
- 任务:选择任务类型。目前支持任务类型包括:启动云主机、停止云主机、重启云主机、创建云主机快照、创建云盘快照Note: 如创建停止云主机定时任务,请注意,云主机因为定时任务关机后,即使启用高可用功能,也不会自动重启。
- 快照类型:选择任务类型为创建云主机快照时,需选择快照类型。支持创建单盘快照或快照组。单盘快照仅对云主机根云盘创建快照,快照组则对云主机根云盘及加载的数据云盘创建快照Note:
- 定时任务创建的快照组不包含云主机内存快照
- 创建快照组需确保云主机根云盘和数据云盘均在Ceph主存储上。定时任务创建完成后,如迁移云主机/数据云盘至非Ceph主存储,或为云主机加载非Ceph主存储上的数据云盘,定时任务将执行失败。
- 不支持为加载共享云盘的云主机创建快照组。如在创建定时快照组任务后为云主机加载共享云盘,定时任务将执行失败。
- 云主机/云盘:选择执行任务的云主机/云盘,可多选Note: 如选择的任务类型是创建云主机快照或创建云盘快照,请注意:
- 此处不支持选择已绑定CDP任务的云主机/云盘。
- 此处不支持选择已有定时快照任务的云主机/云盘。
- 如快照类型为快照组,且云主机加载的数据云盘已有定时快照任务,则此处不支持选择该云主机。
- 保留快照数量:设置快照允许保留的最大数量Note:
- 仅当云主机系统盘在Ceph主存储时支持设置,且保留数量不包括云主机系统盘手动快照。
- 保留快照数量范围:1~32。
- 定时器:可选项,加载合适的定时器到定时任务

管理定时任务
在ZStack Cloud主菜单,点击,进入定时任务界面。
定时任务支持以下操作:
| 操作 | 描述 |
|---|---|
| 创建定时任务 | 创建一个新的定时任务。 |
| 编辑定时任务 | 编辑定时任务的名称、简介信息。 |
| 启用定时任务 | 启用处于停用状态的定时任务。 Note: 启用定时任务,启动后该定时任务生效。 |
| 停用定时任务 | 停止选中的定时任务。 Note: 停用定时任务,停用后该定时任务不生效。 |
| 加载定时器 | 将定时任务加载到运行的定时器上。 |
| 卸载定时器 | 将定时任务从定时器上卸载。 |
| 删除定时任务 | 删除选中的定时任务。 Note: 删除该定时任务,不可恢复,请谨慎操作。 |
定时器
了解定时器
创建定时器
在ZStack Cloud主菜单,点击 。点击 创建定时器按钮,弹出创建定时器界面。
- 名称:设置定时器名称
- 简介:可选项,可留空不填
- 设置定时器执行方式有以下两种方式:
- 执行方式:选择按周期执行
- 执行策略:设置定时器执行周期Note: 需输入整数。时间单位:分钟/小时/天。
- 开始时间:可按需更改,开始时间不能小于当前时间
- 执行策略:设置定时器执行周期
- 执行方式:选择按次执行Note: 对于周期内有限次执行的定时器,当定时任务执行完后,定时器状态将显示为已完成。
- 执行策略:设置定时器执行次数和时间Note: 需输入整数。时间单位:分钟/小时/天。
- 开始时间:可按需更改,开始时间不能小于当前时间
- 执行策略:设置定时器执行次数和时间
- 执行方式:选择按周期执行


管理定时器
在ZStack Cloud主菜单,点击,进入定时器界面。
定时器支持以下操作:
| 操作 | 描述 |
|---|---|
| 创建定时器 | 创建一个新的定时器。 |
| 编辑定时器 | 编辑定时器的名称、简介信息。 |
| 修改定时器配置 | 修改定时器的执行方式、开始时间、执行策略。 |
| 删除定时器 | 删除选中的定时器。 Note: 删除定时器后,定时器上的定时任务将被卸载,定时任务可重新加载到其它运行的定时器上。 |


