制作 YUM RPM 仓库指南

制作 YUM RPM 仓库指南

相关文档

1. 介绍 YUM

YUM(Yellowdog Updater Modified)是一个基于 RPM 包管理的开源命令行软件包管理工具,主要用于基于 Red Hat 的 Linux 发行版(如 RHEL、CentOS、AnolisOS、Fedora、Rocky Linux 等)。YUM 能够自动解决软件包之间的依赖关系,并从指定的软件仓库中下载、安装、更新或删除软件包。

YUM 的核心特性:

  • 自动依赖解析:安装一个软件包时,YUM 会自动分析并下载其所有依赖包,无需手动干预。
  • 仓库机制:软件包存储在远端或本地的“仓库”中,YUM 通过 .repo 配置文件定位仓库地址。
  • 事务化操作:将安装/更新/删除操作视为事务,保证操作原子性(要么全部成功,要么回滚)。
  • 增量更新:支持只下载有变化的包,提高效率。
  • 插件系统:可通过插件扩展功能(如 yum-fastestmirroryum-security)。

在现代 RHEL 8+ / CentOS 8+ 系统中,YUM 已被 DNF 取代(向后兼容 YUM 命令),但底层仓库结构和理念完全一致。本文内容同时适用于 YUM 和 DNF。

2. 介绍 RPM

RPM(Red Hat Package Manager)是低层级的软件包管理工具,也是软件包本身的格式名称(.rpm 文件)。RPM 直接操作单个软件包:安装、升级、卸载、查询等,但它不会自动处理依赖关系

RPM 包的组成:

  • 二进制文件:编译好的程序
  • 配置文件:如 /etc/ 下的默认配置
  • 元数据信息:包名、版本、发布号、架构、依赖关系(Requires)、提供能力(Provides)、冲突列表(Conflicts)等
  • 安装脚本:安装前/后、卸载前/后执行的 shell 脚本

常用 RPM 命令:

操作 命令示例
安装 rpm -ivh package.rpm
升级 rpm -Uvh package.rpm
卸载 rpm -e package-name
查询已安装 rpm -q package-name
查询包信息 rpm -qi package-name
列出包中文件 rpm -ql package-name

由于 RPM 无法自动处理依赖,因此需要 YUM 这样的上层工具来利用 RPM 仓库,实现全自动依赖管理。

3. 介绍 RPM 仓库结构

一个标准的 YUM RPM 仓库本质上是一个带有元数据索引的目录(可以是本地目录、HTTP 服务器、FTP 服务器等)。YUM 客户端通过读取这些元数据来了解仓库中有哪些包、版本、依赖关系等信息。

仓库目录典型结构

my-repo/                  # 仓库根目录
├── repodata/             # 元数据目录(必须)
│   ├── repomd.xml        # 主索引文件,记录其他元数据文件的校验和
│   ├── primary.xml.gz    # 包的基本信息(名称、版本、依赖等)
│   ├── filelists.xml.gz  # 每个包包含的文件列表
│   ├── other.xml.gz      # 额外信息(更新日志等)
│   └── ...               # 可能还有 comps.xml(包组定义)
├── Packages/             # 可选,通常用于存放实际 .rpm 文件(避免根目录混乱)
│   ├── nginx-1.20.1.rpm
│   ├── openssl-1.1.1k.rpm
│   └── ...
└── (或者 .rpm 直接放在根目录)

关键元数据文件说明

  • repomd.xml:仓库的“地图”,记录了 primaryfilelistsother 等数据文件的类型、位置、校验和(SHA256)及压缩方式。YUM 会首先下载并校验此文件。
  • primary.xml.gz:核心元数据,包含每个 RPM 包的包名、版本、架构、依赖关系(Requires/Provides)、大小、描述等信息。
  • filelists.xml.gz:每个包所包含的文件和目录清单(用于 yum providesdnf provides 查询某个文件属于哪个包)。
  • other.xml.gz:额外元数据,如变更日志(changelog)。

如何生成仓库元数据?

使用 createrepo_c(高性能 C 实现)或 createrepo(Python 实现)命令:

# 安装 createrepo_c(推荐,C 实现,性能更高)
yum install createrepo_c   # 或 dnf install createrepo_c

# 也可以安装 Python 版本的 createrepo
yum install createrepo     # 或 dnf install createrepo

# 进入包含 .rpm 文件的目录
cd /path/to/my-repo

# 生成元数据(会自动创建 repodata 目录)
createrepo_c .

# 如果仓库中新增了 RPM,需要更新元数据
createrepo_c --update .

生成后,客户端配置 .repo 文件指向该目录的 URL(例如 http://mirror.example.com/my-repo/ ),即可使用 yum install 从该仓库安装软件。

4. 介绍谁在用 RPM 仓库

RPM 仓库是 Linux 生态中软件分发与运维自动化的核心设施,以下角色和组织广泛使用或维护自己的 RPM 仓库:

4.1 Linux 发行版官方仓库

  • Red Hat:通过订阅提供 RHEL 官方仓库,包含经过严格测试的企业级软件包。
  • CentOS StreamRocky LinuxAlmaLinux:提供免费的二进制兼容仓库。
  • Fedora:面向社区的发行版,拥有更新频繁的官方仓库。
  • OpenSUSE(使用 RPM 格式):也通过类似 YUM 的 zypper 管理仓库。

4.2 第三方软件供应商

许多商业或开源软件厂商提供自己的 YUM 仓库,方便用户安装和更新他们的产品:

  • NVIDIA:CUDA 驱动和工具包仓库(developer.download.nvidia.com
  • Docker CEdownload.docker.com/linux/
  • MySQL / MariaDB / PostgreSQL:各自提供最新版仓库
  • Nginxnginx.org/packages/
  • Elastic Stack(Elasticsearch, Logstash, Kibana)
  • Zabbix 监控软件

4.3 企业内部 IT 运维团队

  • 私有软件分发:将公司自研的软件打包成 RPM,放入内网仓库,通过 YUM 实现一键部署和版本管理。
  • 离线/隔离环境:在无互联网的生产网或军工、金融内网中,运维人员会制作完整的内部镜像仓库,包含所有依赖的 RPM 包。
  • 标准化操作系统基线:通过自定义仓库统一所有服务器的软件版本,避免“依赖地狱”。

4.4 开发者和打包爱好者

  • 个人项目维护者:将自己的开源软件打成 RPM,提供仓库供他人添加和使用。
  • CI/CD 流水线:在持续集成中自动构建 RPM 包并推送至测试或生产仓库,用于自动化部署。
  • RPM 打包学习者:通过制作本地仓库练习 RPM 规范和 YUM 管理。

4.5 云基础设施和容器镜像

  • 公共云镜像构建:AWS、Azure、阿里云的 Linux 镜像中预置了发行版官方仓库及云厂商提供的额外工具仓库。
  • 容器基础镜像:如 Rocky Linux 的 Docker 镜像中,yummicrodnf 会从官方仓库安装软件包。
  • Kubernetes 节点:使用 kubeadm 安装时,通常需要添加 Kubernetes 的 YUM 仓库(packages.cloud.google.com 或阿里云镜像)。

他们如何使用或制作仓库?

  • 使用:在 /etc/yum.repos.d/ 下创建 .repo 文件,指定仓库名称、基 URL、GPG 密钥等,然后运行 yum update / yum install
  • 制作:收集或构建 .rpm 文件,运行 createrepo 生成元数据,最后用 HTTP 服务器(如 Nginx、Apache)将目录暴露出去,或者直接通过 file:// 协议提供本地仓库。

5. 实战:制作一个简单的 YUM 仓库

为了将理论付诸实践,下面演示从零构建一个本地 YUM 仓库,并使用它安装软件。

5.1 环境准备

一台 CentOS / RHEL / Rocky Linux 机器,确保有 createrepo_c 工具和 HTTP 服务器(可选)。

# 在 RHEL / CentOS / Fedora 上安装必要工具
yum install -y createrepo_c httpd   # 推荐 createrepo_c;也可用 createrepo(Python 版)
# 或 dnf install -y createrepo_c httpd;可用 nginx 替代 httpd

# 在 Debian / Ubuntu 上安装必要工具
apt install -y createrepo-c apache2   # 或 nginx

5.2 创建仓库目录并放入 RPM 包

# 创建仓库根目录
mkdir -p /var/www/html/local-repo/Packages

# 假设我们有一些 RPM 包(可手动下载或复制)
cp /path/to/*.rpm /var/www/html/local-repo/Packages/

5.3 生成元数据

cd /var/www/html/local-repo
createrepo_c .   # 注意:createrepo 会在当前目录下生成 repodata 目录

如果以后增加了新的 RPM,使用 --update 快速更新元数据:

cp new-package.rpm /var/www/html/local-repo/Packages/
createrepo_c --update /var/www/html/local-repo

5.4 启动 HTTP 服务

systemctl start httpd
systemctl enable httpd

确保防火墙放行 80 端口:

firewall-cmd --add-service=http --permanent
firewall-cmd --reload

此时仓库可通过 http://IP/local-repo/ 访问。

5.5 配置客户端使用该仓库

同一台机器或另一台机器上创建 .repo 文件:

vi /etc/yum.repos.d/local.repo

内容如下:

[local-repo]
name=Local YUM Repository
baseurl=http://192.168.1.100/local-repo/
enabled=1
gpgcheck=0   # 若 RPM 未签名,设为 0;生产环境应启用 GPG 签名

5.6 测试

清理缓存并列出仓库中的软件包:

yum clean all
yum repolist
yum --disablerepo="*" --enablerepo="local-repo" list available

尝试安装:

yum install --enablerepo=local-repo nginx -y

5.7 高级增强

  • GPG 签名:用 gpg --gen-key 生成密钥,用 rpm --addsign 对 RPM 签名,仓库设置 gpgcheck=1gpgkey=file:///path/to/public.key
  • 包组:创建 comps.xml 定义包组(如 “Web Server”),然后 createrepo -g comps.xml .
  • 镜像同步:使用 reposync 镜像远程仓库到本地,配合 createrepo --update 定期同步。

总结

YUM 与 RPM 构成了 Red Hat 系 Linux 发行版强大的软件管理体系。理解 RPM 包格式、YUM 仓库的元数据结构,以及如何创建和维护自己的仓库,是系统管理员、DevOps 工程师和开源贡献者的必备技能。无论是搭建离线更新源、发布内部软件,还是镜像公共仓库加速访问,掌握制作 YUM RPM 仓库的方法都将大幅提升你的工作效率和系统稳定性。

希望本文能帮助你从原理到实践,轻松构建属于自己的 RPM 仓库!