cloud-init 21.1 CentOS 8 安装指南
在 CentOS 8 上从零安装 cloud-init 21.1 的完整指南,含 vault 镜像源切换排障实录、dnf 在线/离线 RPM 两种安装方案、版本升级降级、cloud.cfg 配置解读与卸载清理,全部命令实测通过。
cloud-init 21.1 CentOS 8 安装指南
目标:在一台 CentOS 8 服务器上从零完成 cloud-init 21.1 的安装与验证,覆盖 EOL 后 vault 镜像源切换排障、dnf 在线安装、离线 RPM 安装、版本升级降级、配置文件解读与卸载清理。全部命令已在 CentOS 8.5.2111(x86_64)真实环境逐条实测,cloud-init 版本 21.1-7.el8_5.3。
一、环境信息
- 操作系统:CentOS 8.5.2111(8 系最后一个版本),x86_64
- cloud-init:21.1-7.el8_5.3(noarch 包,vault 仓库最终版本)
- Python:系统 python3(3.6),cloud-init 代码位于
/usr/lib/python3.6/site-packages/cloudinit - 包管理器:dnf
- 软件源:CentOS 8 已于 2021-12-31 停止维护(EOL),官方 mirrorlist 已下线,必须切换到 vault 归档源(见「三、软件源准备」)
- 关键路径:
/usr/bin/cloud-init(主程序)、/etc/cloud/(配置目录)、/var/lib/cloud/(运行数据目录)、/var/log/cloud-init.log(主日志)
二、前置条件
- 具备 root 权限,以下命令均以 root 执行。
- dnf 包管理器可用(CentOS 8 标配)。
- 软件源已按下一章切换到可用的 vault 镜像(CentOS 8 原生 mirrorlist 已失效,不切换无法安装)。
- cloud-init 为 noarch 包,不区分 CPU 架构,x86_64 / aarch64 通用。
三、软件源准备与 vault 镜像切换(排障实录)
CentOS 8 停维后,默认 repo 的 mirrorlist 域名已无法解析,vault 官方归档源也有访问限制。本章按实际排障顺序记录三步定位与解决过程。
3.1 故障一:mirrorlist 域名解析失败
直接执行任何 dnf 安装命令会先报 mirrorlist 拉取失败:
dnf makecache
实测回显(节选):
Curl error (6): Couldn't resolve host name for http://mirrorlist.centos.org/?release=8&arch=x86_64&repo=AppStream&infra=container
💡 说明:
Curl error (6)即 DNS 解析失败——mirrorlist.centos.org 已随 CentOS 8 EOL 下线,这不是本机 DNS 配置问题,换任何 DNS 服务器都无效。
3.2 故障二:官方 vault 归档源返回 403
把 baseurl 指向官方 vault(vault.centos.org)后,实测所有请求(含 repomd.xml)返回 403:
curl -I https://vault.centos.org/8.5.2111/BaseOS/x86_64/os/repodata/repomd.xml
实测回显(节选):
HTTP/2 403
💡 说明:vault.centos.org 由 CDN 承载,对部分网络环境按地域/UA 限流,整站 403 无法绕过,需要改用第三方镜像站。
3.3 切换到可用的 vault 镜像源
实测阿里云 centos-vault 归档镜像可用:
curl -sI https://mirrors.aliyun.com/centos-vault/8.5.2111/BaseOS/x86_64/os/repodata/repomd.xml | head -1
实测回显:
HTTP/2 200
把全部 repo 文件从 mirrorlist 切到该镜像(8.5.2111 是 8 系最后版本,对应归档路径固定):
sed -i -e 's|mirrorlist=|#mirrorlist=|g' -e 's|#baseurl=http://mirror.centos.org|baseurl=https://mirrors.aliyun.com/centos-vault|g' /etc/yum.repos.d/CentOS-Linux-*.repo
刷新缓存验证:
dnf makecache
实测回显:
CentOS Linux 8 - AppStream 8.4 MB/s | 8.4 MB 00:01
CentOS Linux 8 - BaseOS 4.6 MB/s | 4.6 MB 00:01
CentOS Linux 8 - Extras 10 kB/s | 10 kB 00:00
Metadata cache created.
💡 说明:三行元数据全部拉取成功且出现
Metadata cache created.即源切换完成。8.5.2111 归档中 AppStream/BaseOS/Extras 三个仓库齐全,后续安装均走此源。
四、版本选型说明
切换源之后,用 --showduplicates 查看仓库内全部可用版本:
dnf list --showduplicates cloud-init
实测回显:
Available Packages
cloud-init.noarch 21.1-7.el8 AppStream
cloud-init.noarch 21.1-7.el8_5.3 AppStream
| 版本 | 来源 | 说明 |
|---|---|---|
| 21.1-7.el8 | AppStream 基线 | 8.5 GA 时的原始版本 |
| 21.1-7.el8_5.3 | AppStream 更新 | 带补丁的最终版本,vault 收官版本,推荐 |
关键差异:el8_5.3 是在 el8 基础上叠加安全/缺陷修复后的 build,直接 dnf install cloud-init 默认装到的就是它;仅当复现旧环境问题时才需要指定 21.1-7.el8。
与上游对照:上游社区最新 release 为 26.2(2026-07-29),但 CentOS 8 平台只能使用发行版仓库内的 21.1 系版本,上游 GitHub 资产也仅覆盖 el9,el8 无官方新版 RPM。21.1 的子命令集与新版有差异(无 schema 子命令,query 键名为下划线风格),相关差异在「九、常见问题」中说明。
五、方案 A:dnf 在线安装(推荐)
5.1 安装最新版本
dnf install -y cloud-init
实测回显(节选):
Installed:
cloud-init-21.1-7.el8_5.3.noarch
dhcp-client-4.4.2-15.el8.x86_64
python3-jinja2-2.10.1-3.el8.noarch
python3-jsonpatch-1.21-2.el8.noarch
python3-jsonschema-2.6.0-4.el8.noarch
python3-oauthlib-2.1.0-1.el8.noarch
python3-pyyaml-3.12-12.el8.x86_64
python3-requests-2.20.0-2.1.el8_1.noarch
xfsprogs-5.0.0-9.el8.x86_64
Complete!
💡 说明:dnf 自动带入 python3-jinja2/jsonschema/oauthlib/requests、pyyaml 与 xfsprogs(growpart/resizefs 配套)等依赖,无需手工安装。
5.2 安装指定历史版本
需要固定到原始版本时,用 包名-版本 精确指定:
dnf install -y cloud-init-21.1-7.el8
实测回显(节选):
python3-pytz-2017.2-9.el8.noarch
python3-pyyaml-3.12-12.el8.x86_64
python3-requests-2.20.0-2.1.el8_1.noarch
xfsprogs-5.0.0-9.el8.x86_64
Complete!
验证版本:
cloud-init --version
实测回显:
/usr/bin/cloud-init 21.1-7.el8
5.3 升级已装版本
从基线版本升级到补丁版本:
dnf update -y cloud-init
实测回显(节选):
Upgraded:
cloud-init-21.1-7.el8_5.3.noarch
Complete!
验证版本:
cloud-init --version
实测回显:
/usr/bin/cloud-init 21.1-7.el8_5.3
5.4 验证安装结果
核对 rpm 包状态:
rpm -q cloud-init
实测回显:
cloud-init-21.1-7.el8_5.3.noarch
核对主程序版本:
cloud-init --version
实测回显:
/usr/bin/cloud-init 21.1-7.el8_5.3
核对 systemd 单元注册清单:
rpm -ql cloud-init | grep 'systemd/system'
实测回显:
/usr/lib/systemd/system-generators/cloud-init-generator
/usr/lib/systemd/system/cloud-config.service
/usr/lib/systemd/system/cloud-config.target
/usr/lib/systemd/system/cloud-final.service
/usr/lib/systemd/system/cloud-init-local.service
/usr/lib/systemd/system/cloud-init.service
/usr/lib/systemd/system/cloud-init.target
💡 说明:四个服务单元(local/init/config/final)加两个 target,另有 cloud-init-generator 在系统引导时按数据源探测结果动态生成依赖链,这是 RHEL 系打包与 Ubuntu 打包的布局差异。单元内同样带
ConditionPathExists=!/etc/cloud/cloud-init.disabled等禁用开关。
六、方案 B:离线 RPM 包安装
6.1 下载 RPM 包
在能联网的机器上用 dnf download(由 dnf-plugins-core 提供,缺装时先 dnf install -y dnf-plugins-core):
mkdir -p /tmp/offline-rpm
cd /tmp/offline-rpm
dnf download cloud-init
实测回显:
cloud-init-21.1-7.el8_5.3.noarch.rpm 5.3 MB/s | 1.0 MB 00:00
核对产物:
ls -l /tmp/offline-rpm/
实测回显:
total 1072
-rw-r--r-- 1 root root 1093828 Oct 16 18:12 cloud-init-21.1-7.el8_5.3.noarch.rpm
6.2 rpm -ivh 直装及其依赖问题
裸 rpm 安装会因依赖缺失被拒:
rpm -ivh /tmp/offline-rpm/cloud-init-21.1-7.el8_5.3.noarch.rpm
实测回显(节选):
python3-jinja2 is needed by cloud-init-21.1-7.el8_5.3.noarch
python3-jsonpatch is needed by cloud-init-21.1-7.el8_5.3.noarch
python3-jsonschema is needed by cloud-init-21.1-7.el8_5.3.noarch
python3-oauthlib is needed by cloud-init-21.1-7.el8_5.3.noarch
python3-prettytable is needed by cloud-init-21.1-7.el8_5.3.noarch
python3-pyserial is needed by cloud-init-21.1-7.el8_5.3.noarch
python3-requests is needed by cloud-init-21.1-7.el8_5.3.noarch
xfsprogs is needed by cloud-init-21.1-7.el8_5.3.noarch
⚠️ 注意:rpm 不会自动解析依赖,cloud-init 依赖 8 个包,逐个凑齐易遗漏。
6.3 用 dnf 安装本地 RPM 并自动补齐依赖
推荐把本地 RPM 交给 dnf,由它从源中自动补齐全部依赖:
dnf install -y /tmp/offline-rpm/cloud-init-21.1-7.el8_5.3.noarch.rpm
实测回显(节选):
python3-cryptography-3.2.1-5.el8.x86_64
python3-jinja2-2.10.1-3.el8.noarch
python3-jsonpatch-1.21-2.el8.noarch
python3-jsonschema-2.6.0-4.el8.noarch
python3-markupsafe-0.23-19.el8.x86_64
python3-oauthlib-2.1.0-1.el8.noarch
python3-prettytable-0.7.2-14.el8.noarch
python3-pyserial-3.1.1-8.el8.noarch
python3-pyyaml-3.12-12.el8.x86_64
python3-requests-2.20.0-2.1.el8_1.noarch
xfsprogs-5.0.0-9.el8.x86_64
Complete!
6.4 验证安装结果
rpm -q cloud-init
实测回显:
cloud-init-21.1-7.el8_5.3.noarch
cloud-init --version
实测回显:
/usr/bin/cloud-init 21.1-7.el8_5.3
七、安装方案对比与选择建议
| 维度 | 方案 A:dnf 在线安装 | 方案 B:离线 RPM 安装 |
|---|---|---|
| 网络要求 | 可达 vault 镜像源 | 仅下载机需联网,目标机可离线 |
| 版本选择 | 默认最新 el8_5.3,可 包名-版本 固定 | 与下载的 RPM 版本一致 |
| 依赖处理 | 全自动 | rpm -ivh 手工凑依赖,dnf install 本地rpm 自动补齐 |
| 适用场景 | 常规服务器 | 内网隔离环境、固定版本交付 |
选择建议:能访问 vault 镜像源时一律用方案 A;内网批量交付用方案 B 且落地时用「dnf install + 本地文件路径」形式(如 6.3 小节的 dnf install -y /tmp/offline-rpm/cloud-init-21.1-7.el8_5.3.noarch.rpm),避免 6.2 小节的依赖缺漏问题。
八、安装后配置说明
8.1 /etc/cloud/cloud.cfg 全文与逐段解读
CentOS 8 的 cloud.cfg(69 行)比 Ubuntu 精简,全文如下:
users:
- default
disable_root: 1
ssh_pwauth: 0
mount_default_fields: [~, ~, 'auto', 'defaults,nofail,x-systemd.requires=cloud-init.service', '0', '2']
resize_rootfs_tmp: /dev
ssh_deletekeys: 1
ssh_genkeytypes: ['rsa', 'ecdsa', 'ed25519']
syslog_fix_perms: ~
disable_vmware_customization: false
cloud_init_modules:
- disk_setup
- migrator
- bootcmd
- write-files
- growpart
- resizefs
- set_hostname
- update_hostname
- update_etc_hosts
- rsyslog
- users-groups
- ssh
cloud_config_modules:
- mounts
- locale
- set-passwords
- rh_subscription
- yum-add-repo
- package-update-upgrade-install
- timezone
- puppet
- chef
- salt-minion
- mcollective
- disable-ec2-metadata
- runcmd
cloud_final_modules:
- rightscale_userdata
- scripts-per-once
- scripts-per-boot
- scripts-per-instance
- scripts-user
- ssh-authkey-fingerprints
- keys-to-console
- phone-home
- final-message
- power-state-change
system_info:
default_user:
name: cloud-user
lock_passwd: true
gecos: Cloud User
groups: [adm, systemd-journal]
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
shell: /bin/bash
distro: rhel
paths:
cloud_dir: /var/lib/cloud
templates_dir: /etc/cloud/templates
ssh_svcname: sshd
# vim:syntax=yaml
逐段解读:
users: - default:默认创建 system_info.default_user 定义的cloud-user(lock_passwd true 即密码锁定,仅密钥登录);disable_root: 1与ssh_pwauth: 0:禁 root 直连 SSH、禁密码认证,RHEL 系默认比 Ubuntu 收得更紧(Ubuntu 的 cloud.cfg 未显式写 ssh_pwauth);mount_default_fields:挂载默认字段带上x-systemd.requires=cloud-init.service,保证数据盘挂载在 cloud-init 完成后进行;ssh_genkeytypes: ['rsa', 'ecdsa', 'ed25519']:首启生成三类主机密钥;- 三大模块清单共 12+13+10 个,模块名用连字符旧风格(
write-files、users-groups、set-passwords),并保留 RHEL 系特有的migrator、rh_subscription、yum-add-repo; system_info.distro: rhel:CentOS 8 复用 rhel 发行版类;ssh_svcname: sshd对应 RHEL 系的服务名(Ubuntu 为 ssh)。
8.2 cloud.cfg.d 与模板目录
扩展配置目录实测只有两个包自带文件:
ls -l /etc/cloud/cloud.cfg.d/
实测回显:
total 16
-rw-r--r-- 1 root root 2070 Feb 23 2021 05_logging.cfg
-rw-r--r-- 1 root root 167 Feb 23 2021 README
💡 说明:与 Ubuntu 不同,RHEL 系打包没有
90_dpkg.cfg,datasource_list未显式定义,cloud-init 按内置顺序探测全部数据源;需要收窄时自建一个编号文件(如/etc/cloud/cloud.cfg.d/92-preserve-datasources.cfg)写入datasource_list: [ NoCloud, ConfigDrive ]即可。05_logging.cfg内容与 Ubuntu 版基本一致:日志写/var/log/cloud-init.log,命令输出经tee -a落/var/log/cloud-init-output.log。
模板目录实测清单(24 个):
ls /etc/cloud/templates/
实测回显:
chef_client.rb.tmpl
chrony.conf.alpine.tmpl
chrony.conf.debian.tmpl
chrony.conf.fedora.tmpl
chrony.conf.opensuse.tmpl
chrony.conf.rhel.tmpl
chrony.conf.sles.tmpl
chrony.conf.ubuntu.tmpl
hosts.alpine.tmpl
hosts.debian.tmpl
hosts.freebsd.tmpl
hosts.redhat.tmpl
hosts.suse.tmpl
ntp.conf.alpine.tmpl
ntp.conf.debian.tmpl
ntp.conf.fedora.tmpl
ntp.conf.opensuse.tmpl
ntp.conf.rhel.tmpl
ntp.conf.sles.tmpl
ntp.conf.ubuntu.tmpl
resolv.conf.tmpl
sources.list.debian.tmpl
sources.list.ubuntu.tmpl
timesyncd.conf.tmpl
另有 NetworkManager 分发钩子:
ls /etc/NetworkManager/dispatcher.d/ | grep cloud
实测回显:
cloud-init-azure-hook
💡 说明:
cloud-init-azure-hook用于 Azure 平台网网卡 DHCP 重配场景,私有环境不触发,无需处理。
8.3 initscripts 依赖说明
21.1 的 set-passwords 等模块在需要重启 sshd 时调用 service sshd restart,该命令由 initscripts 包提供。精装 CentOS 8 可能缺少此包,缺失时模块动作会失败,先确认并补装:
rpm -q initscripts
实测回显:
initscripts-10.00.15-1.el8.x86_64
若未安装则执行:
dnf install -y initscripts
九、常见问题(FAQ)
Q1:dnf 报 Error: Unable to find a match: htop,AppStream 里没有的包怎么办?
CentOS 8 官方仓库不含 htop 等常用工具,需要 EPEL:
dnf install -y epel-release
dnf install -y htop
本文 cloud-init 相关演示中需要 JSON 处理时,直接使用了 BaseOS 自带的 jq(实测版本 jq-1.5-12.el8.x86_64),避免引入额外源。
Q2:cloud-init schema 提示 invalid choice,21.1 怎么校验 user-data?
cloud-init schema
实测回显:
usage: /usr/bin/cloud-init [-h] [--version] [--file FILES] [--debug] [--force]
{init,modules,single,query,dhclient-hook,features,analyze,devel,collect-logs,clean,status}
...
/usr/bin/cloud-init: error: argument subcommand: invalid choice: 'schema' (choose from 'init', 'modules', 'single', 'query', 'dhclient-hook', 'features', 'analyze', 'devel', 'collect-logs', 'clean', 'status')
schema 校验是 21.4 才加入的子命令,21.1 无法使用;建议升级检查手段:一是先在 26.1 环境校验好 user-data 再投放(两个版本的 cloud-config 键基本兼容),二是观察首启日志 /var/log/cloud-init-output.log 中各模块的执行报错。
Q3:cloud-init query instance-id 报 ERROR: Undefined instance-data key instance-id?
21.1 的 query 键名是下划线风格(instance_id、local_hostname),26.x 才同时支持连字符风格:
cloud-init query v1.instance_id
实测回显:
iid-centos8-demo-001
Q4:mirrorlist 与 vault.centos.org 都不可用,还有哪些可用镜像?
任何同步了 CentOS 8.5.2111 归档的镜像站均可,把 baseurl 指向 .../centos-vault/8.5.2111/BaseOS/x86_64/os/ 与 .../AppStream/... 即可;本文实测使用阿里云镜像(回显见「三、软件源准备」3.3 小节)。
Q5:升级到 el8_5.3 后 /etc/cloud/cloud.cfg 会被覆盖吗?
rpm 升级对配置文件采用 .rpmnew 机制,用户修改过的 cloud.cfg 以本地文件为准,新版默认配置存为 cloud.cfg.rpmnew 供对照,与 apt 的 conffile 机制类似。
十、卸载与清理
dnf remove -y cloud-init
实测回显(节选):
Removed:
cloud-init-21.1-7.el8_5.3.noarch
python3-requests-2.20.0-2.1.el8_1.noarch
xfsprogs-5.0.0-9.el8.x86_64
Complete!
验证卸载结果:
rpm -q cloud-init
实测回显:
package cloud-init is not installed
ls /etc/cloud
实测回显:
ls: cannot access '/etc/cloud': No such file or directory
ls /var/lib/cloud
实测回显:
ls: cannot access '/var/lib/cloud': No such file or directory
💡 说明:与 Ubuntu 的 purge 保留
/var/lib/cloud/不同,dnf remove 会把包拥有的/etc/cloud/与/var/lib/cloud/目录一并删除(含 seed 种子与首启状态)。若误删种子需重新投放 user-data/meta-data;仅想清日志可保留目录只删/var/log/cloud-init.log与/var/log/cloud-init-output.log。
十一、参考链接
- cloud-init 官网:https://cloud-init.io/
- 官方文档(Read the Docs):https://cloud-init.readthedocs.io/
- GitHub 仓库与 Releases:https://github.com/canonical/cloud-init
- CentOS 8 vault 归档镜像:https://mirrors.aliyun.com/centos-vault/8.5.2111/
- CentOS 官方 EOL 说明:https://www.centos.org/centos-linux-eol/