gushiren

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Cloudinit通过云平台的metadata服务或ConfigDrive等数据源拿到该userdata后,首先会对其进行切分,
并分别供各模块处理。
Cloud中所有模块都放在/usr/lib/python2.6/site-packages/cloudinit/config。
有配置文件可知主要分为如下三大类:cloud_init_modules、cloud_config_modules、cloud_final_modules、
system_info。

这里需要特别提到的一个模块是scripts-user,该模块负责执行userdata中的user scripts内容以及其他模块
(如runcmd)生成的脚本,因此cloudinit的配置文件将其放在了cloud_final_modules阶段的近乎最后。

Cloud配置文件主要分为两部分:

1、参数、变量定义部分。

2、模块列表部分。

常见的配置包括:设定虚拟机的hostname、hosts文件、设定用户名密码、更新apt-get的本地缓存、
调整文件系统的大小(注意不是调整分区的大小)等。

配置文件:/etc/cloud/cloud.cfg 。

cloudinit会在虚拟机启动的过程中分四个阶段运行,按照时间顺序分为:cloud-init-local, cloud-init,
 cloud-config, cloud-final。

cloud-init-local阶段主要是运行本地的一些初始化脚本。cloud-init, cloud-config, cloud-final
阶段分别执行配置文件中名为cloud_init_modules、cloud_config_modules、cloud_final_modules下的所有模块,
如果模块列表为空,则什么都不运行。

各模块在运行时,会根据之前定义的变量/参数的值,配置虚拟机的状态。

update_etc_host模块,/usr/lib/python2.6/site-packages/cloudinit/config/cc_update_etc_hosts.py。
该模块用来设置主机的hosts文件,其中就用到了hostname、fqdn、manage_etc_hosts等变量的值。
模块首先尝试从cloudinit的配置文件中读取这些变量的值,如果没有定义,
则尝试从其他的数据源中获取变量的值,例如对于openstac来讲,
可以从metadata service(http://169.254.169.254/latest/meta-data/hostname)获取虚拟机的主机名。
如果初始模板没有配置此参数,则可以通过创建虚机时的--user-data参数获取相应的参数值)。


4.2. 实例讲解

以主机名写入hosts文件为例进行介绍:

一、模板初始配置

未经设置的hosts文件



/etc/cloud/cloud.cfg配置文件里设置

manage_etc_hosts: True

preserve_hostname: False

manage_etc_hosts设置为true,虚机启动的时候cloud_init_modules阶段运行update_etc_hos模块,
获取变量值和相应的参数值。模板文件/etc/cloud/templates/hosts.redhat.tmpl被利用,



重写hosts文件如下:



二、以自定义脚本添加

如果出事模板里没有设置,可以通过nova boot创建虚机的时候指定--user-data参数获取配置值。

nova  boot testhostname --flavor 6 --image d892728d-3652-49ca-a943-e8006b0cbbb2 \
--nic net-id=f4889f14-33ab-4345-b480-92db1d411a67 --user-data /root/img/pass.txt

或通过horizon页面创建虚机时指定脚本如下:

#cloud-config

chpasswd:

  list: |

    root:123456

  expire: False

ssh_pwauth: True

manage_etc_hosts: True

preserve_hostname: False



将全域名、主机名成功写入hosts文件:


5. 部分脚本、配置示例

可以有配置文件cloud-config或者直接以脚本形式给出.
5.1. 修改root用户密码

#cloud-config

chpasswd:

  list: |

    root:123456

  expire: False

ssh_pwauth: True


5.2. 创建新用户、ssh登陆

#!/bin/bash
 
echo "one test about user data" >>userdata 
 
chmod 777 userdata 
 
useradd -m me 
 
echo -e 'me\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers

passwd me <<EOF

abcabc

abcabc

EOF

sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config

service ssh restart


5.3. 全域名、主机名写入hosts文件

#cloud-config

chpasswd:

  list: |

    root:123456

  expire: False

ssh_pwauth: True

manage_etc_hosts: True

preserve_hostname: False


Cloud-init 能够通过访问这些 URL 来获取其所需要的信息, 然后再进行配置. 
但是需要说明的一点是 169.254.169.254 这个 IP 实际是不存在的, 
本质上提供 metadata 的是 nova-api service, 
所以通常都需要设定防火墙 DNAT 将 169.254.169.254 映射到 nova-api-service-ip:port 这个 IP.

Cloud-Init 还会按照上述模块列表的顺序来进行配置, 
这是因为有些模块的执行对虚拟机操作系统当前的状态是有要求的, 后面模块的配置可能需要前面模块的配置做支撑.

而且, 模块列表中的模块具有多种运行模式:

    per-once: 仅执行一次, 在执行完毕之后会在 sem 目录中创建一个信号文件, 防止在下次启动虚拟机时重复执行.
    per-always: 每次启动都会执行
    per-instance: 每一个虚拟机都会执行

EG.

cloud_final_modules:
 - scripts-per-once
 - scripts-per-boot
 - scripts-per-instance
 metadata 和 userdata 的区别
 其实 userdata 与 metadata 本质上都是提供配置信息的数据源, 使用了相同的信息注入机制, 
 只是两者代表了不同的信息类型而已:

    metadata 主要提供了虚拟机的常用属性, EG. hostname/network/SSH/…, 其以 key/value 的形式进行注入,
    所以非常适合应用到 REST 的场景中.

    userdata 主要提供了 Shell 相关的 CLI 和 Script 等, 其通过文件的方式进行注入, 
    支持多种文件格式(EG. gzip/Bash/cloud-init/…).

所以, 两者的区别仅在于虚拟机在获取到信息后, 对两者的处理方式不尽相同而已.

metadata 的服务机制
ConfigDrive

手动指定使用 ConfigDrive:

nova boot --config-drive=true ...


启动虚拟机时, 使用 --config-drive=true 就是使用 ConfigDrive 机制来注入 metadata 信息.

修改配置文件默认使用 ConfigDrive:
vim /etc/nova/nova.conf

[DEFAULT]
...
force_config_drive = True


ConfigDrive 机制: OpenStack 会将 metadata 信息写入虚拟机的特殊设备中, 然后在虚拟机启动时, 
会将该设备挂载到虚拟机上并由 Cloud-init 读取内含的 metadata 信息, 从而实现信息注入. 

posted on 2018-08-21 15:24  gushiren  阅读(2120)  评论(0编辑  收藏  举报