云实例初始化工具cloud-init简介
项目简介
cloud-init是一款用于初始化云服务器的工具,它拥有丰富的模块,能够为云服务器提供的能力有:初始化密码、扩容根分区、设置主机名、注入公钥、执行自定义脚本等等,功能十分强大。
目前为止cloud-init是云服务器初始化工具中的事实标准,它几乎适用于所有主流的Linux发行版,也是各大云厂商正在使用的默认工具,社区活跃。基于Python语言使得它能够轻易跨平台、跨架构运行,良好的语法抽象使得它适配新模块、新发行版十分容易。
基本概念
实例数据与数据源
实例数据(Instance data)是cloud-init用来处理并配置实例的数据集合。根据用途,可以将实例数据划分为如下三类:
- metadata:一系列字典格式的元数据,用作模板渲染、模块运行等等。
- userdata:启动实例时用户能够指定的数据(单实例数据)
- vendordata:云基座传入的数据(全局数据)
在openstack中,metadata、userdata均在用户创建实例时通过相应参数传入,而vendordata则由nova-api-metadata服务启动时指定。

这些数据可能来源于许多地方,cloud-init使用数据源一词表示实例数据的来源,目前内置的数据源有:OpenStack、ConfigDrive、Amazon EC2、Azure等等,不同的数据源也表明了不同的实例数据搜索方式。cloud-init在实例内部启动时并不知道从哪里才能够找到实例数据,它会根据预设的一个数据源的列表一个一个查找实例数据,而首个能够找到实例数据的数据源将成为这次启动的数据源。

如果cloud-init指定了OpenStack数据源,那么实例数据将均通过HTTP API请求获取,不同类别的实例数据有着不同的获取方式:
- metadata:http://169.254.169.254/openstack/latest/meta_data.json
- userdata:http://169.254.169.254/openstack/latest/user_data
- vendordata:http://169.254.169.254/openstack/latest/vendor_data.json、http://169.254.169.254/openstack/latest/network_data.json
而如果指定了ConfigDrive数据源,那么实例数据将均通过文件获取,cloud-init会搜索标记有CONFIG-2标签的分区,随后将该分区挂载至临时目录中,并读取其中包含实例数据的文件:
- metadata:file://TMPDIR/openstack/latest/meta_data.json
- userdata:file://TMPDIR/openstack/latest/user_data
- vendordata:file://TMPDIR/openstack/latest/vendor_data.json、file://TMPDIR/openstack/latest/network_data.json
所有数据源的参考文档:Datasources — cloud-init 22.1 documentation (cloudinit.readthedocs.io)
启动阶段
在整个系统启动的过程中,cloud-init的执行包括5个阶段,执行阶段从前到后分别为:Generator、Local、Network、Config、Final,每一个阶段都有着它们各自的作用。

Generator
- systemd服务:/usr/lib/systemd/system-generators/cloud-init-generator
- 运行于:系统刚启动时
generator是最先运行的阶段,它的功能包括:
- 判断是否需要禁止运行cloud-init。generator会根据如下条件判断:
- /etc/cloud/cloud-init.disabled文件是否存在。
- 内核参数中是否包括有cloud-init=disabled配置项。
- 筛选可用的数据源。generator为每个数据源都写了判断函数,运行判断函数后返回可用数据源的列表,存放于datasource_list配置项并写入/run/cloud-init/cloud.cfg中。
部分情况下,generator对/run/cloud-init/cloud.cfg文件的写入会对cloud-init的运行产生影响,此时可以通过修改/etc/cloud/ds-identify.cfg配置文件,从而更改generator的行为。
# /etc/cloud/ds-identify.cfg
# 该策略表示启动cloud-init,但不筛选可用数据源
policy: enabled,found=all,maybe=none,notfound=disabled
Local
- systemd服务:/usr/lib/systemd/system/cloud-init-local.service
- 运行于:根目录挂载并可读写后
Local阶段的主要功能为:
- 搜索数据源。在datasource_list配置项中搜索第一个可用的数据源,作为本次启动的数据源。数据源搜索细节如下:
- 尝试从缓存恢复。若存在obj.pkl缓存,为trust模式或ds.check_instance_id()返回true,则从缓存恢复。
- 搜索数据源,遍历datasource_list配置项中的数据源,找出第一个可用的数据源,并返回。
- 应用网络配置(不拉起网络)。网络配置的来源如下:
- 数据源,使用从数据源获取的网络配置,渲染并写入网络配置至磁盘中。
- 回退,如果无数据源,则写入一个默认的dhcp网络配置。
- 不应用,如果cloud-init配置文件中有如下配置项:network: {config: disabled},或者存在/var/lib/cloud/data/upgraded-network文件,则不应用网络配置。
Network
- systemd服务:/usr/lib/systemd/system/cloud-init.service
- 运行于:网络服务启动之后
Network阶段的主要功能为:
- self.datasource.setup(),在uesr-data和vendor-data处理之前调用,用于网络启动后再次更新数据源,目前仅用于azure获取fabric数据并填充进fabric_data。
- 存储与渲染userdata和vendor_data。
- self.datasource.activate(),该方法在user-data和vendor-data渲染后,init_modules执行前调用。
- 运行cloud_init_modules中配置的模块。
Config
- systemd服务:/usr/lib/systemd/system/cloud-config.service
- 运行于:Network阶段之后
Config阶段的主要功能是运行cloud_config_modules中配置的模块。
Final
- systemd服务:/usr/lib/systemd/system/cloud-final.service
- 运行于:Config阶段之后
Config阶段的主要功能是运行cloud_final_modules中配置的模块。
cloud-config
cloud-config是cloud-init的配置文件,它用于控制cloud-init的行为,比如说该运行哪些功能,以及每个功能如何运行等等。和其他软件的配置文件相比,cloud-config具有高度定制化的特点,除了云服务器本身的cloud-config以外,cloud-init还能够从vendordata、userdata甚至内核参数中获取cloud-config,从而使得用户能够方便地利用cloud-init定制自己的云服务器。

模块
模块(Modules)是cloud-init运行的主体,所有我们需要的用来初始化云服务器的功能都是通过执行模块而实现的。以set_hostname模块为例,该模块的功能是设置主机名,当运行该模块时,它会读取cloud-config中的hostname参数,并将其中值设置为云实例的主机名。

每个模块都有名称、运行频率、配置参数这三大要素,其中运行频率表示一个模块该在什么时候运行,通常有两种运行频率:1. once-per-instance,表示仅在实例首次启动时运行;2. always,表示实例每次启动都运行。
是否运行某个模块、何时运行模块、怎么运行模块,这些都可以在cloud-config中配置,下面截取部分cloud-config,可以看到在这个云实例中:
- network阶段将运行ssh模块,config阶段将运行mounts、locale等模块,final阶段将运行scripts开头的一些模块;
- set-passwords模块默认的运行频率是once-per-instance,可将其调整为always,表示每次启动云实例时都会设置密码;
- ssh_pwauth是set-passwords模块的配置项,ssh_deletekeys、ssh_genkeytypes是ssh模块的配置项,它们描述了该如何运行模块。
# /etc/cloud/cloud.cfg
ssh_pwauth: 1
ssh_deletekeys: 1
ssh_genkeytypes: ['rsa', 'ecdsa', 'ed25519']
cloud_init_modules:
- ssh
cloud_config_modules:
- mounts
- locale
- [set-passwords,always]
cloud_final_modules:
- scripts-per-once
- scripts-per-boot
- scripts-per-instance
- scripts-user
所有模块的参考文档:https://cloudinit.readthedocs.io/en/latest/topics/modules.html
发行版
cloud-init设计支持绝大多数的主流linux发行版,诸如Centos、Ubuntu、Arch、Fedora等等,然而不同的linux发行版可能在使用方式上有着或多或少的不同,因此cloud-init需要针对不同的发行版进行一定程度的抽象,形成一个统一层并提供给上层的模块使用。就算是这样,某些模块也只能提供给特定的发行版使用,比如apk_configure模块只能alpine使用,而apt_configure模块则只能在ubuntu、debian上使用,这点在使用cloud-init的过程中需要稍加注意。
基础用法
我们在使用cloud-init时一般不会特别地去执行cloud-init相关的命令,在云实例的启动过程中操作系统会按正常流程去执行cloud-init,不过当需要开发/调试cloud-init的时候,这些命令会带来很大的帮助。
执行cloud-init的四个阶段:
# local阶段
cloud-init init --local
# network阶段
cloud-init init
# config阶段
cloud-init modules --mode=config
# final阶段
cloud-init modules --mode=final
查询相关:
# 查询cloud-id
cloud-id
# 查询cloud-init执行状态
cloud-init status -l
# 查询metadata
cloud-init query <variable>
cloud-init query -l
清理缓存:
cloud-init clean
rm -rf /var/run/cloud-init/
rm -rf /var/lib/cloud/
rm -rf /var/log/cloud-init.log
rm -rf /etc/sysconfig/network-scripts/ifcfg-*
其他命令:
# 创建一个包含cloud-config(config.yaml)和shell脚本(script.sh)的userdata
cloud-init devel make-mime -a config.yaml:cloud-config -a script.sh:x-shellscript > userdata
使用案例
重置密码
cloud-config方式:
##template: jinja
#cloud-config
runcmd:
# OpenStack数据源在local阶段无法获取数据,network阶段由于是trust模式,直接从缓存读取数据,无法获取更新后metadata,因此需要事先删除缓存。
- DIR=/var/lib/cloud/scripts/per-boot/ && mkdir -p $DIR && cd $DIR && echo '#!/bin/bash' > 99-clean-cloudinit-cache.sh && echo 'rm -f /var/lib/cloud/instance/obj.pkl' >> 99-clean-cloudinit-cache.sh && chmod +x 99-clean-cloudinit-cache.sh
# ConfigDrive数据源无法获取更新后metadata,需在首次启动后修改为OpenStack数据源。
- echo 'datasource_list: [OpenStack]' > /etc/cloud/cloud.cfg.d/90_openstack_datasource.cfg
# 首次启动后禁止写入网络配置,防止ConfigDrive中的bond配置被覆盖。
- touch /var/lib/cloud/data/upgraded-network
{% if ds.meta_data.meta.admin_pass is defined %}
chpasswd:
list: |
root:{{ds.meta_data.meta.admin_pass}}
expire: false
ssh_pwauth: [true]
phone_home:
url: http://169.254.169.254/openstack/latest/phone_home?unset=admin_pass
post:
- instance_id
tries: 5
cloud_config_modules:
- [set-passwords,always]
- [phone_home,always]
- ssh
- runcmd
{% endif %}
{% endif %}
获取更新后metadata的方法,除删除缓存之外,也可实现setup方法,在该方法中获取metadata并填充进数据源中(参考azure数据源)。
将set-passwords和phone_home模块设为always的方法,出了在vendor-data中指定外,也可在activate方法中实现,删除执行这两个模块的信号(参考exoscale数据源)。
ssh公钥注入
使用如下userdata注入ssh公钥:
##template: jinja
#cloud-config
ssh_authorized_keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDIe6oWYfMB4m9TDSmyVlONj2UakYKkAnpTsZnYXWHUd6zLQDvCLkeXmLiBTuJ51Dh6nolL4rZETj1wLJpXqcMvDhhOZyA0Ji3ENbeJj0URWNjDpRUc3eUApDOzpa3gHm8yRwXDZsZbFMpqcL5vQjlZJ9K+SmLCvbfk6sG04uJWLsIFrjSkxlRxdWwHwdvMH9tAo3UeQGnzRxdnF4zxrob+vAV7PPqJ9u4J6GwXWykTtS+cmvoPOBWQHL5gULxp2FVt/xTF5xY2IRHpzfNmJlCd4G7HGow/PVD+jsIN57iNwvxU7dvTzg0PVUXGQImJvQ8pkHD6//ghXcLleUQz3f+7Brlc6yEZuDdEy2NFEnYW8CoEymPSXVZaBykiggP2XSGp6gQa1gtT7yy44EEB5kjX9epi+jAwiCRaLDrgSLBWQmJp8435dtoOALZOXb1Br0uOA0a3G3KZr+7v11f09NZgFPzJTrY2d4ZNtOUILOcQkUAhtW6yOwuCiuxVeKM8cjE= webssh@hikcloud
云实例初始化工具cloud-init简介的更多相关文章
- 云实例初始化工具cloud-init源码分析
源码分析 代码结构 cloud-init的代码结构如下: cloud-init ├── bash_completion # bash自动补全文件 │ └── cloud-init ├── Chan ...
- JavaSE面试题:类初始化和实例初始化等
类初始化过程 1.一个类要创建实例需要先加载并初始化该类 main方法所在的类需要先加载和初始化 2.一个子类要初始化需要先初始化父类 3.一个类初始化就是执行<clinit>()方法 & ...
- Java类初始化和实例初始化过程
1.类初始化过程 一个类要创建实例需要先加载并初始化该类 main方法所在的类需要先加载和初始化 一个子类要初始化需要先初始化父类 一个类初始化就是执行<client>()方法(编译器生成 ...
- JAVA类初始化和实例初始化
一.类初始化过程 1.一个类要创建实例需要先创建和加载 (1) main方法所在的类需要先加载和实例化 2.一个子类要初始化,需要先初始化父类 3.一个类初始化就是执行<clinit>方法 ...
- .NET DLL 保护措施应用实例(百度云批量保存工具)
最近做了个小工具,将保护措施思路全部应用到了此工具中. 点我下载 百度云批量保存工具是一款专门用于自动批量保存百度云分享的软件. 本软件特点:1:完全模拟人工操作:2:可以批量保存百度分享的文件( ...
- 002-Spring Cloud 功能简介
一.主要功能 分布式/版本化配置.服务注册与发现.路由.服务间调用.负载均衡.断路器.分布式消息传递 1.云本地应用[Cloud Native Applications] Spring Cloud C ...
- 亚马逊AWS EC2云实例AMI安装LNMP环境(3)——Mysql5.5
概括:这里选择亚马逊EC2的Linux AMI实例,该Linux服务器是亚马逊预配置的Linux环境,内置多个YUM源,属于亚马逊首推的稳定Linux服务器.默认登录用户名为ec2-user,执行ro ...
- vue 源码学习二 实例初始化和挂载过程
vue 入口 从vue的构建过程可以知道,web环境下,入口文件在 src/platforms/web/entry-runtime-with-compiler.js(以Runtime + Compil ...
- 通过阿里云命令行工具 aliyuncli 购买服务器
开始想通过 aliyuncli 的 golang 源码进行编译安装(注:python 版的 aliyuncli 已不再维护),但没成功,详见 通过 golang 源码编译阿里云命令行工具 aliyun ...
随机推荐
- 【java】学习路径23-拆箱与装箱
拿Integer类型和int类型来举例子. 装箱,基本给引用.下面的代码相当于Integer i_test = Integer.valueOf("100"); 注意!过程是自动的. ...
- 【java】基础1-字符串、堆、栈、静态与引用类型
/*结论:1,一般变量(int,float,boolean..)使用==比较,引用类型(String,int[],对象)使用equals比较.2,一般的变量存放在栈中,new出来的对象都存放在堆中,字 ...
- DES|3DES|AES|RSA|DH | CA | SSL(HTTPS)
1.对称密钥算法: 加解密速度块,算法使安全的,已知算法无法推出密钥.但是密钥的分发困难. DES:对称密钥算法,是一种块加密算法,只有一个密钥.加解密都是用一个密钥. 3DES:与DES一样,可以认 ...
- 从0到1写一款自动为Markdown标题添加序号的Jetbrains插件
1. markdown-index 最近做了一个Jetbrains的插件,叫markdown-index,它的作用是为Markdown文档的标题自动添加序号,效果如下: 目前已经可以在Jetbrain ...
- django_day11_项目相关
django_day11_项目相关 新增和编辑 路由 url(r'^category_add/$', views.category_change, name='category_add'), url( ...
- KingbaseES 数据库连接断开问题排查思路
用户在使用数据库过程中,经常会发现如果会话空闲一段时间,会话有可能断开,需要重连.这个问题影响因素很多,包括数据库参数设置.操作系统参数.防火墙等.以下介绍KingbaseES针对该问题的排查思路. ...
- 学会Linux,看完这篇就行了!
转载请注明出处️ 作者:测试蔡坨坨 原文链接:caituotuo.top/797ab07d.html 你好,我是测试蔡坨坨. 对于测试同学来说,Linux基本属于必学必会内容,招聘要求中基本都会出现L ...
- Latex中也能展示动态图?
技术背景 在学术领域,很多文档是用Latex做的,甚至有很多人用Latex Beamer来做PPT演示文稿.虽然在易用性和美观等角度来说,Latex Beamer很大程度上不如PowerPoint,但 ...
- 使用k8s部署springcloud解决三大问题
1.正式环境使用的话启动时需要指定使用正式的配置文件,这个要咋处理? 解决办法 文章地址:https://www.cnblogs.com/sanduzxcvbnm/p/13262411.html 分析 ...
- 请求库之requests库
目录 一.介绍 二.基于get请求 1 基本请求 2 带参数的get请求 3 请求携带cookie 三.基于post请求 1 基本用法 2 发送post请求,模拟浏览器的登录行为 四.响应Respon ...