开发者
基础命令与 RPM 之变 —— 从 Yum 到 DNF 的平滑过渡
基础命令与 RPM 之变 —— 从 Yum 到 DNF 的平滑过渡
原创
发表于05/27
150

一、Yum 还在,但 DNF 已成默认

登录 openEuler 22.03,输入 yum install nginx,你会发现命令能正常执行。这是因为 openEuler 做了兼容别名 —— yum 实际上软链接到了 dnf

$ ls -l /usr/bin/yum
lrwxrwxrwx 1 root root 5 Mar 10  2024 /usr/bin/yum -> dnf-3
```

**为什么从 Yum 切到 DNF?**

- **Yum** 基于 Python 2,依赖复杂,内存占用高,事务处理慢。
- **DNF**(Dandified YUM)基于 Python 3(openEuler 默认 Python 3.8+),使用 libsolv 库解决依赖关系,性能更好,支持事务回滚。
- DNF 的 API 更清晰,便于上层自动化工具(如 Ansible、dnf-automatic)调用。

作为运维,你不需要彻底忘记 Yum,但推荐**主动使用 DNF 命令**,因为未来 RHEL 系(包括 CentOS Stream、Rocky、AlmaLinux)都会全面转向 DNF。

### 二、DNF 常用命令速查表(附 Yum 对照)


| 操作                     | Yum 命令                  | DNF 命令                  | 说明                               |
| ------------------------ | ------------------------- | ------------------------- | ---------------------------------- |
| 安装软件                 | `yum install pkg`         | `dnf install pkg`         | 完全兼容                           |
| 移除软件                 | `yum remove pkg`          | `dnf remove pkg`          | 完全兼容                           |
| 升级所有包               | `yum update`              | `dnf upgrade`             | `upgrade` 语义更明确,会处理废弃包 |
| 搜索包                   | `yum search keyword`      | `dnf search keyword`      | 结果展示更简洁                     |
| 列出已安装               | `yum list installed`      | `dnf list installed`      | 支持`--installed`                  |
| 查看哪个包提供了某个文件 | `yum provides */filename` | `dnf provides */filename` | 性能更快                           |
| 清理缓存                 | `yum clean all`           | `dnf clean all`           | 相同                               |
| 查看事务历史             | 无原生                    | `dnf history`             | **DNF 特有**,可回滚               |
| 回滚上一次事务           | 无                        | `dnf history undo last`   | 非常实用                           |
| 下载 RPM 包但不安装      | `yumdownloader`           | `dnf download`            | 需要安装`dnf-plugins-core`         |

**重点掌握**:`dnf history` 和 `dnf history undo`。比如你批量安装了一堆包导致冲突,不用一个个手删,直接回滚即可:

```bash
dnf history
ID     | Command line                                | Date and time
---------------------------------------------------------------
12     | install nginx mariadb-server php            | 2025-01-15 10:23
# 回滚 ID 12 的所有操作
dnf history undo 12
```

### 三、openEuler 软件仓库结构

与 CentOS 的 BaseOS/AppStream 类似,openEuler 的 repo 分为几个主要部分:

```bash
$ dnf repolist
repo id                     repo name
OS                          openEuler 22.03-LTS-SP3 base
everything                  openEuler 22.03-LTS-SP3 everything
EPOL                        openEuler 22.03-LTS-SP3 EPOL
update                      openEuler 22.03-LTS-SP3 update
  • OS:核心包组(kernel、glibc、systemd 等),必须启用。
  • everything:扩展软件集合(数据库、Web 服务器、开发工具等),建议启用。
  • EPOL(Extra Packages for openEuler):类似 EPEL,社区维护的额外包(如 docker-compose、htop)。
  • update:安全更新和 bugfix,必须启用

配置位置/etc/yum.repos.d/openEuler.repo。强烈建议先备份,然后替换为国内镜像(如华为云、清华源),否则 dnf update 可能会很慢。

四、实战:解决依赖冲突(Python 3 vs Python 2 案例)

场景:你的旧业务脚本依赖 python2-requests,但 openEuler 默认移除了 Python 2 全家桶。

错误信息示例

Error: 
 Problem: package A requires python(abi) = 2.7, but none of the providers can be installed

解决方案

  1. 尝试从 EPOL 或第三方源安装 Python 2(不推荐长期使用):

    dnf install python2 python2-pip
  2. 更佳方案:容器化旧应用。使用 Docker 跑一个 CentOS 7 容器来执行老脚本,保持宿主机干净:

    dnf install docker
    systemctl start docker
    docker run -it --rm centos:7 bash
  3. 若必须安装 RPM 包,使用 dnf download 下载后手动分析依赖:

    dnf download --destdir=/tmp/oldpkgs some-package
    rpm -qpR /tmp/oldpkgs/some-package.rpm   # 查看依赖

核心原则:在 openEuler 上,优先使用 Python 3 重构脚本,而不是强行兼容旧环境。

五、运维锦囊:构建离线 repo 源

生产环境往往无法直连互联网,需要预先准备本地软件源。以下是标准流程:

5.1 在有互联网的机器上同步 openEuler 仓库

使用 reposync(属于 dnf-utils 或单独安装 dnf-plugin-download):

dnf install dnf-utils
mkdir -p /var/local/mirror/openeuler
cd /var/local/mirror/openeuler
reposync --repoid=OS --repoid=everything --repoid=update --download-metadata

同步完成后,目录下会有对应的子目录(OS、everything、update),每个子目录内包含 repodata 元数据。

5.2 提供仓库服务(HTTP 或本地文件)

  • 本地挂载方式:将同步好的目录拷贝到离线服务器的 /var/local/repo,创建本地 repo 文件:

    cat > /etc/yum.repos.d/local.repo << EOF
    [local-OS]
    name=local openEuler OS
    baseurl=file:///var/local/repo/OS
    enabled=1
    gpgcheck=0
    [local-everything]
    name=local everything
    baseurl=file:///var/local/repo/everything
    enabled=1
    gpgcheck=0
    EOF

    然后 dnf clean all &amp;&amp; dnf makecache

  • HTTP 方式(推荐,便于多台机器共享):

    dnf install nginx
    # 将同步目录软链到 nginx 根目录 /usr/share/nginx/html/repo
    systemctl start nginx

    其他机器配置 baseurl=http://your-nginx-ip/repo/OS 即可。

5.3 只制作 ISO 的离线源(快速但不全)

如果你只需要基础包,可直接挂载 openEuler 安装 ISO:

mount -o loop openEuler-22.03-LTS-SP3-x86_64-dvd.iso /mnt/iso
cat > /etc/yum.repos.d/iso.repo << EOF
[iso]
name=iso repo
baseurl=file:///mnt/iso
enabled=1
gpgcheck=0
EOF

但 ISO 内只包含核心包,无法提供 update 更新。

六、RPM 底层操作:查询、验证、提取文件

即使 DNF 再方便,运维也离不开直接操作 RPM 包的场景(例如从崩溃系统中恢复文件)。

操作命令
查询包是否安装rpm -q nginx
查询包安装的文件列表rpm -ql nginx
查询某个文件属于哪个包rpm -qf /etc/nginx/nginx.conf
验证包文件完整性(是否被篡改)rpm -V nginx
提取 RPM 中的某个文件(不安装)`rpm2cpio nginx.rpm

常见场景:你不小心删了 /etc/ssh/sshd_config,可以从 sshd 的 RPM 包中提取:

dnf download openssh-server
rpm2cpio openssh-server*.rpm | cpio -idv ./etc/ssh/sshd_config
cp ./etc/ssh/sshd_config /etc/ssh/

七、清理与系统瘦身

openEuler 默认安装可能包含不用的内核或文档,定期清理可以释放磁盘:

  • 删除旧内核:dnf remove $(rpm -q kernel-core | tail -n +2) (保留当前最新)
  • 删除缓存:dnf clean all
  • 删除没用的依赖:dnf autoremove

八、实验指南

  1. 练习 DNF 历史回滚:故意安装一组软件(如 dnf install httpd mariadb),然后用 dnf history undo 卸载,确认系统恢复。
  2. 构建离线源:使用另一台虚拟机(无互联网)配置本地文件源,成功安装 nginx
  3. 提取文件:手动删除 /bin/ls,然后通过 rpm2cpio 从 coreutils 包中恢复。

九、小结与下期预告

本期我们解决了 openEuler 上包管理的核心问题:从 Yum 到 DNF 的命令迁移、依赖冲突应对、以及离线仓库构建。这些能力足以应对大多数日常软件部署需求。记住:DNF 不是魔法,它只是让你更清晰地看到事务的变化

下期预告:第 3 期《网络与防火墙 —— 别再关掉防火墙了》。我们将深入 NetworkManager 的新玩法、Bonding 配置实战,以及如何用 nftables 替代 iptables 写出高效的防火墙规则。

思考题答案(上期)ifconfig 被弃用是因为它直接读取 /proc/net/dev,且不支持网络命名空间等新特性;现代替代是 ip 命令(ip addrip linkip route),它是 iproute2 包的一部分,更强大且脚本友好。

本期思考:当你执行 dnf upgrade 时,如果升级了内核,重启后旧内核还在吗?如何设置默认启动的内核版本?(答案下期揭晓)

收藏举报
Level 1
0
帖子
0
粉丝
0
获赞