Cloud-Init
什么是 Cloud-Init?
Cloud-Init 是一个开源工具,运行在云服务器实例内部的一个非常驻服务,在开机启动时执行,执行完成立即退出,不会监听任何端口。
腾讯云的 Linux 公有镜像都预安装了 Cloud-Init 服务。由于 Cloud-Init 服务主要用于实现对 CVM 实例的初始化操作(例如,对 DNS,Hostname,IP 等信息的配置),以及执行一些用户在创建 CVM 实例时指定首次开机启动要执行的自定义脚本,因此需要以 root 用户运行 Cloud-Init 服务。
如何确认 Linux 实例内部的 Cloud-Init 服务是否正常运行?
Cloud-Init 服务运行排查方案
说明:
该步骤仅适用于使用 Linux 公共镜像创建的云服务器实例。若您自行安装了 Cloud-Init,请结合实际情况调整执行命令。
1. 删除 cloud-init 缓存目录。
rm -rf /var/lib/cloud
2. 执行完整的 cloud-init 初始化。
/usr/bin/cloud-init init --local
3. 根据配置的数据源拉取数据。
/usr/bin/cloud-init init
4. Cloud-Init 初始化分为多个 stage,为保证各个 stage 的依赖充分,cloud-init modules 指定运行 config stage。
/usr/bin/cloud-init modules --mode=config
5. cloud-init modules 指定运行 final stage。
/usr/bin/cloud-init modules --mode=final
Cloud-Init 执行了哪些实例初始化的操作?
初始化类型 | 默认行为 | 禁用方式 | 注意事项 |
hostname 的初始化 | 实例首次启动时,Cloud-Init 会根据 vendor_data.json 中的 hostname 信息来设置实例的 hostname。 | 当您使用自定义镜像创建或重装实例时,如需保持自定义镜像内部自定义的 hostname 设置,则请在制作自定义镜像之前将 /etc/cloud/cloud.cfg 中的 preserve_hostname 设置为 true ,并删除 - scripts-user 这行配置。 | 若 preserve_hostname 为 true 且 - scripts-user 配置被禁用,则实例内部的 /var/lib/cloud/instance/scripts/runcmd 初始化脚本将不会被执行,并会同时影响其他子项的初始化(主要涉及:云监控、云安全的安装、软件源的设置)。 同时,在您创建子机时,自定义脚本也不会被执行。 |
/etc/hosts 的初始化 | 实例首次启动时,Cloud-Init 会默认将 /etc/hosts 初始化为 127.0.0.1 $hostname 。 | 当您使用自定义镜像创建或重装实例时,您想保持自定义镜像内部自定义的 /etc/hosts 设置,可以在制作自定义镜像之前在 /etc/cloud/cloud.cfg 里面删除 - scripts-user 与 - ['update_etc_hosts', 'once-per-instance'] 这两行配置。 | 如果您禁用了 - scripts-user 这行配置,实例内部的 /var/lib/cloud/instance/scripts/runcmd 初始化脚本将不会被执行,并会同时影响其他子项的初始化(主要涉及:云监控、云安全的安装、软件源的设置)。同时,在您创建子机时,自定义脚本也不会被执行。每当子机重启时,部分存量机器 /etc/hosts 的设置都会被覆盖。解决方案请参见 如何有效的修改 Linux 实例的 etc hosts 配置。 |
DNS 的初始化(非 DHCP 场景) | 实例首次启动时,Cloud-Init 会根据 vendor_data.json 中的 nameservers 信息来设置实例的 DNS。 | 当您使用自定义镜像创建或重装实例时,您想保持自定义镜像内部自定义的 DNS 设置,可以在制作自定义镜像之前在 /etc/cloud/cloud.cfg 里面删除 - resolv_conf 与 unverified_modules: ['resolv_conf'] 两行配置。 | 无。 |
软件源的初始化 | 实例首次启动时,Cloud-Init 会根据 vendor_data.json 中的 write_files 信息来设置实例的软件源。 | 当您使用自定义镜像创建或重装实例时,您想保持自定义镜像内部自定义的软件源设置,可以在制作自定义镜像之前在 /etc/cloud/cloud.cfg 里面删除 - write-files 这行配置。 | 无。 |
NTP 的初始化 | 实例首次启动时,Cloud-Init 会根据 vendor_data.json 中的 NTP Server 信息来设置实例的 NTP 服务器配置,并拉起 NTP Service。 | 当您使用自定义镜像创建或重装实例时,您想保持自定义镜像内部自定义的 NTP 设置,可以在制作自定义镜像之前在 /etc/cloud/cloud.cfg 里面删除 - ntp 这行配置。 | 无。 |
密码的初始化 | 实例首次启动时,Cloud-Init 会根据 vendor_data.json 中的 chpasswd 信息来设置实例的默认账号密码。 | 当您使用自定义镜像创建或重装实例时,您想保持自定义镜像内部自定义的默认账号密码,可以在制作自定义镜像之前在 /etc/cloud/cloud.cfg 里面删除 - set-passwords 这行配置。 | 无。 |
密钥绑定 | 实例首次启动时,Cloud-Init 会根据 vendor_data.json 中的 ssh_authorized_keys 信息来设置实例的默认账号密钥。 | 当您使用自定义镜像创建或重装实例时,您想保持自定义镜像内部自定义的密钥,可以在制作自定义镜像之前在 /etc/cloud/cloud.cfg 里面删除 - users-groups 这行配置。 | 如果您通过手工的方式在实例内部自行绑定密钥,在通过控制台下发密钥绑定的操作时,系统会将此密钥覆盖。 |
网络初始化(非 DHCP 场景) | 实例首次启动时,Cloud-Init 会根据 network_data.json 中的信息来设置实例的 IP、GATEWAY、MASK 等。 | 当您使用自定义镜像创建或重装实例时,您想保持自定义镜像内部自定义的网络信息,可以在制作自定义镜像之前在 /etc/cloud/cloud.cfg 里面增加 network: {config: disabled} 这行配置。 | 无。 |
如何排查 Cloud-Init 常见问题?
1. 因卸载 Cloud-Init 的依赖包导致报错
问题现象:
在使用命令确认 Cloud-Init 服务是否正常运行时,收到如下的错误:
Traceback (most recent call last):File "/usr/bin/cloud-init", line 5, in********raise DistributionNotFound(req)pkg_resources.DistributionNotFound: pyyaml
问题分析:
“pkg_resources.DistributionNotFound: xxxxx ” 表示 Cloud-Init 的安装依赖包被卸载。
解决方案:
1.1 重新安装该依赖包。
1.2 根据 Cloud-Init 服务运行排查方案 执行操作,直至全部执行完无错误为止。
2. 修改了默认 Python 解释器导致报错
问题现象:
在开机启动执行 Cloud-Init 时报错。
问题分析:
安装 Cloud-Init 时,Python 解释器默认使用 Python2(即
/usr/bin/python
与 /bin/python
这两个软链接指向 Python2)。当用户业务有需要时,可能会在实例内部把 Python 的默认解释器改为 Python3(即修改 /usr/bin/python
与 /bin/python
这两个软链接,使其指向 Python3)。由于兼容性问题,导致在开机启动执行 Cloud-Init 时报错。解决方案:
1.1 以 Python2.7为例,修改
/usr/bin/cloud-init
文件中指定的 Python 解释器,将 #!/usr/bin/python
或 #!/bin/python
修改为 #!/usr/bin/python2.7
。注意:
不要使用软连接,直接指向具体的解释器。
1.2 根据 Cloud-Init 服务运行排查方案 执行操作,直至全部执行完无错误为止。
Cloudbase-Init
什么是 Cloudbase-Init?
与 Cloud-Init 相似,Cloudbase-Init 是与 Windows 云服务器实例通信的桥梁。 在实例首次启动的时候会执行 Cloudbase-Init 服务,该服务会读取出实例的初始化配置信息,并对实例进行初始化操作。同时包括后续的重置密码、修改 IP 等功能也都是通过 Cloudbase-Init 来实现的。
如何确认 Windows 实例内部的 Cloudbase-Init 服务是否正常运行?
Cloudbase-Init 服务运行排查方案
1. 登录实例。
说明:
2. 打开控制面板,搜索并找到服务。
3. 找到 cloudbase-init 服务,并右键单击属性,打开 cloudbase-init 的属性窗口。
查看启动类型,确保启动类型为自动。如下图所示:
![](https://qcloudimg.tencent-cloud.cn/image/document/5c381f187fed63dd405d4ead4dabd4b4.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/5c381f187fed63dd405d4ead4dabd4b4.png)
查看登录身份,确保登录身份为本地系统账户。如下图所示:
![](https://qcloudimg.tencent-cloud.cn/image/document/d6b0525fb2df371d4b8ae8b061ad6189.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/d6b0525fb2df371d4b8ae8b061ad6189.png)
手动启动 cloudbase-init 服务并观察是否有相关报错。
如果有报错需要优先解决,并请确认是否安装相关安全软件拦截 cloudbase-init 执行的相关操作。
![](https://qcloudimg.tencent-cloud.cn/image/document/20291756e2be41ff02fb09d90ba99bc9.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/20291756e2be41ff02fb09d90ba99bc9.png)
打开注册表搜索并找到全部的 LocalScriptsPlugin,确保其值为2。如下图所示:
![](https://qcloudimg.tencent-cloud.cn/image/document/2887a30028064bd58cedc81c2a6d8f30.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/2887a30028064bd58cedc81c2a6d8f30.png)
确认 CD-ROM 的加载是否被禁用。如下图所示,可以看到一个光驱设备,则表示正常加载;否则是被禁用了,需要取消禁用。
![](https://qcloudimg.tencent-cloud.cn/image/document/f16d656a0735391cb2c077aae39553ba.png)
![](https://qcloudimg.tencent-cloud.cn/image/document/f16d656a0735391cb2c077aae39553ba.png)
Cloudbase-Init 执行了哪些实例初始化的操作?
初始化类型 | 默认行为 | 禁用方式 | 注意事项 |
hostname 的初始化 | 实例首次启动时, Cloudbase-Init 根据元数据服务或用户数据设置主机名。 | 在 cloudbase-init.conf 中设置set_hostname 为 false。 | 主机名必须符合RFC 952规范。 |
配置网络 | 实例首次启动时, Cloudbase-Init 根据元数据服务或用户数据配置虚拟机的网络设置。 | 在 cloudbase-init.conf 中设置network_adapter 为 none。 | 确保提供的网络配置是正确的。 |
生成新的 SSH 密钥对(仅适用于支持 SSH 的 Windows 系统) | 实例首次启动时, Cloudbase-Init 生成新的 SSH 密钥对,并将公钥添加到用户数据中。 | 在 cloudbase-init.conf 中设置generate_ssh_keys 为 false。 | 禁用此功能后,需要手动设置 SSH 密钥对。 |
设置用户密码 | 实例首次启动时, Cloudbase-Init 为新创建的用户账户设置一个随机密码。 | 在 cloudbase-init.conf 中删除 plugins 配置中的cloudbaseinit.plugins.common.setuserpassword.SetUserPasswordPlugin 。 | 禁用此功能后,需要手动设置用户密码。 |
执行用户数据脚本 | 执行用户数据中包含的脚本。 | 在 cloudbase-init.conf 中删除 plugins 配置中的cloudbaseinit.plugins.common.userdata.UserDataPlugin 。 | 用户数据脚本应该是可执行的,并且不应包含任何可能破坏虚拟机的操作。 |
如何查看 Cloudbase-Init 执行日志?
您可对应操作系统,查看以下日志文件:
Linux 系统:
/var/log/cloud-init-output.log
Windows 系统:
C:\\Program Files\\Cloudbase Solutions\\Cloudbase-Init\\log\\cloudbase-init.log
如何排查 Cloudbase-Init 常见问题?
初始化重置密码失败
可能原因:
手动修改 cloudbase-init 账号密码导致 cloudbase-init 服务启动失败,从而使得初始化重置密码等操作失败。
禁用了 cloudbase-init 服务,从而使得初始化重置密码等操作失败。
安装安全软件拦截了 cloudbase-init 服务重置密码的操作,从而使得重置密码流程返回成功但实际重置失败。
解决方案:
请针对可能原因,分别参考以下三点进行操作。
1.1 将 cloudbase-init 服务改为 LocalSystem 服务,具体操作方式请参见 Cloudbase-Init 服务运行排查方案 的 步骤 2。
1.2 将 cloudbase-init 服务启动类型改为自动。 具体操作方式请参见 Cloudbase-Init 服务运行排查方案 的 步骤 2。
1.3 卸载对应的安全软件, 或在安全软件里面对 cloudbase-init 服务的相关操作加白名单。