config drive and cloud-init

本文探讨了OpenStack中镜像制作与个性化配置的方法,介绍了如何利用cloudinit实现虚机启动时的自动配置,并详细解析了configdrive的工作流程。

在config drive和cloud init之前,先要从制作镜像说起。

一般情况下,我们可以从ubuntu或者fedora等的官网上下载镜像,启动虚机时从镜像启动即可,前面提过启动instance,root disk,swap等的意义,在开发项目

的过程中,如果我们希望自己的镜像中自带某些已经安装好的服务,一些库,或者一些通用的配置文件等,除了使用cloud init,这个之后会说,其实制作自己的

镜像一直都是个不错的方法,没有复杂的配置,虽然灵活性上差一些,但不失为一个好办法。

mark link 1 中是官网的镜像制作过程,有Centos,ubuntu,windows,FreeBSD,Fedora,过程十分详细。

使用vish命令,创建一个磁盘镜像,将系统装到创建的磁盘镜像中,启动系统进行定制化的服务安装,做一些处理之后,创建的磁盘镜像就可以导入openstack做image了。


通过镜像我们可以添加自己的服务,但是有些元数据是变化的,随着不同用户而定制的,我们不可能为了每个用户都去做一个镜像,怎么办呢,于是有了cloud init。

mark link 2是一篇不错的文章,制作镜像时候会安装cloud init并进行配置,它仅在镜像启动(虚机启动)时运行,就像一个agent一样,从各种数据源读取相关数据

并据此对虚拟机进行配置。常见的数据源包括:云平台的metadata服务、ConfigDrive等,常见的配置包括:设定虚拟机的hostname、hosts文件、

设定用户名密码、更新apt -get的本地缓存、调整文件系统的大小(注意不是调整分区的大小)等。


所以这里关系理顺了,使用cloud init做定制化配置,配置的数据源是configDrive,从哪里看合适呢?

还是从client看,openstack的东西,网上能搜到实例,更加实例分析最容易,找不到实例,通过test case看其次,从client看最佳,前面提到从test看大系统

的全局是很好的入口,而openstack的client则是除了发布的rest 文档之外最好的文档。


在novaclient中有三个参数比较感兴趣:

'--user-data',

'--file',

'--config-drive',

在novaclient/v2/shell.py中的do_boot创建新的instance方法:cs.servers.create(*boot_args, **boot_kwargs),在client.py中:

self.servers = servers.ServerManager(self)

在ServerManager的create方法中:

if userdata:
            。。。。
            userdata_b64 = base64.b64encode(userdata).decode('utf-8')
            body["server"]["user_data"] = userdata_b64

if files:
            personality = body['server']['personality'] = []
            for filepath, file_or_string in sorted(files.items(),
                                                   key=lambda x: x[0]):
                if hasattr(file_or_string, 'read'):
                    data = file_or_string.read()
                else:
                    data = file_or_string

                if six.PY3 and isinstance(data, str):
                    data = data.encode('utf-8')
                cont = base64.b64encode(data).decode('utf-8')
                personality.append({
                    'path': filepath,
                    'contents': cont,
                })

if config_drive:
            body["server"]["config_drive"] = config_drive

这也就是我们在nova中nova/api/openstack/compute/server.py看到:

        config_drive = None
        if self.ext_mgr.is_loaded('os-config-drive'):
            config_drive = server_dict.get('config_drive')

        if personality:
            injected_files = self._get_injected_files(personality)

       user_data = self._extract(server_dict, 'os-user-data', 'user_data')
           self._validate_user_data(user_data)

所以--file变成了personality字段,成为inject file. 我们trace nova创建instance的过程,会先在数据库中创建instance的实例,其中user data和config drive(true false,

0或者1)会作为属性成为instance的数据库中记录。

一致trace到Virt Driver创建虚机,这里是LibVirt:

self._create_image(context, instance,   #user data和config drive在这里
                           disk_info['mapping'],
                           network_info=network_info,
                           block_device_info=block_device_info,
                           files=injected_files,    #--file 参数
                           admin_pass=admin_password)

重点在于这一段:

        # Config drive
        if configdrive.required_by(instance):   #如果config drive是True或者CONF.force_config_drive是always,或者image_prop == 'mandatory'

              #可以tracerequired_by函数                                       
            LOG.info(_LI('Using config drive'), instance=instance)
            extra_md = {}
            if admin_pass:
                extra_md['admin_pass'] = admin_pass

            inst_md = instance_metadata.InstanceMetadata(instance,
                content=files, extra_md=extra_md, network_info=network_info)
  #将user data和inject files传入InstanceMetadata
            with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb:
                configdrive_path = self._get_disk_config_path(instance, suffix)
                LOG.info(_LI('Creating config drive at %(path)s'),
                         {'path': configdrive_path}, instance=instance)

                try:
                    cdb.make_drive(configdrive_path)

                    #首先调用self._write_md_files(tmpdir),将user data等写到一个tmp dir中

                   #再调用_make_iso9660或者_make_vfat,一般是前者,支持更好,生成一个镜像挂载到image上

                except processutils.ProcessExecutionError as e:
                    with excutils.save_and_reraise_exception():
                        LOG.error(_LE('Creating config drive failed '
                                      'with error: %s'),
                                  e, instance=instance)


到这里,cloud init在哪里派上用场呢,在instance boot起来时候,cloud init会从数据源中读取user data和meta data,这里的数据源就是前面千辛万苦得到

的config drive,而这些是linux在boot时候的动作,可以在mark link中看cloud init的配置和user data文件的写法等等。


openstack很多思想来源于AWS,这个必须承认,使用镜像,cloud init(配合config drive使用),使得instance的定制化和灵活性变得不输给AWS了。

终于写完这一篇了,几次想trace完都耽搁了,move!


mark link

1. http://docs.openstack.org/image-guide/content/centos-image.html

2.http://www.it165.net/os/html/201404/7848.html


3. https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux_OpenStack_Platform/4/html/End_User_Guide/config-drive.html
4. http://www.chenshake.com/about-openstack-centos-mirror/
5. http://www.scalehorizontally.com/2013/02/24/introduction-to-cloud-init/
6. http://cloudinit.readthedocs.org

7. http://longgeek.com/2014/05/19/openstack-trove-dedicated-mirror-making/#i

8.http://mathslinux.org/?p=591

<think> 根据用户的问题和提供的引用内容,用户想要了解如何手动指定cloud-init的数据源。虽然提供的引用中没有直接关于cloud-init手动指定数据源的内容,但根据我对cloud-init的了解,以下是手动指定数据源的方法: 在cloud-init中,数据源(datasource)是指cloud-init获取实例元数据的来源,例如OpenStack、AWS、Azure等。默认情况下,cloud-init会自动检测运行环境并选择合适的数据源。但有时需要手动指定,例如在调试或特殊环境中。 ### 手动指定cloud-init数据源的方法: 1. **使用内核命令行参数** 在GRUB配置或内核启动参数中添加`cloud-init.datasources`参数: ```bash # 在GRUB_CMDLINE_LINUX中添加(例如Ubuntu系统) GRUB_CMDLINE_LINUX="cloud-init.datasources=['ConfigDrive', 'OpenStack']" ``` 然后更新GRUB并重启: ```bash sudo update-grub sudo reboot ``` 2. **通过配置文件指定** 在`/etc/cloud/cloud.cfg`或`/etc/cloud/cloud.cfg.d/`目录下的配置文件中设置: ```yaml # 例如:/etc/cloud/cloud.cfg.d/90_datasources.cfg datasource_list: [ ConfigDrive, OpenStack, NoCloud ] ``` 然后重启cloud-init服务: ```bash sudo systemctl restart cloud-init ``` 3. **优先级说明** cloud-init按以下顺序选择数据源: - 内核命令行参数(最高优先级) - 配置文件中的`datasource_list` - 自动检测(最低优先级) 4. **调试方法** 使用`cloud-init`命令查看当前使用的数据源: ```bash sudo cloud-init query datasource ``` > **注意**:手动指定时需确保数据源名称正确,常见名称包括: > - `NoCloud`(用于本地镜像或ISO) > - `ConfigDrive`(OpenStack常用) > - `OpenStack` > - `Azure` > - `Ec2`(AWS) ### 验证配置 查看日志确认数据源是否生效: ```bash sudo tail -f /var/log/cloud-init.log # 搜索"Datasource"关键字 ``` ### 参考示例 在OpenStack环境中强制使用`ConfigDrive`(当同时存在元数据服务和配置驱动器时): 1. 修改配置文件: ```yaml # /etc/cloud/cloud.cfg.d/80_datasource.cfg datasource_list: [ ConfigDrive ] ``` 2. 重启服务: ```bash sudo cloud-init clean # 清除缓存 sudo systemctl restart cloud-init ``` §§相关问题§§ 1. cloud-init如何自动检测云平台? 2. 如何为cloud-init添加自定义数据源? 3. 在混合云环境中如何配置多数据源? 4. cloud-init常见数据源故障如何排查? [^1]: cloud-init官方文档 - 数据源配置 </think> ### Cloud-init 手动指定数据源方法详解 Cloud-init 的数据源(datasource)是指虚拟机启动时获取元数据的来源(如 OpenStack、AWS 等云平台)。以下是手动指定数据源的三种方法: #### 一、内核启动参数指定(最高优先级) ```bash # 在GRUB配置中添加(以Ubuntu为例) sudo nano /etc/default/grub ``` 修改配置项(指定OpenStack和ConfigDrive两种数据源): ```bash GRUB_CMDLINE_LINUX="cloud-init.datasources=['OpenStack', 'ConfigDrive']" ``` 更新并重启: ```bash sudo update-grub sudo reboot ``` #### 二、配置文件覆盖(推荐方式) 1. 创建配置文件: ```bash sudo nano /etc/cloud/cloud.cfg.d/90_datasources.cfg ``` 2. 添加内容(限制只使用NoCloud数据源): ```yaml # 数据源白名单 [^1] datasource_list: [ NoCloud ] ``` 3. 重启服务生效: ```bash sudo cloud-init clean # 清除缓存 sudo systemctl restart cloud-init ``` #### 三、运行时调试(临时测试) ```bash # 强制使用特定数据源执行 sudo cloud-init init --local -d -D -f -v -m "ConfigDrive" ``` 关键参数说明: ``` -d:调试模式 -D:输出完整日志 -m:指定数据源模块名 ``` #### 四、数据源类型对照表 | 数据源名称 | 适用场景 | 典型用例 | |----------------|-----------------------------|--------------------------| | `NoCloud` | 本地镜像/KVM虚拟化 | 开发环境测试[^1] | | `ConfigDrive` | OpenStack环境 | 私有云部署[^1] | | `OpenStack` | OpenStack元数据服务 | 公有云实例 | | `Ec2` | AWS云环境 | AWS EC2实例 | | `Azure` | Microsoft Azure环境 | Azure虚拟机 | #### 五、验证与调试 1. 查看当前使用数据源: ```bash cloud-init query datasource ``` 2. 检查加载过程日志: ```bash tail -f /var/log/cloud-init.log | grep "DataSource" ``` 3. 调试模式输出(显示详细加载顺序): ```bash sudo cloud-init init --local -d -D -f -v ``` #### 六、注意事项 1. **优先级规则**: $$ \text{内核参数} > \text{配置文件} > \text{自动检测} $$ 2. **混合云场景**配置示例: ```yaml # /etc/cloud/cloud.cfg.d/multi-ds.cfg datasource_list: - OpenStack - NoCloud - ConfigDrive ``` 3. 禁用自动检测(配置文件添加): ```yaml datasource: Azure: apply_network_config: false ``` > **故障排查**:若数据源加载失败,检查`/run/cloud-init/cloud-init-generator.log`中的错误日志[^1]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值