Cloudinit简介
cloudinit是专为云环境中虚拟机的初始化而开发的工具,它从各种数据源读取相关数据并据此对虚拟机进行配置。常见的数据源包括:云平台的metadata服务、ConfigDrive等,常见的配置包括:设定虚拟机的hostname、hosts文件、设定用户名密码、更新apt-get的本地缓存、调整文件系统的大小等。
Cloudinit数据源
Cloud-init github仓库地址:https://github.com/cloud-init/cloud-init
Cloud-init目前代码库中,已支持阿里云自定义的数据源:[‘http://100.100.100.200‘]
Cloudinit 如何判断虚拟机是初始化时的第一次启动?
Cloudinit主要通过读取/etc/cloud/cloud.cfg配置文件,来执行相应模块。模块一般位于python第三方包cloudinit目录下:/usr/lib/python2.6/site-packages/cloudinit/config
模块有多种运行模式(frequency),包括PER_INSTANCE, PER_BOOT, PER_ONCE ,PER_ALWAYS,在上述python文件中配置。
模式为per-once的模块,一旦运行完毕会在一个名为sem的目录中创建一个信号文件,从而防止模块的在下次启动时重复运行,若虚拟机初始化时,sem目录中不存在相应的信号文件,Cloudinit则会执行一次,以后都不会执行。
sem目录具体位置:
/var/lib/cloud/instances/实例ID/sem
Windows系统,主要由cloudbase-init读取注册表项判断是不是初始化。例如注入密码时,第一次注入之后会在注册表中更新HKEY_LOCAL_MACHINE/SOFTWARE/Cloudbase Sloutions/Cloudbase-Init/实例ID/Plugins/SetUserPasswordPlugin值为1,表示下次不再更新。如果需要从数据源读取密码重新注入,只需删除SetUserPasswordPlugin项目即可。
AWS EC2Config简介
AWS EC2Config是对cloudbase-init的封装。
EC2Config配置文件位于 C:\Program Files\Amazon\Ec2ConfigService\Settings 目录下:
- ActivationSettings.xml - 使用密钥管理服务器 (KMS) 控制产品激活。
- AWS.EC2.Windows.CloudWatch.json - 控制要发送到 CloudWatch 的性能计数器以及要发送到 CloudWatch Logs 的日志。有关如何更改此文件中的设置的更多信息,请参阅向 Amazon CloudWatch 发送日志、事件和性能计数器。
- BundleConfig.xml - 控制 EC2Config 为 AMI 创建准备实例存储支持的实例的方式。
- Config.xml - 控制基本设置。
- DriveLetterConfig.xml - 控制驱动器号映射。
- EventLogConfig.xml:控制实例启动时控制台上显示的事件日志信息。
- WallpaperSettings.xml:控制桌面背景上显示的信息。
如密码初始化在Config.xml 文件中配置,如下图所示:
Ec2SetPassword:在您每次启动实例时生成随机加密密码。默认情况下,首次启动之后该功能会被禁用,因此重新启动该实例并不会更改用户设置的密码。每次您启动实例时,请将该设置改为 Enabled,以继续生成密码。
http://docs.amazonaws.cn/AWSEC2/latest/WindowsGuide/UsingConfig_WinAMI.html
Cloudbase-init 的Plugin执行策略简述
Cloudbase-init的Plugin执行策略定义在cloudbase-init/cloudbaseinit/plugins/common/base.py文件。
PLUGIN_EXECUTION_DONE = 1
表示Plugin已经执行完成
PLUGIN_EXECUTE_ON_NEXT_BOOT = 2
表示Plugin在下次启动时执行
Plugin的执行策略可通过注册表进行配置,Cloudbase-init读取Plugin的注册表配置项流程如下。
步骤一:shell.py主入口函数,调用init.IniManager.configure_host()
cloudbase-init/cloudbaseinit/shell.py
步骤二:init.IniManager.configure_host(),调用_handle_plugins_stage()
cloudbase-init/cloudbaseinit/init.py
步骤三:_handle_plugins_stage(),调用_exec_plugin()
cloudbase-init/cloudbaseinit/init.py
步骤四: _exec_plugin(),调用_get_config_value()
cloudbase-init/cloudbaseinit/init.py
步骤五:_get_config_value(),调用osutils.get_config_value()
cloudbase-init/cloudbaseinit/init.py
步骤六:osutils.get_config_value()通过Python winreg模块读取注册表对应的Plugin值
OpenStack Windows实例使用cloudbase-init自动生成密码流程
Windows实例启动后,cloudbase-init执行各功能plugin,关于初始化密码流程简述如下
1. 访问http://169.254.169.254/openstack/latest/meta_data.json,获取实例元数据
(其中lastest、2013-04-04等是指版本号)
2. 执行SetUserSSHPublicKeysPlugin,获取SSH public keys并写入文件:C:\Users\Administrator.ssh\authorized_keys
3. 执行SetUserPasswordPlugin:
①生成随机密码;
②将密码设置给Windows Administrator用户;
③判断Nova metadata数据库是否已经保存密码自动(判断方法:get方法获取http://169.254.169.254/openstack/latest/password 数据,若无返回值则说明数据库未保存密码)
④使用SSH public key加密密码;
⑤将密文post给Nova metadata数据库(该接口服务端同时也会检查数据库中是否已保存密码,如果已保存,则拒绝写入,起到保护数据库的作用)。
注意,当安装上文步骤修改注册表值,重新初始化密码时会出现如下状况
- Windows Administrator用户密码已被重新初始化
- 无法通过GET /v2/{tenant_id}/servers/{server_id}/os-server-password 接口获取Windows实例密码
所以,当需要重新初始化Windows实例密码需要进行如下操作
- 调用 DELETE /v2/{tenant_id}/servers/{server_id}/os-server-password 接口,清除Nova metadata数据库中保存的密码
- 根据上文修改注册表项
- 重启。此时Windows Administrator密码已重新初始化,Windows实例密码也可顺利通过接口获取。
参考文献
http://cloudinit.readthedocs.io/en/latest/topics/debugging.html
http://blog.csdn.net/weiyuanke/article/details/23789069
https://github.com/cloud-init/cloud-init
https://github.com/openstack/cloudbase-init
http://www.cnblogs.com/davygeek/p/4579829.html
https://wiki.cloudbase.it/cloudbaseinit-doc
https://ask.cloudbase.it/question/1011/updating-windows-imagesysprep-how-to-rearm-clouldbase-init/
http://docs.ocselected.org/openstack-manuals/kilo/admin-guide-cloud/content/section_metadata-service.html