cloud-init 21.1 CentOS 8 安装指南

在 CentOS 8 上从零安装 cloud-init 21.1 的完整指南,含 vault 镜像源切换排障实录、dnf 在线/离线 RPM 两种安装方案、版本升级降级、cloud.cfg 配置解读与卸载清理,全部命令实测通过。

cloud-initcloud-initCentOSCentOS 8Linuxsystemd2026/10/17

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(主日志)

二、前置条件

  1. 具备 root 权限,以下命令均以 root 执行。
  2. dnf 包管理器可用(CentOS 8 标配)。
  3. 软件源已按下一章切换到可用的 vault 镜像(CentOS 8 原生 mirrorlist 已失效,不切换无法安装)。
  4. 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.el8AppStream 基线8.5 GA 时的原始版本
21.1-7.el8_5.3AppStream 更新带补丁的最终版本,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。

十一、参考链接