saltstack之virt模块创建虚拟机分析

简介:

虚拟管理机: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的配置文件处,设置如下

wKiom1SFgRvCdBz8AABce4FibDE660.jpg

通过salt 'kvm.tiancity.com' config.get libvirt:hypervisor,我们将会获取到zzj这个值。

wKiom1SFgYXRTu_mAABF04z3b_8488.jpg

在这里,我不需要设置,因为我的虚拟管理机用的就是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代码噢。


你看我的结果:

wKioL1SIK-ewtZxhAABVjns0u4g281.jpg


wKioL1SIK_zAc0eGAABZJVR4SFg111.jpg




本文转自hahazhu0634 51CTO博客,原文链接:http://blog.51cto.com/5ydycm/1587645,如需转载请自行联系原作者
相关文章
|
7月前
|
Java 编译器
【面试题精讲】int i=0;i=i++,从底层虚拟机角度分析答案
【面试题精讲】int i=0;i=i++,从底层虚拟机角度分析答案
|
存储 安全 Java
【新】虚拟机深层系「GC本质底层机制」SafePoint 的深入分析和底层原理探究指南
【新】虚拟机深层系「GC本质底层机制」SafePoint 的深入分析和底层原理探究指南
140 0
|
存储 缓存 监控
「作者推荐!」JVM研究系列-虚拟机分析与调优技巧分析(回顾篇)
「作者推荐!」JVM研究系列-虚拟机分析与调优技巧分析(回顾篇)
173 0
「作者推荐!」JVM研究系列-虚拟机分析与调优技巧分析(回顾篇)
|
存储 Java
【JVM原理探索】带你梳理分析虚拟机栈映射源代码的流程
【JVM原理探索】带你梳理分析虚拟机栈映射源代码的流程
110 0
【JVM原理探索】带你梳理分析虚拟机栈映射源代码的流程
|
存储 算法 Java
Java虚拟机-逃逸分析(Escape Analysis)和栈上分配
Java虚拟机-逃逸分析(Escape Analysis)和栈上分配
193 0
Java虚拟机-逃逸分析(Escape Analysis)和栈上分配
|
Ubuntu 编译器 Shell
Hi3516开发笔记(三):Hi3516虚拟机基础环境搭建之交叉编译环境境搭建以及开机启动脚本分析
Hi3516开发笔记(三):Hi3516虚拟机基础环境搭建之交叉编译环境境搭建以及开机启动脚本分析
Hi3516开发笔记(三):Hi3516虚拟机基础环境搭建之交叉编译环境境搭建以及开机启动脚本分析
|
安全 Java Linux
从 Hotspot 虚拟机角度来分析 Java 线程启动
从 Hotspot 虚拟机角度来分析 Java 线程启动
从 Hotspot 虚拟机角度来分析 Java 线程启动
J3
|
存储 缓存 安全
聊聊虚拟机的垃圾回收算法细节问题-根节点枚举、安全点、安全区、记忆集与卡表、写屏障、并发可达性分析中的三色标记法
聊聊虚拟机的垃圾回收算法细节问题-根节点枚举、安全点、安全区、记忆集与卡表、写屏障、并发可达性分析中的三色标记法
J3
269 0
聊聊虚拟机的垃圾回收算法细节问题-根节点枚举、安全点、安全区、记忆集与卡表、写屏障、并发可达性分析中的三色标记法
|
算法 Java
Java 虚拟机原理】Class 字节码二进制文件分析 七 ( 局部变量表分析 )(二)
Java 虚拟机原理】Class 字节码二进制文件分析 七 ( 局部变量表分析 )(二)
121 0
Java 虚拟机原理】Class 字节码二进制文件分析 七 ( 局部变量表分析 )(二)
|
Java 数据挖掘
Java 虚拟机原理】Class 字节码二进制文件分析 七 ( 局部变量表分析 )(一)
Java 虚拟机原理】Class 字节码二进制文件分析 七 ( 局部变量表分析 )(一)
177 0
Java 虚拟机原理】Class 字节码二进制文件分析 七 ( 局部变量表分析 )(一)