虚拟管理机:kvm/qemu
两种方式创建:
salt 'hypervisor' virt.init vm_name 4 512 salt://path/to/image.raw
salt 'hypervisor' virt.init vm_name 4 512 nic=profile disk=profile
先说第1种,此种方式是将Master上的镜像文件cp到kvm主机(此种方式依赖网络速),
执行命令如下:
salt 'kvm.tiancity.com' virt.init web10 4 512 salt://img/Template_Centos63x64.img
hypervisor = __salt__['config.get']('libvirt:hypervisor', hypervisor)
config.get获取数据的顺序如下:
- Local minion config (opts)
- Minion's grains
- Minion's pillar
- Master config
因为我没有在grains,pillar处设置libvirt:hypervisor,所以此处的值为hypervisor(默认值:hypervisor=VIRT_DEFAULT_HYPER,VIRT_DEFAULT_HYPER = 'kvm')
假设我在/etc/salt/minion的配置文件处,设置如下
通过salt 'kvm.tiancity.com' config.get libvirt:hypervisor,我们将会获取到zzj这个值。
在这里,我不需要设置,因为我的虚拟管理机用的就是kvm。哇....
nicp = _nic_profile(nic, hypervisor, **kwargs)
此处的函数会获取一个网卡相关属性列表,最后我会提供出来
# support old location
config_data = __salt__['config.option']('virt.nic', {}).get(
profile_name, None
)
if config_data is None:
config_data = __salt__['config.get']('virt:nic', {}).get(
profile_name, default
)
这段话的意思是说,如果你没有定义virt.nic变量,那么config_data为None
当config_data为None时,我们再判定有没有设置virt:nic,如果没有设置则取default
那么config_data=default(default = [{'eth0': {}}])
if isinstance(config_data, dict):
append_dict_profile_to_interface_list(config_data)
elif isinstance(config_data, list):
for interface in config_data:
if isinstance(interface, dict):
if len(interface.keys()) == 1:
append_dict_profile_to_interface_list(interface)
else:
interfaces.append(interface)
判定config_data是字典,还是列表,此处是列表,并且仅有1个键(如果有两块网卡呢?以后分析测试),执行append_dict_profile_to_interface_list(interface)
def append_dict_profile_to_interface_list(profile_dict):
for interface_name, attributes in profile_dict.items():
attributes['name'] = interface_name
interfaces.append(attributes)
此处意指:interfaces这个列表追加一个attributes字典.值interfaces=[{'name':'eth0'}]
for interface in interfaces:
_normalize_net_types(interface)
_assign_mac(interface)
if hypervisor in overlays:
_apply_default_overlay(interface)
_normalize_net_types(interface)将会为interfaces中的字典增加type和source属性,interfaces=[{'name':'eth0','type':None,'source':None}]
_assign_mac(interface)此处通过salt.utils.gen_mac()生成一个虚拟mac,并且更新interfaces=[{'name':'eth0','type':None,'source':None,'mac':'AC:DE:48:5D:9C:B4'}]
_apply_default_overlay(interface)将会更新interfaces=[{'name':'eth0','type':'bridge','source':'br0','mac':'AC:DE:48:5D:9C:B4','model': 'virtio'}]
并且返回interfaces,那么nicp的值就是interfaces
若指定image,
diskp = _disk_profile('default', hypervisor, **kwargs)
则返回diskp=[{'system':{'size':'8192','format':'qcow2','model':'virtio','pool':'/srv/salt-images'}}]
disk_name = diskp[0].keys()[0]
disk_type = diskp[0][disk_name]['format']
disk_file_name = '{0}.{1}'.format(disk_name, disk_type)
则disk_name=system,disk_type=qcow2,disk_file_name=system.qcow2
img_dir = __salt__['config.option']('virt.images')
img_dest = os.path.join(
img_dir,
name,
disk_file_name
)
img_dir = os.path.dirname(img_dest)
则:img_dest="/srv/salt-image/web10/system.qcow2",img_dir="/srv/salt-image/web10"
sfn = __salt__['cp.cache_file'](image, saltenv)调用cp.cache_file将image通过网络保存到
minion(也是kvm主机的)/var/cache/salt/minion/files/base/web10/system.qcow2
最后通过salt.utils.copyfile(sfn, img_dest)将
/var/cache/salt/minion/files/base/img/Template_Centos63x64.img此处的文件copy到
/srv/salt-image/web10/system.qcow2
xml = _gen_xml(name, cpu, mem, diskp, nicp, hypervisor, **kwargs)
这段很重要,这段生成了一个虚拟机简要的xml,不过,最重要的是构造了一个context的复杂数据,再通过JINJA的模板(libvirt_domain.jinja)渲染成xml.
context={'hypervisor':'kvm','mem':'524288','name':'web10','cpu':'4','controller_model':False,'boot_dev':['hd'],'disks':{'system':{'file_name':'system.qcow2','source_file':'/srv/salt-images/vm_name/system.qcow2','target_dev':'vda','address':False,'driver': True,'disk_bus':'virtio','type': 'qcow2','index': '0'}},'nics':[{'mac':'AC:DE:48:FE:01:BC','model':'virtio','name':'eth0','source':'br0','type':'bridge'}]}
生成的xml:
<domain type='kvm'>
<name>web10</name>
<vcpu>4</vcpu>
<memory unit='KiB'>524288</memory>
<os>
<type>hvm</type>
<boot dev='hd' />
</os>
<devices>
<disk type='file' device='disk'>
<source file='/srv/salt-images/vm_name/system.qcow2' />
<target dev='vda' bus='virtio' />
<driver name='qemu' type='qcow2' cache='none' io='native'/>
</disk>
<interface type='bridge'>
<source bridge='br0'/>
<mac address='AC:DE:48:FE:01:BC'/>
<model type='virtio'/>
</interface>
<graphics type='vnc' listen='0.0.0.0' autoport='yes' />
</devices>
<features>
<acpi />
</features>
</domain>
define_xml_str(xml)将以上的xml生成一个/etc/libvirt/qemu/web10.xml
后面那一段要不要安装salt-minion,最后一个create(name),就启动虚拟机喽。
注意:我的镜像文件格式为raw,不是qcow2,所以我将代码中的'format':'qcow2'改为
'format':'raw',注意噢,改的是minion的virt.py代码噢。
你看我的结果: