云计算国产化之路 vnc登录 文件系统直通(virtio-9p) 扩展qemu接口 gpg WARNING 珍藏博客 虚拟内存情况dommemstat分析 免密码自动登录脚本 Linux网桥 测试网段IP占用情况 Linux 进程状态 systemc强制依赖 调试openstack ut uefi p2v 重做ubuntu内核 virsh创建虚拟机简介 virtio IO路径 虚拟化层升级后磁盘无法卸载卷 vmtouch使用 Taint flags 主机和虚拟机文件共享处理的几种方法 kvm分析工具 kvm中对磁盘的io cache 虚拟化不同导致的guestos中软件安装差异(未解决) 设备直通(PCI Assignment)到底是咋整的 virtio到底是咋整的 内核启动参数 虚拟化实时性提升(零)之配置步骤 中断虚拟化(pic)到底是咋整的 中断虚拟化(apic)到底是咋整的 Raid卡配置丢失导致服务器无法启动 tainted kernels cpu stuck for 23s问题分析 虚拟化实时性提升(一)之hostOS切换为强实时系统 内存虚拟化到底是咋整的 qemu-kvm中vcpu虚拟化到底是咋整的 风河虚拟化技术点分析 使用qga的好处 qemu迁移代码分析 虚拟机串口配置及其导出到主机pts和console.log System-based I/O vs. Raw I/O 虚拟机使用Hugepage(大页) 硬件辅助分页(hardware assisted paging) 修改centos7默认启动项目 virtio的工作流程——kernel中virtio-pci初始化(2) virtio的工作流程——qemu中virtio-backend初始化(1) qmp ceilometer取不到memory.usage指标 Virtio-Balloon超详细分析 slabtop输出 虚拟机磁盘cache导致的host os kernel崩溃 虚拟机cpu和memory性能优化测评 PCI配置空间(PCI Configuration Space) centos下网卡设备直通(VT-dpci passthrough)遇到的问题及其解决思路 libguestfs详解 yum卸载软件包及其依赖 通过原始Centos ISO来定制自己的ISO centos下网卡设备直通(VT-d,pci passthrough) (占位符)window虚拟机中拔盘如何通知到libvirt和qemu后端的 cirrus漏洞分析CVE-2017-2615 XSA-208 qcow2随笔 控制寄存器概览 ceilometer对接postgresql 解压initrd和vmlinuz qemu guest agent验证 QEMU升级指南(待续) ubuntu中kdump的配置 qemu(2.3)接口梳理 热迁移导致的FC存储场景下的multipath卷残留问题分析 virsh命令(4)secret,snapshot,pool,volume部分 virsh命令(3)之interface,filter,network virsh命令(2)monitor,host,nodedev部分 virsh命令(1)之domain部分 QEMU内存管理之FlatView模型(QEMU2.0.0) ovirt基于sanock的高可用(主机粒度HA) Sanlock防脑裂场景功能测试用例 gnocchi配置及与ceilometer对接指南 make patch for libvirt in centos centos使用sanlock指导 高可用nfs资料 ubuntu14中使用sanlock指导 LVM操作指南 sanlock相关功能验证流程汇总 make patch for libvirt in ubuntu libvirt.so.0-version `LIBVIRT_PRIVATE_1.2.7' not found gdb debug libvirt 基于ubuntu社区源码包编译libvirt compile libvirt(centos) No PCI buses available nfs lead to Linux halt nfs install and config anti-virus for cloud platform nova fetch image from glance(something about _base) token auth process ovs入门指南 virt software anti-virus something about ceilometer disk sample context interview questions openstack vm injection openstack Restful and RPC murano 概览 创建虚拟机流程(compute节点)之网络创建 创建虚拟机流程之compute_api之虚拟机实例填充之配额检测 创建虚拟机流程之compute_api之基本参数生成 创建虚拟机流程之compute_api 创建虚拟机流程(主) 创建虚拟机之image 创建虚拟机流程之准备网桥 创建虚拟机流程之virt 创建虚拟机流程之compute节点 CI/CD研发流程之工程创建 CI/CD研发流程之代码合入 CI/CD研发流程之UT(单元测试) 向openstack社区合入代码记 openstack/ceilometer/gnocchi杂谈 影子页表原理 mem_add(exec.c) qemu编译安装调试 openstack/ceilometer/gnocchi之Grafana简介 openstack wiki etcd openstack计量ceilometer openstack计费cloudKitty enventlet backdoor USB 安装VMWARE ESX pycharm设置指南 无法执行modprobe -a kvm-intel解决办法 QEMU配置项 网络不通小记 libvirt之XML(虚拟机定义文件) openstack-horizon 证书认证 ceilometer与ceph对接 openstack定时任务剖析(TODO) 服务器重启后mongodb进程无法启动 ubuntu14下新增openstack服务到service的导引 ERROR 1045(28000)-数据库连不上 Python两个内置函数—locals和globals unknown exit, hardware reason 31

openstack vm injection

2016年05月13日

背景知识

一句话总结

使用cloud-init的config-drive类型数据源实现注入

老的方式是:
使用libguestfs或者其他方式操纵vm的磁盘,向里面写入东西
如密钥注入是向磁盘的.ssh目录写入密钥的公钥

注入方式

  • –meata 注入meatadata
  • –file 注入文件
  • –key-name 注入密钥
  • –nic 在需要的时候注入网卡信息

openstack代码流程

nova-client

将对应参数传给_boot()
下面这三个参数直接放到body中

files参数需要使用base64做下编码

nova-api

然后把这些参数传入compute_api

compute-api

根据key_name获取到key_data,后续都使用key_data,一开始没有注意到这里,导致线索中断卡了好久。

基本信息校验,并将数据暂存至base_options中

信息整合到instance对象中

注入文件,需要校验注入文件的长度信息

nova-conductor

消息发向nova-compute节点

nova-compute

解密injectfiles

调用虚拟化层

driver层

_create_image中根据配置的不同会走不同的分支

config-drive 控制注入的情况

config-drive的目的是将虚拟机的元信息通过一种尽量稳定,方便暴露给客户机操作系统(虚拟机操作系统)
虚拟机启动的时候,假如镜像安装了cloud_init则会读取disk.config文件,进而实现相关内容的注入
当使用config-drive时,上述流程会走下面这里

基本上就是将注入的内容,按照格式写入文件,形成iso9660或者vfat格式的文件。

  • 这里需要注意:
    devstack场景下,force_config_drive会打开

    也就是说devstack场景下,会使用config-drive进行数据注入。
    当然,也可以通过nova-boot传递config-drive参数

    $ nova boot –config-drive true –image my-image-name –key-name mykey \
    –flavor 1 –user-data ./my-user-data.txt myinstance \
    –file /etc/network/interfaces=/home/myuser/instance-interfaces \
    –file known_hosts=/home/myuser/.ssh/known_hosts \
    –meta role=webservers –meta essential=false
    上面这条命令启用config-drive功能,并基于config-drive传入
    user-data并且注入两个文件,两个键值对的metadata。

    假如虚拟机的os支持标签(label)访问,可以将config-drive用mount挂在为
    /dev/disk/by-label/configurationDriveVolumeLabel
    比如下例配置为config-2

    mkdir -p /mnt/config mount /dev/disk/by-label/config-2 /mnt/config

  • 注意
    config-drive 只能在创建虚拟机时指定,之后即使修改了虚拟机的信息
    config-drive 的内容也不会发生变化,hard-reboot 之后也不会发生变化

参考文档:
http://docs.openstack.org/user-guide/cli_config_drive.html
http://cloudinit.readthedocs.io/en/latest/topics/datasources.html#version-2

inject_partition控制注入的情况(这种情况现在默认关闭)


需要注意的是,这里inject_files是一个boolean型的变量,默认是True
也就是说,需要根据CONF.libvirt.inject_partition != -2是否会走向这里
默认CONF.libvirt.inject_partition为 -2

默认情况下不允许注入密钥,需要手动配置打开

默认页不允许注入admin密码

使用nova/virt/interfaces.template格式化网卡信息

存在任何一种注入的情况,会调用disk.inject_data

尝试加载nova.virt.disk.vfs.guestfs.VFSGuestFS
不成功则加载nova.virt.disk.vfs.localfs.VFSLocalFS
也就是下文的fs,然后调用inject_data_into_fs利用fs去注入相关内容

根据注入的类型不同,选择不同的注入方法

  • 密钥注入_inject_key_into_fs
    目录是/root/.ssh,也就是将公钥写到.ssh目录下
    登陆虚拟机的时候,公钥加密,用登陆段的私钥解密,即可实现登陆功能
    另外,需要注意下selinux
    seclinux详细参考鸟哥私房菜
    大体意思是在rc.local中增加一段脚本,用restorecon命令恢复/etc/.ssh目录的权限,使得公钥可读
    虚拟机启动的时候会去执行rc.local下的脚本(不论sysvinit或者upstart)

  • 网卡注入_inject_net_into_fs
    将网卡信息写入/etc/network/interfaces

  • admin密码注入_inject_admin_password_into_fs
    写配置文件/etc/passed和/etc/shadow

  • metadata注入_inject_metadata_into_fs

  • 文件注入

  • 注:
    这种方式现在默认关闭,推荐使用config-drive及其metadata进行注入。
    要是执意使用这种方式,需要将inject_partition配置为非-2