找回密码
 注册
查看: 2765|回复: 2

Cloud-init的常用认识和实际应用

[复制链接]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
发表于 2021-5-26 09:18:13 | 显示全部楼层 |阅读模式
Cloud-init是什么# b" t+ u+ C2 e* F) s! `5 V2 T
Cloud-init是开源的云初始化程序,能够对新创建弹性云服务器中指定的自定义信息(主机名、密钥和用户数据等)进行初始化配置。通过Cloud-init进行弹性云服务器的初始化配置,将对您使用弹性云服务器、镜像服务和弹性伸缩产生影响。简单地讲,cloud-init是一个Linux虚拟机的初始化工具,被广泛应用在AWS和OpenStack等云平台中,用于在新建的虚拟机中进行时间设置、密码设置、扩展分区、安装软件包等初始化设置。. k9 `) d8 U; O2 w
官方讨论:http://cloudinit.readthedocs.io/en/latest/topics/examples.html
& `1 k% m- V' }对镜像服务的影响. Y+ T  \& d( B) m7 [: x0 V  c
为了保证使用私有镜像新创建的弹性云服务器可以自定义配置,您需要在创建私有镜像前先安装Cloud-init/Cloudbase-init。1 B6 D5 n$ n% R+ d. M
如果是Windows操作系统,需下载并安装Cloudbase-init。4 s' s9 D( C; v# a9 x0 |
如果是Linux操作系统,需下载并安装Cloud-init。( U, q1 L( m/ i' V- r
在镜像上安装Cloud-init/Cloudbase-init后,即可在创建弹性云服务器时,按照用户的需要自动设置弹性云服务器的初始属性。
; m/ e" N+ T& g对弹性云服务器的影响+ f, \" k7 O6 G1 ~+ T
在创建弹性云服务器时,如果选择的镜像支持Cloud-init特性,此时,您可以通过系统提供的“用户数据注入”功能,注入初始化自定义信息(例如为弹性云服务器设置登录密码),完成弹性云服务器的初始化配置。: w% e+ b. Y+ v6 L# V' ^+ a+ X
支持Cloud-init特性后ZQ,弹性云服务器的登录方式会产生影响。
8 w, N7 ]6 q! V( F" N7 x- q9 A  ~4 b对于运行中的的弹性云服务器,支持Cloud-init特性后,用户可以通过查询、使用元数据,对正在运行的弹性云服务器进行配置和管理。5 I0 _$ g% ]" l0 t: ]1 Z# j
对弹性伸缩的影响
) r& n/ o3 `) a0 _; i创建伸缩配置时,您可以使用“用户数据注入”功能,指定弹性云服务器的初始化自定义信息。如果伸缩组使用了该伸缩配置,则伸缩组新创建的弹性云服务器会自动完成初始化配置。* J" ^! S! R3 `! e7 v# Z
对于已有的伸缩配置,如果其私有镜像没有安装Cloud-init/Cloudbase-init,则使用该伸缩配置的伸缩组创建的弹性云服务器在登录时会受到影响。
3 f; V7 y9 R8 Y9 O% n$ I使用须知( T5 Z, y! K" I7 V. [/ F
使用Cloud-init特性时,需开启弹性云服务器所在VPC中子网的DHCP。
) e7 u4 v& I+ u' G: u使用Cloud-init特性时,安全组出方向规则需满足如下要求:
& Z5 D# @2 I" y! |协议:TCP7 m, n) U. U9 `
端口范围:80
8 O# u1 N$ t7 e$ W0 u- D6 d- k远端地址:169.254.0.0/16
  ?6 p) n3 c4 f说明:
* ~/ q- _0 K# d* Q: e2 u如果您使用的是默认安全组出方向规则,则已经包括了如上要求,可以正常访问元数据。默认安全组出方向规则为:
$ c- j! p1 Y5 q* t3 `( H7 M0 L! A$ f7 t协议:ANY* c0 c8 Q8 ]0 U8 `( W  T0 i7 d- V
端口范围:ANY* Q+ K) n- Y9 x' j- \: H  d
远端地址:0.0.0.0/06 ?9 A) `# D! I# H
cloud-init简介及组件说明
6 C, A% r* q$ m' d, }. V+ m介绍:
; w# R  n* t1 |1 a    cloud-init是专为云环境中虚拟机的初始化而开发的工具,它从各种数据源读取相关数据并据此对虚拟机进行配置。
# q9 q1 D5 n+ S8 u8 G% J, J    向一台数据服务器获取元数据(meta data)和用户数据(user data),前者是指VM的必要信息,; N% a% z* J3 i* c
    如主机名、网络地址等;后者是系统或用户需要的数据和文件,如用户组信息、启动脚本等。
% E2 i' R; @9 e) j' m    当cloud-init获取这些信息后,开始使用一些模块对数据进行处理,如新建用户、启动脚本等。常见的配置包括:设定虚拟机的hostname、hosts文件、设定用户名密码、更新apt -get的本地缓存、调整文件系统的大小(注意不是调整分区的大小)等。& E7 q5 O( v! Z
工作原理:% k2 P, R; Y0 }% s' O
    首先,数据服务器开启HTTP服务,cloud-init会向数据服务器发送请求,确认数据源模块,依次获取版本、数据类型和具体数据内容信息。
* Q( a3 K- }' u5 I. m    & N! V0 V) l. o% n5 e+ j
  功能:5 `% z+ f; b. S  B+ k% I
    用户可配置性
6 C' U, g+ u- I' N4 V        可以通过用户数据配置Cloud-init的行为。
3 p% @" p9 l9 q% |, w. S" q8 I        用户数据可以给用户在实例启动时输出$ v& v% q2 [" S& F- p$ y+ x
        例如,这可以通过--user-data或--user-data-file参数到ec2-run-instances, U# e8 Z  h& |2 H7 H
        
4 R7 A/ G& B* s( e7 u+ M5 m, k    特征
6 i$ S. B) C. d0 U0 x    设置默认域- Q, j& X3 t: U$ d. g
    设置一个实例的主机名
7 f% b7 C7 o; x- X3 W    生成实例SSH秘钥
- t. {* h0 I5 B& r    将SSH密钥添加到用户的.ssh / authorized_keys,以便他们可以登录
% M7 N0 T! G* {& d    设置临时挂载点
, M) j4 ~8 R. A  s3 W. M- Z    配置网络设备
+ C0 k8 Q+ I) K9 }可用性:
9 Y3 k2 z0 G3 y4 v1 q# r4 ]6 R4 F; m    它目前安装在Ubuntu Cloud Images中,还有在EC2,Azure,GCE和许多其他云端上提供的官方Ubuntu映像。
0 e0 w& ]0 ^( K: O9 x* }" A    支持诸多linux发行版本,ubuntu、fedora、debian、rhel、centos等等7 \6 H0 _# r' S
Gzip压缩:
" J( r, i, U3 i. }    发现gzip压缩的内容将被解压缩。 然后将使用未压缩的数据,如同未压缩的数据一样。 $ o  j8 k( a, q4 a* V  k
    这通常是有用的,因为用户数据被限制在〜16384 [1]个字节。
) L; g; Y) c4 n  n用户数据:
; R3 e2 O7 u+ @' {    配置文件(Cloud Config Data),类型为Content-Type: text/cloud-config,系统配置文件,如管理用户等,与/etc/cloud下的cloud.cfg最后合并配置项
4 `# |8 E$ `9 }& w; I: h* m    启动任务(Upstart Job),类型为Content-Type: text/upstart-job,建立Upstart的服务
8 z* T& D- `5 _    用户数据脚本(User-Data Script),类型为Content-Type: text/x-shellscript,用户自定义的脚本,在启动时执行
5 L1 T9 f+ `$ l* x    包含文件(Include File),类型为Content-Type: text/x-include-url,该文件内容是一个链接,这个链接的内容是一个文件, (Cloud Boothook),类型为Content-Type: text/cloud-boothook
: t" `  K/ f6 h& E    压缩内容( Gzip Compressed Content),' A4 Q2 w& [/ I5 f* D- Q: e- e0 s
    处理句柄(Part Handler),类型为Content-Type: text/part-handler,内容为python脚本,根据用户数据文件的类型做相应的处理
3 D' K! }/ u  G: p    多部分存档(Mime Multi Part archive),当客户端需要下载多个上述用户数据文件时,可用Mime编码为Mime Multi Part archive一次下载1 u+ j' \' ]! }7 R
目录结构:
) n  O4 F! d. p: L! q4 F0 Zcloud-init 是 linux 的一个工具,当系统启动时,cloud-init 可从 nova metadata 服务或者 config drive 中获取 metadata,完成包括但不限于下面的定制化工作:
( v; z) p& t7 J8 S! S; z设置默认语言环境$ A/ Y0 m3 w% l  J; K- G+ O
设置实例主机名$ c9 G; w7 }* v9 i
添加 ssh keys到 .ssh/authorized_keys
- c4 P0 W- Z4 z& ]  G& ^设置用户密码, C) J8 M  d$ [2 o7 u
配置网络安装软件包( e1 {1 Q9 M  P. ?+ L
启动阶段:
. ~$ K5 p9 Y( T, z   
5 o. k$ Q; v1 o. _: _    Generator. k( W2 `8 o' h
    Local
( V4 V6 s6 h3 C; v% E% X    Network
+ {: o1 l  T9 _( I    Config% l5 `9 G' [6 L% C% u  y  @6 Y$ {  F1 j
    Final
1 [* U2 v* k* j9 Z9 `0 c' R为了实现 instance 定制工作,cloud-init 会按 4 个阶段执行任务:1 `4 ^; T. y5 E
local5 {& i. W1 S8 i# W' a* A+ X
init) [9 a* q/ ]1 P
config
! g) S3 t0 n, V0 F8 `final
  q, w; P, a) Q; U' Mcloud-init 安装时会将这 4 个阶段执行的任务以服务的形式注册到系统中,比如在 systemd 的环境下,我们能够看到这4个阶段分别对应的服务:, h: `5 {+ U) V* W5 t. |" x8 x1 t
local - cloud-init-local.service3 ~' X+ j. d  N" U; s2 c
init - cloud-init.service& {* W5 v( n, i& c% I  C8 x
config - cloud-config.service: `% o9 u! Z+ I+ ?! Z( |4 \7 e
final - cloud-final.service& X8 c# ?, R5 ~7 w' A4 u9 K
+ c; D1 ~* g# I* R
当在systemd下引导时,将运行一个生成器,以确定cloud-init.target是否应包含在引导目标中。
* k, I# T$ y2 e  Y. z默认情况下,此生成器将启用cloud-init。 它不会启用cloud-init,如果:9 A; q/ U; {/ {9 z
    9 ?3 I2 R* Y! I5 z3 p+ l" p7 P
    Generator:
( U4 c6 j% s3 T        当在systemd下引导时,将运行一个生成器,以确定cloud-init.target是否应包含在引导目标中。 - Q& I  s" Z( h' B( c, v
        默认情况下,此生成器将启用cloud-init。 它不会启用cloud-init,如果:A file exists: /etc/cloud/cloud-init.disabled
7 o1 H1 s9 ]" A         /proc/cmdline contains cloud-init=disabled
9 \+ R+ z4 C" z2 m4 b9 I$ a0 J7 D    1 q- P1 O, S% c# z+ F# y. P
    local:, Q( s4 y1 D$ \( X& Z8 O
        cloud-init-local.service
5 G9 p% y6 ]% x! a0 R* d4 h        找到本地的数据源
5 C- k& @8 N- V, a  H4 S! w* L* \        对系统应用及网络进行配置
7 a* c9 E, Y. F0 U2 u; @        网络配置:8 \" E2 k, P! r: C; Y
            数据源
- y1 n6 O: R1 u0 v2 y9 e$ `            网卡dhcp; W# j& G! y( |% n
            禁用网络
" T( c9 d, P9 n8 s    $ \+ ]4 }3 \0 m8 Z
    Network:
/ [. T2 |1 z, W; o' ~* R2 d        cloud-init.service
* C7 N% h7 q* O& z) {8 T) d! G5 M1 v6 z        http5 p- c- ?  w. ~0 h% [
        解压gzip1 V" ^  [+ _+ w& i
        格式化磁盘、分区9 _& C: {# M/ Y3 _5 M5 j
        bootcmd
6 @" v, p5 y% r( {5 j- f9 P' l9 D" v3 R    4 {- W4 f8 _4 \5 R$ H
    Config:& p% l# \) O7 |. |2 P
        cloud-config.service
' f* G2 n5 u& F' W% i) c        配置模块modules
' w, g  {( J6 }2 P- o+ x/ O9 T    Final:
, ~( p  W# n  @( K( s( x  `        cloud-final.service
0 M) Q* Y) e2 h" ~6 l2 o        启动最后阶段rc.local- E) @% D2 C0 m+ S
        包的安装
1 P0 p1 o- {& y6 g0 @        配置管理插件、chef、puppet: A! K% Q* O( Z* u4 ^
        用户脚本,runcmd* z8 w; X% Y$ V! [! r) p
数据源:4 J  {: o- t! n1 b
    数据源是cloud-init的配置数据源,通常来自用户(也称为用户数据)或来自创建配置驱动器(也称为元数据)的堆栈。
( F* r: o! g8 Y6 Y  g% T    型的用户数据将包括文件,yaml和shell脚本,而典型的元数据将包括服务器名称,实例ID,
6 ?0 g/ Q5 N* T" }5 y* K+ P    显示名称和其他云具体细节。 # T5 o/ r& C6 {% n9 o  T
    由于有多种方式来提供这些数据(每个云解决方案似乎都喜欢自己的方式)内部创建了一个数据源抽象类,
! U  s# o8 ]" k" c: U) z( G    以允许单一方式访问不同的云系统方法,以通过典型的子类使用提供此数据。' i: J( {. @% ~6 e. A1 a
    ) B6 S  ~6 s7 `% ~
    支持的方式:
& W- K3 x8 k8 X        Alt Cloud:
# w6 x, n& S; j+ p            RHEVm- K5 y, t7 r: N2 t# Y3 x
            vSphere
/ x5 j9 i) a6 y1 u- g        Azure/ R( j& N  Q* s/ X/ M: g$ |& p; o
        CloudSigma3 e  ~% A) z) D) u$ n. G
        CloudStack- g: d' B. S2 A0 x% u
        Config Drive
) z* y! |! K: O        Digital Ocean
2 ~& i# s2 ~; J6 i1 u        Amazon EC22 s1 H; G  E* y" E
        MAAS& A$ P; }. g& g* C
        NoCloud; J2 M, @5 p9 m% J$ S* R
        OpenNebula" g) p  a+ L2 c: D+ k
        OVF
- ~* T% [0 {7 ^4 R, r+ y, j8 h        SmartOS Datasource1 ]. f; U2 N: ^+ m" ?- @1 I
        OpenStack:1 p: e) W8 L8 y8 j, D( x) G
            metadata_urls http://169.254.169.254返回200ok% }" p$ }# N4 b. s
            max_wait default 1
9 d1 _- ~; ~# s9 O            timeout default 10
1 {& ~# b8 a1 @* {. c            retries default 5重试次数
- L9 U0 Z3 y* n  z) h        #cloud-config! g. Y+ `6 @$ R$ h, `: |
            datasource:
$ k6 c# [" R8 V/ D. s                OpenStack:
, Q$ G$ T6 k) Z' W                metadata_urls: ["http://169.254.169.254"]  X$ V" T% K$ A
                max_wait: -1
  }* W1 }! X* m% u& }                timeout: 106 I7 T  J' \  p7 f
                retries: 5# f$ _+ F7 {. A  \* l$ w2 m- {
Logging:. H3 C& h1 u  e0 u$ \: B# u
    支持本地和远程日志记录是通过 python 的内置-在日志记录配置并通过云 init rsyslog 模块可配置、, z+ X+ {" L* Z0 ]: d/ U% q
    默认cloud-init将其输出配置从/etc/cloud/cloud.cfg.d/05_logging.cfg加载- `: D- q% |! `
    默认配置将stdout和stderr从所有cloud-init阶段引导到/var/log/cloud-init-output.log
3 b  ^9 \  i) sModules:
: @' H! ~9 V: G! O- P3 S    Apt Configure配置ubuntu 源列表
! H; h+ b/ d- h+ p    Bootcmd:在引导过程的早期运行命令,用于在引导过程中不能完成的$ `0 \8 }; z' V3 |% w8 _
    Byobu:该模块控制是否启用或禁用系统范围以及默认系统用户
7 @1 }8 J1 a# T& F1 F    CA Certs:添加CA证书) @$ q: u2 T: u3 N
    Chef:安装chef client
, g; B* K& h8 G    Debug:帮助调试内部数据结构
0 Y) B5 _9 m, }: [  Q, t. x0 ?8 F" Q( Q    Disable EC2 Metadata:默认禁用,该模块通过拒绝发送到169.254.169.254的路由,从而禁用ec2数据源。. `' k* q3 _0 [5 P! q* `; N
    Disk Setup:配置分区和文件系统" u' N' T" C7 |+ t( J" i( P9 G  g8 C
    Emit Upstart:发出启动配置,不需要配置6 e$ j1 U/ ?+ ?0 Y2 I, q
    Fan:配置ubuntu网络6 y" ]: E5 D1 d$ _7 U" P
    Final Message:当cloud-init完成时输出最终消息  ~: E  ^9 D& ]- \; i7 ?
        version: cloud-init version版本
5 I! Y; S* I( p9 D* y0 F) J        timestamp: time at cloud-init finish 完成耗时( x  M' i, q. @
        datasource: cloud-init data source源数据
! O3 \/ ?9 G2 N4 h2 D" ~        uptime: system uptime系统运行时间1 H/ G* Q& e0 i6 a# i
    Foo:示例显示模块结构,不做任何事情    . E: [4 m7 p$ M' Y$ L6 Y3 L& e* |
    Growpart:调整分区大小以填充可用磁盘空间5 u7 d' g5 S1 N% r3 @- O. E. d5 m
        growpart:4 n; @( }' [+ m2 F! t2 y& V
            mode: auto% m6 d  t% ?  L; d0 ]
            devices: ["/"]% S0 B8 j; o$ y; V) W
            ignore_growroot_disabled: false
! \: H. B1 N, Q( A    Grub Dpkg:配置哪个设备用作grub安装的目标,默认情况下,此模块应正常工作无须配置。
+ Q/ p- m  F3 T4 @    Keys to Console:控制哪些ssh密钥可以写入控制台, b' x; G, ]  m4 o3 K  y  E" p
        出于安全考虑,可能不希望将ssh指纹和密钥写入控制台。 & k$ l( L1 {2 b' g* Y9 @
        为了避免将ssh键的类型指纹写入控制台,可以使用ssh_fp_console_blacklist配置密钥。 6 y. O" e9 u4 G$ Z9 V+ M9 @
        默认情况下,所有类型的键都将其指纹写入控制台。
6 o% X- J1 E) j; c% Q        为了避免将密钥类型的密钥写入控制台,可以使用ssh_key_console_blacklist配置密钥。8 P) H8 M0 F% A& s; O
        默认情况下,ssh-dss键不会写入控制台5 B7 R6 a( r. x& f8 W; e- }
    Landscape:
2 l0 J- r& y0 K9 K* h- k: Z- P    Locale:配置系统区域设置并系统应用
# j0 n7 d5 X# ~9 V    LXD:- f+ O- \2 H1 \7 _
    Mcollective:
8 T0 \1 Q$ E4 ]) q- R5 B- k    Migrator:该模块处理将旧版本的cloud-init数据移动到较新版本
) q  b4 X5 v+ W% T    Mounts:配置挂载点和交换文件
) e. a$ [& ~; _3 u+ R    NTP:处理ntp配置
! B  v. H- ?" G! T- E        ntp:
: q( I; U! m! [! N! {    pools:
9 {2 ?5 s# N  P. V) K  `$ \8 ~6 J9 H1 g& Q        - 0.company.pool.ntp.org8 Y$ @2 A, y. }; t: W! L
        - 1.company.pool.ntp.org3 n# m. Z, j! W* ~+ e2 |
        - ntp.myorg.org
% ?- j/ X2 m9 x" f+ ?2 ]    servers:
! j/ r$ D8 w4 A) w& W, u# j        - my.ntp.server.local8 A* n5 n( q4 B& |% I
        - ntp.ubuntu.com
& k1 T# ?8 M, ~4 c( P8 q& j+ l+ R        - 192.168.23.2& z8 L9 T7 v3 F4 w/ Z. _
    Package Update Upgrade Install:
3 H! e+ F, Y8 U! B) [& x6 D* P        更新,升级和安装软件包) a# [* H9 f( Z: f" x
    此模块允许在引导期间更新,升级或安装软件包4 ]& ?7 ^2 d, I, E$ h7 d
     如果要安装任何软件包或执行升级,那么软件包缓存将首先更新。
4 O5 t7 V# S+ e1 r/ W0 T2 }: Z     如果软件包安装或升级需要重新启动,则如果指定了package_reboot_if_required,则可以执行重新启动。
1 h* d! K; X* L+ J     可以提供要安装的软件包的列表。
, a3 ~4 Q7 x: a: {9 k# L; p+ `     列表中的每个条目可以是包名称或具有两个条目的列表,第一个是包名称,第二个是要安装的特定包版本。
/ j% C) w0 }. C+ n    Phone Home:
8 w5 D6 c: u* i9 |/ t$ T% A        引导完成后,该模块可用于将数据发布到远程主机, 可以发布所有数据或发布的密钥列表。) ?' l0 E& w, ^  V; t
    Power State Change:6 J' H6 G2 j2 Y% ]9 P, t) g
        改变电源状态/ D$ W1 B8 i. I9 l( b0 M
        所有配置模块都运行后,该模块处理关机/重新启动。
" i9 k+ v4 O1 Y, ~) U$ Q' h    Puppet:
7 E% V$ [! ^- ^* w! [4 t3 ^- J: m        安装、配置puppet
( r( e  W$ T, z+ B    Resizefs:调;整文件系统的大小以使用分区上的所有可用空间。2 ?* e  w+ b* p+ q  l8 c! p
    Resolv Conf:5 j9 M8 Y8 D9 @, b
        manage_resolv_conf: <true/false>
, [2 w9 z; {. ]9 l. i    resolv_conf:
" L( e1 y  N2 \$ S0 z1 D        nameservers: ['8.8.4.4', '8.8.8.8']" K1 k/ B6 i+ \- o
        searchdomains:: x. x7 Y. V' {% t3 |2 T
            - foo.example.com7 s( L3 C$ u5 h# h& e" E/ ^
            - bar.example.com
$ u( g, {# y$ T& o" V: N% {5 ~        domain: example.com
; n; J. S! z5 \4 ^" O9 K2 O        options:
: M4 r: |$ z1 x8 m) f* c8 a" |            rotate: <true/false>
5 U: t0 B, G% R  h( M. |            timeout: 1
* Q# t7 O+ [* O7 p        Debian / Ubuntu默认情况下会使用resovlconf,同样的RedHat也会使用sysconfig
! C" z) s6 K, G* h& k% Q    RedHat Subscription:
, w" b) g3 D  Y        通过用户名和密码或激活和组织注册一个RedHat系统3 u5 @% n. P$ K. n
    Rsyslog:
- T5 }. w( N# c        此模块使用rsyslog配置远程系统日志记录6 x) B: M6 `$ m! X$ _6 J/ L2 I
    Runcmd:' T! K! h% d. r0 h, z  t& i
        在类似级别的rc.local上运行任意命令,并输出到控制台/ |) r' ], J# o  O% S
        所有的命令必须是正确的yaml,因此您必须引用yaml所符合的任何字符
" ?" H* [  I+ N0 J: q" b        runcmd:4 ?' e; i) K' d! Q8 d) m
    - [ ls, -l, / ]
; P2 D! t7 m7 C, O$ z. u    - [ sh, -xc, "echo $(date) ': hello world!'" ]6 D) x* j2 E/ M! Y# K. u
    - [ sh, -c, echo "=========hello world'=========" ]2 \6 }. O) z9 r* `+ F5 V1 z
    - ls -l /root
% `1 d! a' F3 d0 D    - [ wget, "http://example.org", -O, /tmp/index.html ]
+ D" c7 E* M; J: F' {- y$ Q$ B    如果项目是一个列表,它将被正确执行,就好像传递给execve()(以第一个arg为命令)。 2 }% o# Y  ]3 G- ]3 P2 u  \
    如果项目是一个字符串,它将被写入一个文件并使用sh进行解释
3 t$ N3 h% Y  S& b$ m: {/ v    Salt Minion:配置公钥和私钥( P+ G, h( B, l% u3 q
    Scripts Per Boot:运行启动脚本
7 h: z* a4 I, s# s        数据源中的scripts / per-boot目录中的任何脚本都将在系统引导时运行。" h  ?" s; F( @* X) ?
    Scripts Per Instance:实例运行脚本,系统引导时运行9 ~' b7 [' z$ X- n1 j: U. r2 c
    Scripts Per Once:运行一次脚本  r. D1 O5 S* s% h9 {1 v
    Scripts User:运行用户脚本
. V; j, ]% t3 x8 V        该模块运行所有用户脚本。 : u; P( X8 d! W0 ~+ J
        用户脚本未在数据源中的scripts目录中指定,而是存在于实例配置中的脚本目录中。% X7 z3 @' ^: s' B" f- }
    Scripts Vendor:数据源中脚本/供应商目录中的任何脚本将在首次引导新实例时运行。8 Q7 y1 e" B& {% j; N& y
    Seed Random:生成随机秘钥
/ ^  p# x4 w- R6 S" Z# _    Set Hostname:设置主机名和fqdn
5 X9 z( N- B" t2 {) C9 M    Set Passwords:设置系统密码,启用或禁用ssh密码认证。
# n5 c9 p2 X' r' F$ k! w5 B+ V        chpasswd配置密钥接受一个包含两个密钥中的一个的字典,即过期或列表。
! l# c9 G3 W: t/ A) G3 t3 d        如果expire被指定并设置为false,那么将使用password全局配置密钥作为所有用户帐户的密码。 5 {( p! P5 C7 G6 m: t
        如果指定了过期密钥,并设置为true,则用户密码将过期,从而防止使用默认系统密码。
" Q- _" [9 }* D% M5 N0 Z% a2 ]+ p6 ~        ssh_pwauth: <yes/no/unchanged>3 s- P- T1 K' u, [, [( h  O
        password: password1
* _" Y6 W8 _" S. U- _        chpasswd:
' k1 F3 e4 R7 N% W: j        expire: <true/false>. t& h; q& S' j, H) `8 c0 w  T* Y7 i
        chpasswd:
/ v) }7 R" ?& q( v        list: |+ N/ S+ J' D* z$ ]$ [$ ~
            user1:password18 d1 {% y- f& L" W1 S
            user2:RANDOM. ~& P/ ~6 {: y
            user3:password3  a+ y  N' u! S) Q9 D8 t
            user4:R
0 I: P- a5 r' K, d9 T        ##
: P, U% r, G0 K; D1 b- r% C        # or as yaml list
1 g0 [5 ?8 s# M6 R- R% N; Z        ##6 P) ]5 u+ R8 c% M% S5 i
        chpasswd:8 e( O# f8 N$ }! ^+ S
            list:
" J  S  w5 Q% B( \7 T            - user1:password1
! ]  d; N! w2 Y$ e# i/ f, c            - user2:RANDOM- ^# f- X" W6 p% u: f1 y
            - user3:password3
7 o8 |7 J/ J& C1 k+ H% B9 q            - user4:R7 y* [; R, {; V3 _
            - user4:$6$rL..$ej...3 x* Y, L% Q4 ]7 K
    SSH:该模块处理ssh和ssh密钥的大部分配置  z3 C1 A% E0 R- I" L: k9 Z+ n" t
    SSH Authkey Fingerprints:为每个用户写入授权密钥的指纹记录日志- t+ Z) I6 Y, {: o
    SSH Import Id:此模块通过公钥钥匙服务器(通常是启动板或github)使用ssh-import-id导入ssh密钥7 n2 F: o9 ?/ p- p: R
    Timezone:设置系统时区4 H3 b+ L4 f- |# n  X; K
        timezone: <timezone>
8 F6 n! Q3 Q4 e6 H7 a    Update Etc Hosts:更新/etc/hosts
& }0 i! w8 [: @+ a( K6 P' t2 R        该模块将根据config中指定的主机名/ fqdn更新/ etc / hosts的内容。 ( K( w8 D! v# A
        / etc / hosts的管理使用manage_etc_hosts进行控制。
- ~7 b  ~$ E& m' r) t. y        如果设置为false,则cloud-init将不会管理/ etc / hosts5 A7 y4 j- A8 l' y: _
        如果设置为true或template,cloud-init将使用位于/etc/cloud/templates/hosts.tmpl中的模板生成/ etc / hosts。 8 e/ [& g, @! q& |8 A2 A
        如果manage_etc_hosts设置为localhost,那么cloud-init将不会完全重写/ etc / hosts,而是确保/ etc / hosts中存在具有ip 127.0.1.1的fqdn的条目
) u. P! d& [: C; `' K        manage_etc_hosts: <true/"template"/false/"localhost">$ |) T2 H6 W* S+ r* X
        fqdn: <fqdn>
: ^2 I" ]+ Z1 n. ^/ Y4 P; {  F        hostname: <fqdn/hostname>0 n- {9 ]- {9 Z9 F1 ?/ Q9 e
    Update Hostname:该模块将更新系统主机名和fqdn。8 f. r- f* {* q9 H' E
        preserve_hostname: <true/false>2 k3 v! M" S5 e) O8 W2 e0 X3 w
        fqdn: <fqdn>8 ]" y+ x7 h7 p( p
        hostname: <fqdn/hostname>7 b% R; k* W" M4 D
    Users and Groups:配置用户和组! a" j4 a: Z2 ?! N5 j
            groups:* C7 ]9 z; A! _# f: ]" W
    - <group>: [<user>, <user>]( N$ \; C+ ]. a' B) p7 ?
    - <group>6 u/ ~; _, m& r2 z* ^1 u, \
    users:5 H7 q( T: ?+ r, U
        - default
4 R7 ?0 U4 x4 q" _- S9 k        - name: <username>! U" B# t8 Q- K4 j4 u
        expiredate: <date>7 H0 a, L- ~1 U
        gecos: <comment>
7 U* v6 M9 H7 H. g' q        groups: <additional groups>
* u$ L, e! m' O5 D        homedir: <home directory>
2 S  E* K9 ?6 s- J8 \        inactive: <true/false>' u$ H0 S6 a* \' C+ b* Y
        lock_passwd: <true/false>5 d7 K' I7 F8 Z
        no-create-home: <true/false>  n- d1 b) ]7 J9 V2 O  p3 M) P
        no-log-init: <true/false>
  L$ |2 @9 r& {/ v# J2 V, y) v        no-user-group: <true/false>
3 O9 T' L8 l( ~        passwd: <password>
9 F, l! \: X+ A1 o4 G8 P        primary-group: <primary group>0 N2 _# v4 T$ e  i
        selinux-user: <selinux username>) j/ h! E- ]0 R% R$ w" ?* U
        shell: <shell path>
% b2 [# G. A9 ^* A0 s! X        snapuser: <email>
  _5 ?' v; z; H5 X        ssh-authorized-keys:/ ?; b" A' L& ]
            - <key>7 Z6 `0 g" v: b0 |: `/ y
            - <key>
* f) d* C2 E5 z$ {+ ~( {7 `        ssh-import-id: <id>
5 r. F. R/ {; o0 J" A        sudo: <sudo config>% B4 m% H- g. r0 j2 A7 O: u
        system: <true/false>1 B6 Y5 o) \+ u* _& B- ]
        uid: <user id>8 y0 R  g0 A4 W) m1 g; C9 O- A
    Write Files:
; f6 h# {9 a2 L8 d: H        将任意内容写入文件,可选择设置权限。 内容可以用纯文本或二进制格式指定。 + U5 B6 j0 g, Z$ i& F" W
        可以指定使用base64或二进制gzip数据编码的数据,并在写入之前对其进行解码。
' x6 h8 ^9 z! t% |4 u/ h- f2 b1 v            write_files:
# |# w  X* }. w# V        - encoding: b647 y# m6 D4 \% r& B
        content: CiMgVGhpcyBmaWxlIGNvbnRyb2xzIHRoZSBzdGF0ZSBvZiBTRUxpbnV4...9 U4 N! m/ [! y, d. ]. l
        owner: root:root
$ x$ l4 F' j+ F( l        path: /etc/sysconfig/selinux
" M: [3 p0 a, e* Y        permissions: '0644'
" A4 e' o, I$ M  W/ t        - content: |
4 m3 ~$ Z  E1 ?% J: B% ~        # My new /etc/sysconfig/samba file
$ ^* |: i/ g8 j4 c$ s: A        SMDBOPTIONS="-D"
1 N! c5 q2 J3 p2 L        path: /etc/sysconfig/samba
: n. R4 t) M% g! K) o5 Z        - content: !!binary |
/ {( J5 u& l8 x( |1 q2 Y        f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAwARAAAAAAABAAAAAAAAAAJAVAAAAAA
9 v. a' n3 h" t% O; g3 p        AEAAHgAdAAYAAAAFAAAAQAAAAAAAAABAAEAAAAAAAEAAQAAAAAAAwAEAAAAAAA
" k: S5 P) M) F5 D        AAAAAAAAAwAAAAQAAAAAAgAAAAAAAAACQAAAAAAAAAJAAAAAAAAcAAAAAAAAAB% s1 D8 p( T& r
        ..." U, _1 n: m# B" c
        path: /bin/arch+ R! M2 C) L' a# ?( d7 F) \
        permissions: '0555'
% X, F9 h, w4 m    Yum Add Repo:
2 D6 J* b( G& K1 i% U( D9 S        将yum存储库配置添加到/etc/yum.repos.d。4 q+ H& v) R9 W& t, g
        yum_repos:
$ G  ]; ]; }. k+ C, H; A: L            <repo-name>:/ k+ B+ h6 y1 ]- g* E% x. x4 k
                baseurl: <repo url>1 y) u  j/ I" x$ V3 |) V" k7 U
                name: <repo name>! i& N& f1 H" P" z5 z
                enabled: <true/false>
7 V9 j7 v$ U# @( I) [1 \1 t0 Y在本地KVM中使用cloud-init
; p$ o( P: A- e' d) w- }( u* e, f4 X    本文主要研究在本地KVM虚拟机,也就是没有云平台的情况下,如何使用cloud-init进行初始化工作。示例虚拟机的操作系统是centos7.1。  q, [# ^9 J7 C. B
安装* u, ?: q$ e' h# G( T+ ?9 x
在虚拟机内安装cloud-init:
0 c- W* b& c8 W% s% y0 ?$ {% zyum install cloud-init -y/ W8 Z+ u/ n! I! Y& ?7 Z
0 V6 |1 d  t5 O) G8 n2 I
安装完后,配置文件在/etc/cloud目录,主配置文件为/etc/cloud/cloud.cfg
$ H$ f# c4 M( a1 |$ LDataSource
) E. \! |4 H+ A/ F$ `2 y要让cloud-init能够顺利完成初始化工作,必须把一些数据传给cloud-init,例如让cloud-init设置root密码,必须要告诉cloud-init密码是什么。Cloud-init支持很多种数据来源,常见的有metadata service、config drive和nocloud等。
4 r: P, ]# Q* `! Q. N" G  {/ fl  metadata service提供一个可以获取数据的url,例如OpenStack中的nova-api-metadat提供的http://169.254.169.254,虚拟机开机后cloud-init在完成网络配置后,会向这个url发起请求。因此这种模式需要先配置好网络;
; C1 t7 }) \$ f1 ml  Config drive 把数据封装进一个iso9660(也支持vfat,但是不常见)文件系统的镜像中,然后把这个镜像以光驱(ide接口)的形式挂载到虚拟机中,虚拟机开机后cloud-init会自动去该镜像中获取数据。文件结构一般如下:
& J; f: u: N# U% n( Oopenstack/8 H1 z* q3 Z% p, `5 ?8 S. j
  -   2012-08-10/ or latest/
0 M: S7 o: e  n      - meta_data.json& n1 V8 D2 x1 P. @. _& a- ^- E9 D
      - user_data (not mandatory): A' i- }6 _+ R! F: Q% E9 T- i
  -   content/
( V2 q. q3 @; g* p7 C& k      - 0000 (referenced content files)3 f$ l: x8 }6 V" w1 w
      - 0001
/ y- F- O) N# a8 y+ Z+ {& `+ ^      - ....
+ z/ t# B/ Z% m5 E; i& d! H* U' pec2# l! R/ @" Z* M; I5 K! ^
  -   latest/
0 M4 [0 ^4 Y5 I4 r1 z      - meta-data.json (not mandatory)
! E4 {2 P& c4 Z7 P6 S0 Q5 l9 O. \* B' }. r
l  Nocloud 这种模式与config drive类似,只是文件结构不同,一般由user-data和meta-data两个文本文件构成。并且镜像以普通磁盘(virtio接口)的方式挂载。
) g7 U5 f) x; a" q' l本文主要试验nocloud模式。5 ?1 T- ~- [" q0 x7 I) C
封装数据
# Y! q, Z# n( R制作镜像需要cloud-localsd命令,默认没有安装,安装命令如下:0 G6 s7 y3 C9 M3 {$ O) Q
yum install cloud-utils -y
7 L% x* F( G. W  _编写user-data:
/ _" V3 Z8 d% e& `: z5 a+ `# Icat << EOF > my-user-data3 [7 H  E+ l! b
#cloud-config! K, V( \6 `) r. v$ c) k: S  a$ J
chpasswd:
3 V$ N; R6 y; Elist: |- D& v7 e9 k4 ]. c& N
root:123456
: }! D' M' r: B$ b3 ]# I7 F2 rexpire: false
* s( v! x+ w6 q" q+ Mssh_pwauth: true
, |' M% ^4 D; @4 {: B) N' ^EOF8 s6 V; x' q' Q/ q( t5 v* u
cloud-init也支持多种数据格式,我们使用的是cloud-config格式,这种格式必须是以#cloud-config开头的yaml格式。上面这段的意思是把root的密码设置为“123456”,然后配置ssh允许密码登录。6 Y8 L5 p1 Q& i
制作img:" n5 q$ s: ?0 C- Y6 M- y
cloud-localds -m local my-seed.img   my-user-data6 f$ ?9 d1 h& e: |1 S0 O/ E( b
-m指定的cloud-init的工作模式,local的意思是不需要依赖网络,我们没有使用metadata service,所以不需要网络。
# X' X7 m4 Z$ a: k  @: f9 H挂载数据
, _6 s# D/ I5 j. P- l编辑虚拟机的libvirt xml配置文件,挂载镜像:
) C7 S9 R' h" ^3 e9 Y<disk type='file' device='disk'>
' e. m4 n2 E; r8 t/ d9 [      <driver name='qemu' type='raw' cache='none' io='native'/>
& ~2 w, B# R5 y      <source file='/path/to/my-seed.img'/>; q- D, t4 a) V2 J* ]) D
      <target dev='vdb' bus='virtio'/>
7 {1 G5 h! M  p+ ?: p1 h6 y; N# B7 u$ S      <readonly/>
$ Z0 Y$ j8 p6 x9 b- W; V</disk>
( J7 p. v1 d/ q$ E修改cloud-init配置7 ^. j. i' U' x4 @3 b9 z! V
在/etc/cloud/cloud.cfg最后一行添加以下内容,这句的意思是让cloud-init接受NoCloud来源的数据:
; l0 c, I8 N+ ]$ j+ K8 pdatasource_list: ["NoCloud"]
4 D' f* u! F5 v" }8 P重启虚拟机( @* T# T$ _9 K3 {- U- h
在虚拟机内执行rm -rf /var/lib/cloud,不删除这个目录,cloud-init不会执行。
4 @, C7 W" T$ b& t硬重启虚拟机
& J5 G; b: Z3 K0 U5 t' Gvirsh destroy vm
3 m" K) L7 v5 t6 kvirsh start vm7 d* A6 N# Z( b( f/ }# S6 e) g
虚拟机开机后,会发现root密码变成了“123456”
5 o! w9 `) {" ~& q0 ~3 n; w查看数据3 Q0 t2 Y( o9 S8 u. A; f
在虚拟机内mount /dev/vdb /mnt,可以查看数据的内容。3 E. ^2 P- y- H3 Q! ]
ls /mnt
% \- r$ h9 Q+ a# V1 G& j5 wmeta-data user-data
. H& F& a, ?: p/ {cat user-data
8 R+ c9 @1 g' V, J* u# [5 S#cloud-config- f6 H4 a- `) w
chpasswd:; Q3 g" G# b1 Z% D  h
list: |
: v  G. k5 E$ }, f* D1 P9 Troot:123456' N% T2 M* n, `+ V6 t
expire: false) C/ m/ M, e5 j2 w1 n
ssh_pwauth: true  t9 @& v( q' ]1 Q- i+ p6 B9 y
总结2 @  n1 }8 Y" `- I( r3 p
本文测试了在无云平台管理的本地KVM虚拟机上使用cloud-init修改root密码的功能。cloud-init还有很多功能和技术细节,后续会继续研究。
. `1 V' v3 l! x. _
: ]7 |- Q2 U/ ^

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2021-5-26 12:25:39 | 显示全部楼层
cloud-init配置
  b5 E, P& n; r: W7 S+ dcloud-init配置开机启动命令:
' e" [8 q/ M' m  m. ]# cat /etc/cloud/cloud.cfg5 z5 C3 ?7 q4 X. Y* j
….' V- k2 f8 O& `+ m: L
3 h( Y& k2 j: G
bootcmd:; [1 i8 v, @5 r0 h
  - [ cloud-init-per, once, grow-partition, growpart, /dev/vda, 3 ]( R% K) i; B* f9 t8 R6 C! ]& W
  - [ cloud-init-per, once, resize-filesystem, resize2fs, /dev/vda3 ]- r/ F1 r7 I- F  m0 @# _
简单来说就是,在系统第一次启动的时候,执行命令:
" E& ?" Y+ J* f, l. q% A% y& ~; G7 _growpart /dev/vda 3
  d9 C3 k* ?, L2 o6 [3 Zresize2fs /dev/vda37 X7 K8 J& M4 h! H1 i
即可。
2 V8 }% K+ n' S) s. N, M6 _lvm类型的系统盘扩容脚本- k" L- v: |8 b" ]
如果是lvm类型的系统盘,可以通过如下脚本扩容:/ N: J( h% b* F  v$ I& @& ^* b
# cat extend_root_fs& w4 P. k6 d. n' i
echo "[] linux-rootfs-resize ..."
) ?" N0 S' R  Q# u# Ilvm vgchange --sysinit -an
* z' G* h$ q, O- P2 K) M, B#lvm_lv_root=$( echo $(df -h | grep '/$') | sed " ")8 v( o1 d2 w( b% s- A( i9 @
lvm_lv_root=$(echo $(df -h | grep '/$') | awk -F ' ' '{print $1}')8 V7 V, M! R# S/ x
lvm_pv_path=$(lvm pvs --noheadings |awk '{print $1}')
' K% v5 T. X! u! v% k( _. I% xlvm_pv_temp=$(echo ${lvm_pv_path}|sed "s/dev//g")4 S, ~4 w+ a6 v$ V. S1 e
lvm_pv_dev=$(echo ${lvm_pv_temp}| sed "s/[^a-z]//g")0 F, ?9 L2 y1 T* J; ?6 H3 O
lvm_pv_part=$(echo ${lvm_pv_temp}| sed "s/[^0-9]//g")6 ]0 w9 f8 U+ z7 N( k9 c! r6 m* ]
growpart -v /dev/${lvm_pv_dev} ${lvm_pv_part}+ H8 m. R% g0 E+ d8 O
partprobe -s /dev/${lvm_pv_dev}
$ |2 S0 e2 }, s; Z- Y9 W/ dlvm pvresize -v ${lvm_pv_path}  p( r0 W/ }2 n* L
lvm vgchange --sysinit -ay
% h, E. m$ b; Q8 |lvm lvextend -v -l +100%FREE ${lvm_lv_root}* x) o) ?/ K" }; T2 I/ f
然后执行:) _. T: d/ Z* b- R& M$ G$ |8 A
./ extend_root_fs3 i1 `+ g9 [* K7 j7 M3 d+ C2 z
再重启系统即可。
, U0 T/ x5 V* K% s
8 `3 [, S4 C3 D1 n, C, P

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2021-5-26 17:00:22 | 显示全部楼层
要实现cloud.cfg文件的自动生效
5 m+ T" O, F0 o  {  }- f% l$ C2 \8 Z可以通过添加些参数
0 z3 B, C! ]" U4 C- t$ v; v2 ~! ubootcmd:( k/ b; E6 c5 \/ ~5 y. a7 y
  - [colud-init-per,growpart,reboot]+ |  ]; J, F- n; X
  - sh extend_root_fs
% y3 U/ Z$ o$ u! _( k写好脚本的位置,即可实现。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

返回首页|Archiver|手机版|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )

GMT+8, 2026-6-12 01:02 , Processed in 0.020191 second(s), 22 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表