简介
最近的发行版(撰写本文时只有Ubuntu14.04和CentOS7)上可用的Cloud-init
程序能够使用和执行DigitalOcean Metadata service.]的User-Data
字段中的数据根据找到的信息的格式,此过程的行为会有所不同。user-data
中最流行的脚本格式之一是cloud-config 文件格式。
云配置文件是专为由Cloud-init进程运行而设计的特殊脚本。它们通常用于服务器第一次引导时的初始配置。在本指南中,我们将讨论云配置文件的格式和用法。
云配置一般信息
Cloud-Config
格式对许多常见的配置项实现了声明性语法,可以轻松完成许多任务。它还允许您为预定义的声明性功能之外的任何内容指定任意命令。
这种两全其美
的方法允许文件充当常见任务的配置文件,同时保持脚本的灵活性以实现更复杂的功能。
YAML格式设置
该文件使用YAML数据序列化格式编写。 YAML格式的创建是为了便于人类理解和易于程序解析。
YAML文件在阅读时通常相当直观,但最好知道管理它们的实际规则。
YAML文件的一些重要规则如下:
- 带空格的缩进表示项目的结构和彼此之间的关系。 缩进程度更高的项是第一项的子项,其上的缩进级别更低。
- 列表成员可以用前导破折号标识。
- 关联数组项是通过使用冒号(:)后跟空格和值来创建的。
- 文本块是缩进的。 若要指示块应按原样读取,并保持格式不变,请使用管道符(|)在块之前。
让我们来看看这些规则,并分析一个示例cloud-config
文件,只关注格式:
1#cloud-config
2users:
3 - name: demo
4 groups: sudo
5 shell: /bin/bash
6 sudo: ['ALL=(ALL) NOPASSWD:ALL']
7 ssh-authorized-keys:
8 - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDf0q4PyG0doiBQYV7OlOxbRjle026hJPBWD+eKHWuVXIpAiQlSElEBqQn0pOqNJZ3IBCvSLnrdZTUph4czNC4885AArS9NkyM7lK27Oo8RV888jWc8hsx4CD2uNfkuHL+NI5xPB/QT3Um2Zi7GRkIwIgNPN5uqUtXvjgA+i1CS0Ku4ld8vndXvr504jV9BMQoZrXEST3YlriOb8Wf7hYqphVMpF3b+8df96Pxsj0+iZqayS9wFcL8ITPApHi0yVwS8TjxEtI3FDpCbf7Y/DmTGOv49+AWBkFhS2ZwwGTX65L61PDlTSAzL+rPFmHaQBHnsli8U9N6E4XHDEOjbSMRX [email protected]
9 - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDcthLR0qW6y1eWtlmgUE/DveL4XCaqK6PQlWzi445v6vgh7emU4R5DmAsz+plWooJL40dDLCwBt9kEcO/vYzKY9DdHnX8dveMTJNU/OJAaoB1fV6ePvTOdQ6F3SlF2uq77xYTOqBiWjqF+KMDeB+dQ+eGyhuI/z/aROFP6pdkRyEikO9YkVMPyomHKFob+ZKPI4t7TwUi7x1rZB1GsKgRoFkkYu7gvGak3jEWazsZEeRxCgHgAV7TDm05VAWCrnX/+RzsQ/1DecwSzsP06DGFWZYjxzthhGTvH/W5+KFyMvyA+tZV4i1XM+CIv/Ma/xahwqzQkIaKUwsldPPu00jRN user@desktop
10runcmd:
11 - touch /test.txt
通过查看这份文件,我们可以了解到许多重要的事情。
首先,每个cloud-config
文件的第一行必须只以# cloud-config
开头。这向Cloud-init程序发出信号,表明这应该被解释为一个cloud-config
文件。如果这是一个常规脚本文件,则第一行将指示应该使用哪个解释器来执行该文件。
上面的文件有两个顶级指令,users
和runcmd
。 两者都是钥匙。 这些键的值由键后的所有缩进行组成。
在users
键的情况下,值是单个列表项。 我们知道这一点是因为下一级缩进是一个破折号(-),它指定了一个列表项,并且因为在这个缩进级别只有一个破折号。 在users
指令的情况下,这顺便表明我们只定义了一个用户。
列表项本身包含一个具有更多键值对的关联数组。 这些是兄弟元素,因为它们都存在于同一缩进级别。 每个用户属性都包含在我们上面描述的单个列表项中。
需要注意的是,您看到的字符串不需要引号,并且没有不必要的括号来定义关联。解释器可以相当容易地确定数据类型,缩进指示项之间的关系,对人和程序都是如此。
到目前为止,您应该已经掌握了YAML格式的工作知识,并且可以轻松地使用我们上面讨论的规则处理信息。
现在,我们可以开始探索cloud-config
的一些最常见的指令。
用户和组管理
要在系统上定义新用户,可以使用我们在上面的示例文件中看到的users
指令。
用户定义的一般格式为:
1#cloud-config
2users:
3 - first_user_parameter
4 first_user_parameter
5
6 - second_user_parameter
7 second_user_parameter
8 second_user_parameter
9 second_user_parameter
每个新用户都应该以破折号开头。每个用户都以键-值对的形式定义参数。以下密钥可用于定义:
- 名称 :帐号用户名。
- 主组 :用户的主组。默认情况下,这将是创建的与用户名匹配的组。此处指定的任何组必须已经存在或必须显式创建(我们将在本节后面讨论这一点)。
- 群组 :此处可以列出任意补充群组,以逗号分隔。
- Gecos :用户补充信息字段。
- 外壳 :应该为用户设置的外壳。如果您不设置它,将使用非常基本的‘sh`外壳。
- 过期日期 :账号的到期日期,格式为YYYY-MM-DD。
- sudo :如果要定义sudo权限,则使用sudo字符串,不带用户名字段。
- lock-passwd :默认设置为True。将其设置为
False
以允许用户使用密码登录。 - passwd :帐号的哈希密码。
- ssh授权密钥 :一个完整的SSH公钥列表,需要添加到该用户的
.ssh
目录下的授权密钥
文件中。 - 停用 :布尔值,用于将帐号设置为停用。
- 系统 :如果为True,则该帐号将是没有主目录的系统帐号。
- home dir :用于覆盖默认的
/home/<用户名>
,默认/home/<用户名>
由其他方式创建和设置。 - ssh-import-id :从LaunchPad导入的SSH ID。
- selinux-User :用于设置该账号登录时需要使用的SELinux用户。
- no-create-home :设置为True,避免为用户创建
/home/<用户名>
目录。 - no-user-group :设置为True,避免创建与用户同名的组。
- no-log-init :设置为True表示不启动用户登录数据库。
除了name
键等一些基本信息外,您只需要定义哪些区域偏离了默认设置或提供了需要的数据。
用户需要注意的一件事是,除非您有立即修改给定值的机制,否则不应在生产系统中使用passwd
字段。与作为用户数据提交的所有信息一样,在服务器的整个生命周期内,系统上的任何 用户都可以访问哈希。在现代硬件上,这些散列很容易在很短的时间内被破解。即使是暴露散列也是一个巨大的安全风险,不应该在任何不可丢弃的机器上承担。
对于示例用户定义,我们可以使用上面看到的示例cloud-config
的一部分:
1#cloud-config
2users:
3 - name: demo
4 groups: sudo
5 shell: /bin/bash
6 sudo: ['ALL=(ALL) NOPASSWD:ALL']
7 ssh-authorized-keys:
8 - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDf0q4PyG0doiBQYV7OlOxbRjle026hJPBWD+eKHWuVXIpAiQlSElEBqQn0pOqNJZ3IBCvSLnrdZTUph4czNC4885AArS9NkyM7lK27Oo8RV888jWc8hsx4CD2uNfkuHL+NI5xPB/QT3Um2Zi7GRkIwIgNPN5uqUtXvjgA+i1CS0Ku4ld8vndXvr504jV9BMQoZrXEST3YlriOb8Wf7hYqphVMpF3b+8df96Pxsj0+iZqayS9wFcL8ITPApHi0yVwS8TjxEtI3FDpCbf7Y/DmTGOv49+AWBkFhS2ZwwGTX65L61PDlTSAzL+rPFmHaQBHnsli8U9N6E4XHDEOjbSMRX [email protected]
9 - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDcthLR0qW6y1eWtlmgUE/DveL4XCaqK6PQlWzi445v6vgh7emU4R5DmAsz+plWooJL40dDLCwBt9kEcO/vYzKY9DdHnX8dveMTJNU/OJAaoB1fV6ePvTOdQ6F3SlF2uq77xYTOqBiWjqF+KMDeB+dQ+eGyhuI/z/aROFP6pdkRyEikO9YkVMPyomHKFob+ZKPI4t7TwUi7x1rZB1GsKgRoFkkYu7gvGak3jEWazsZEeRxCgHgAV7TDm05VAWCrnX/+RzsQ/1DecwSzsP06DGFWZYjxzthhGTvH/W5+KFyMvyA+tZV4i1XM+CIv/Ma/xahwqzQkIaKUwsldPPu00jRN user@desktop
要定义组,您应该使用groups
指令。 这个指令相对简单,因为它只接受您想要创建的组的列表。
一个可选的扩展是为您正在创建的任何组创建一个子列表。 此新列表将定义应置于此组中的用户:
1#cloud-config
2groups:
3 - group1
4 - group2: [user1, user2]
更改已有用户密码
对于已经存在的用户帐户(root帐户是最相关的),可以使用chpasswd指令提供密码。
注意 :此指令应** 仅** 用于调试情况,因为再次声明,该值将在服务器的整个生命周期内对系统上的每个用户可用。这一点在本节中更为相关,因为与此指令一起提交的密码必须以** 纯文本** 形式提供。
基本语法如下所示:
1#cloud-config
2chpasswd:
3 list: |
4 user1:password1
5 user2:password2
6 user3:password3
7 expire: False
该指令包含两个关联数组键。 list
键将包含一个块,其中列出了您想要分配的帐户名和相关密码。 expire
键是一个布尔值,用于确定是否必须在第一次引导时更改密码。 默认为True
。
需要注意的一点是,您可以将密码设置为随机或R,这将生成一个随机密码,并将其写入/var/log/cloud-init-output.log
。请记住,系统上的任何用户都可以访问此文件,因此它不再安全。
将文件写入磁盘
要将文件写入磁盘,应使用WRITE_FILES
指令。
每个应该写入的文件都由指令下的一个列表项表示。这些列表项将是定义每个文件属性的关联数组。
这个数组中唯一需要的键是path
,它定义了文件的写入位置,以及content
,它包含了你希望文件包含的数据。
可用于配置WRITE_FILES
项的密钥为:
- 路径 :文件系统中需要写入文件的位置的绝对路径。
- 内容 :应该放在文件中的内容。对于多行输入,应该在)作为块的开头,后跟包含内容的缩进块。二进制文件应包括
!!BINARY
和管道字符前的空格。 - 所有者 :应授予文件所有权的用户帐号和组。这些信息应以
用户名:组
的格式提供。 - 权限 :该文件应该被赋予的八进制权限集。
- 编码 :文件的可选编码规范。对于Base64文件,可以是
b64
;对于Gzip压缩文件,可以是gzip
;对于组合文件,可以是gz+b64
。省略此选项将使用默认的常规文件类型。
例如,我们可以向/test.txt
写入一个文件,其内容为:
1Here is a line.
2Another line is here.
完成此任务的cloud-config
部分如下所示:
1#cloud-config
2write_files:
3 - path: /test.txt
4 content: |
5 Here is a line.
6 Another line is here.
在服务器上更新或安装包
要管理包,有一些相关的设置和指令需要牢记。
要在基于Debian的发行版上更新apt数据库,您应该将package_update
指令设置为true
。 这与从命令行调用apt-get update
同义。
缺省值实际上为true
,因此如果您希望禁用该指令,则只需考虑该指令:
1#cloud-config
2package_update: false
如果您希望在服务器首次启动后升级服务器上的所有包,可以设置Package_Upgrade
指令。这类似于手动执行apt-get升级
。
默认情况下,它被设置为false
,所以如果你想要这个功能,请确保将它设置为true
:
1#cloud-config
2package_upgrade: true
要安装其他软件包,只需使用Packages
指令列出软件包名称即可。每个列表项都应该代表一个包。与上面的两个命令不同,该指令将与yum或apt管理的发行版一起工作。
这些项目可以采用两种形式之一。第一个只是一个包含包名称的字符串。第二个表单是一个包含两个项目的列表。这个新列表的第一项是包名,第二项是版本号:
1#cloud-config
2packages:
3 - package_1
4 - package_2
5 - [package_3, version_num]
Packages
指令会将apt_update
设置为True,覆盖之前的任何设置。
配置用户账号和SSH守护程序的SSH密钥
您可以在users
指令中管理SSH密钥,但也可以在专用的ssh_Authority_keys
部分中指定它们。这些将被添加到第一个定义的用户的AUTHORIZED_KEYS文件。
它采用与USERS
指令中的KEY规范相同的通用格式:
1#cloud-config
2ssh_authorized_keys:
3 - ssh_key_1
4 - ssh_key_2
您还可以提前生成SSH服务器的私钥,并将它们放在文件系统上。如果您想要事先向客户端提供有关此服务器的信息,使其能够在服务器一上线时就信任它,这可能会很有用。
为此,我们可以使用ssh_keys
指令。这可以使用rsa_Private
、rsa_Public
、dsa_Private
、dsa_Public
、ecdsa_Private
和ecdsa_Public
子项获取RSA、DSA或ECDSA密钥的密钥对。
由于格式和换行符对于私钥很重要,因此在指定它们时,请确保将块与管道键一起使用。此外,您必须 包括BEGIN KEY和END KEY行才能使密钥有效。
1#cloud-config
2ssh_keys:
3 rsa_private: |
4 -----BEGIN RSA PRIVATE KEY-----
5 your_rsa_private_key
6 -----END RSA PRIVATE KEY-----
7
8 rsa_public: your_rsa_public_key
设置可信CA证书
如果您的基础结构依赖于由内部证书颁发机构签署的密钥,则可以通过注入证书信息将新计算机设置为信任您的CA证书。为此,我们使用ca-certs
指令。
该指令有两个子项。第一个是Remove-defaults
,当设置为True时,将删除默认包含的所有正常证书信任信息。这通常是不必要的,如果你不知道自己在做什么,可能会导致一些问题,所以使用时要谨慎。
第二项是trusted
,这是一个列表,每个列表包含一个受信任的CA证书:
1#cloud-config
2ca-certs:
3 remove-defaults: true
4 trusted:
5 - |
6 -----BEGIN CERTIFICATE-----
7 your_CA_cert
8 -----END CERTIFICATE-----
配置Resolv.conf使用特定的DNS服务器
如果您已经配置了自己想要使用的DNS服务器,则可以使用resolv_conf
指令管理服务器的resolv.conf文件。 这目前只适用于基于RHEL的发行版。
在Resolv_conf
指令下,您可以使用name ervers
、earch domains
、domain
和options
项来管理您的设置。
name ervers
指令应该获取您的名称服务器的IP地址列表。当用户指定主机而不是域时,searchdomains
指令获取要搜索的域和子域的列表。
domain
设置任何无法解析的请求应该使用的域名,options
包含一组选项,可以在解析器.conf文件中定义。
如果使用的是resolv_conf
指令,则必须确保manage-resolv-conf
指令也设置为true。 不这样做将导致您的设置被忽略:
1#cloud-config
2manage-resolv-conf: true
3resolv_conf:
4 nameservers:
5 - 'first_nameserver'
6 - 'second_nameserver'
7 searchdomains:
8 - first.domain.com
9 - second.domain.com
10 domain: domain.com
11 options:
12 option1: value1
13 option2: value2
14 option3: value3
运行任意命令以获得更多控制
如果cloud-config
提供的托管操作都不能达到您想要的效果,您也可以运行任意命令。您可以使用runcmd
指令来执行此操作。
此指令接受要执行的项的列表。这些项可以用两种不同的方式指定,这将影响它们的处理方式。
如果列表项是一个简单的字符串,则整个列表项将传递给sh
外壳进程运行。
另一个选项是传递一个列表,其中的每一项都将以类似于execve
处理命令的方式执行。 第一项将被解释为要运行的命令或脚本,而以下项将作为该命令的参数传递。
大多数用户可以使用这两种格式中的任何一种,但如果您有特殊要求,其灵活性使您能够选择最佳选项。所有输出都将写入标准输出和/var/log/cloud-init-output.log
文件:
1#cloud-config
2runcmd:
3 - [ sed, -i, -e, 's/here/there/g', some_file]
4 - echo "modified some_file"
5 - [cat, some_file]
关机或重启服务器
在某些情况下,您可能希望在执行其他项目后关闭或重新启动服务器。您可以通过设置Power_state
指令来实现这一点。
此指令有四个子项可以设置。 它们分别是delay
、timeout
、message
和mode
。
delay
指定重新启动或关机应该在多长时间后发生。默认情况下,这将是)。
timeout
参数获取一个无单位的值,表示在启动delay
倒计时之前等待Cloud-init完成的秒数。
Message
字段允许您指定将发送给系统所有用户的消息。`模式‘指定要启动的电源事件的类型。这可以是):
1#cloud-config
2power_state:
3 timeout: 120
4 delay: "+5"
5 message: Rebooting in five minutes. Please save your work.
6 mode: reboot
结论
上面的示例代表了在运行cloud-config
文件时可用的一些更常见的配置项。 还有一些我们在本指南中没有介绍的其他功能。 这些包括配置管理设置、配置其他存储库,甚至在初始化服务器时使用外部URL进行注册。
有关这些选项的更多信息,请查看/usr/Share/doc/Cloud-init/Examples
目录。如需了解Cloud-configuration](https://andsky.com/tech/tutorials/how-to-use-cloud-config-for-your-initial-server-setup)
文件的实用指南,请参考我们的教程[如何使用Cloud-Configer完成基础服务端配置]。