背景知识
一句话总结
使用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-2mkdir -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