Published on

How to Upgrade CentOS Stream 8 to Stream 9

Authors
  • avatar
    Name
    ttyS3
    Twitter

CS9 (CentOS Stream 9) 发布也挺久了.

一直没有升级, 主要是官方一直没有发布升级指南. 这一点 CentOS 比较坑 (当然, RHEL用户是可以从RHEL8 升级 RHEL9的).

reddit 上甚至有 RHEL 的员工回复:

Q: How to upgrade from Stream 8 to Stream 9? A:

rbowen2000 1 yr. ago Red Hat Employee No. There is not currently a way to do an in-place upgrade between C8S and C9S, nor do we expect for there to be one. This is one of the questions that gets asked at each of our CentOS Dojo AMA sessions, and the answer is typically along the lines of "Red Hat Engineering isn't interested in this feature for RHEL, and so it won't be worked on for CentOS. However, if someone from the community works on it, that would be awesome."

Related, the ELevate project - https://almalinux.org/elevate - may be the solution to this problem, but isn't yet. I think that Jack suggested that upgrades between various CentOS Stream versions was a long-term goal.

ref: https://www.reddit.com/r/CentOS/comments/ql5iek/how_to_upgrade_from_stream_8_to_stream_9/

其实这个回复具有很大的误导作用.

CS8 到 CS9 并不是不能升级, 而是, 从企业级的角度来看, 这个升级可能要花费很多时间去校验其可行性和稳定性, 以及各种包的兼容问题处理等.

当然, 对于个人用户来说, 这个升级完全是可行的.

我就一 NAS, 升挂了大不了我重装为 Fedora Server. (嗯,我之前是从 CentOS 8升级到 Stream 8 的, 如果早知道它会搞出 Stream, 我就直接装 Fedora Server了, 至少是发布的稳定版)

升级步骤

以下操作都是在 root 用户下进行的.

  1. 先升级 CS8 到最新版
dnf upgrade --refresh -y
  1. 移除非必要RPM包 (没有被任何其它包依赖的包) 和 orphans 包 (当前的repo中已经不存在了的包)
dnf remove -y $(dnf repoquery --unneeded)

dnf remove -y $(dnf repoquery --extras)

dnf autoremove -y
  1. 清理旧的内核 (可选操作)

我们先看下当前的内核版本(主要是方便翻车后选择从这个旧内核启动):

uname -a
Linux homenas 4.18.0-408.el8.x86_64 #1 SMP Mon Jul 18 17:42:52 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

偷懒的清理方法是, 删除所有内核,然后再安装最新的内核:

rpm -e `rpm -q kernel` --nodeps
rpm -e `rpm -q kernel-devel` --nodeps
rpm -e `rpm -q kernel-core` --nodeps
rpm -e `rpm -q kernel-modules` --nodeps

dnf install -y kernel
  1. 下载 epel9 和 cs9 的 repo rpm 安装文件
mkdir -p /root/upgrade/epel9
cd /root/upgrade/epel9

curl -LO https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
curl -LO https://dl.fedoraproject.org/pub/epel/epel-next-release-latest-9.noarch.rpm

cd ../
# http://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/Packages/ 找到最新的 centos-stream-release 和 centos-stream-repos 包下载回来

curl -LO http://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/Packages/centos-stream-release-9.0-18.el9.noarch.rpm
curl -LO http://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/Packages/centos-stream-repos-9.0-18.el9.noarch.rpm
curl -LO http://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/Packages/centos-gpg-keys-9.0-18.el9.noarch.rpm
  1. 安装 epel9 和 cs9 的 repo rpm

先安装 cs 9 rpm:

dnf install -y *.rpm

再安装 epel9:

cd epel9
dnf install -y *.rpm
  1. 升级到 CS9
dnf -y --releasever=9 --allowerasing --setopt=deltarpm=false distro-sync

这里老灯遇到了个包冲突:

(1116/1116): isl-0.16.1-15.el9.x86_64.rpm                                  16 kB/s | 864 kB     00:53    
----------------------------------------------------------------------------------------------------------
Total                                                                      12 MB/s | 1.2 GB     01:46     
Extra Packages for Enterprise Linux 9 - x86_64                            1.6 MB/s | 1.6 kB     00:00    
Importing GPG key 0x3228467C:
 Userid     : "Fedora (epel9) <[email protected]>"
 Fingerprint: FF8A D134 4597 106E CE81 3B91 8A38 72BF 3228 467C
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-9
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
The downloaded packages were saved in cache until the next successful transaction.
You can remove cached packages by executing 'dnf clean packages'.
Error: Transaction test error:
  file /usr/share/terminfo/r/rxvt-unicode-256color from install of ncurses-base-6.2-8.20210508.el9.noarch conflicts with file from package rxvt-unicode-terminfo-9.26-1.el8.noarch

解决方法是直接 dnf remove rxvt-unicode-terminfo-9.26-1.el8 -y 即可.

然后再重新执行上面的升级语句.

  1. 重建 rpm 数据库

这里需要重建的原因主要是: CS9 的 rpm 数据库格式从 bdb_ro 变成了 sqlite

ref https://fedoraproject.org/wiki/Changes/Sqlite_Rpmdb

rpmdb --rebuilddb
  1. 清理 dnf 缓存 (可选操作)
dnf clean packages

subscription-manager 这个包一般人也用不到订阅, 可以卸载: dnf remove -y subscription-manager

  1. 再升级一次
dnf upgrade --refresh -y
  1. 确保核心包已安装
dnf -y groupupdate "Core" "Minimal Install"
  1. 检查内核和 sshd 是否安装成功
检查默认启动内核:

❯ grubby --default-kernel
/boot/vmlinuz-5.14.0-183.el9.x86_64

检查内核和 sshd 是否安装成功

❯ dnf list --installed | rg ssh
libssh.x86_64                               0.10.4-3.el9                          @baseos                                        
libssh-config.noarch                        0.10.4-3.el9                          @baseos                                        
openssh.x86_64                              8.7p1-24.el9                          @baseos                                        
openssh-clients.x86_64                      8.7p1-24.el9                          @baseos                                        
openssh-server.x86_64                       8.7p1-24.el9                          @baseos      

❯ dnf list --installed | rg kernel
kernel.x86_64                               4.18.0-408.el8                        @baseos                                        
kernel.x86_64                               5.14.0-183.el9                        @baseos                                        
kernel-core.x86_64                          4.18.0-408.el8                        @baseos                                        
kernel-core.x86_64                          5.14.0-183.el9                        @baseos                                        
kernel-devel.x86_64                         4.18.0-408.el8                        @baseos                                        
kernel-devel.x86_64                         5.14.0-183.el9                        @appstream                                     
kernel-devel-matched.x86_64                 5.14.0-183.el9                        @appstream                                     
kernel-headers.x86_64                       5.14.0-183.el9                        @appstream                                     
kernel-modules.x86_64                       4.18.0-408.el8                        @baseos                                        
kernel-modules.x86_64                       5.14.0-183.el9                        @baseos                                        
kernel-srpm-macros.noarch                   1.0-11.el9                            @appstream                                     
kernel-tools.x86_64                         5.14.0-183.el9                        @baseos                                        
kernel-tools-libs.x86_64                    5.14.0-183.el9                        @baseos      
  1. 重启

重启比较快, 整个升级还算是比较成功的.

检查当前的版本是不是已经升级到 CS9 了:

cat /etc/os-release
NAME="CentOS Stream"
VERSION="9"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="9"
PLATFORM_ID="platform:el9"
PRETTY_NAME="CentOS Stream 9"
ANSI_COLOR="0;31"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:centos:centos:9"
HOME_URL="https://centos.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux 9"
REDHAT_SUPPORT_PRODUCT_VERSION="CentOS Stream"

检查内核版本:

uname -a
Linux homenas 5.14.0-183.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Mon Oct 31 09:18:51 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

其它清理

确认启动工作正常后, 可以把旧的内核删除了.

rpm -q kernel-core
kernel-core-4.18.0-408.el8.x86_64
kernel-core-5.14.0-183.el9.x86_64
dnf remove -y kernel-core-4.18.0-408.el8

列出当前还在的安装自 CentOS Stream 8 的包:

❯ dnf list --installed|grep el8
bind-export-libs.x86_64                     32:9.11.36-5.el8                      @baseos                                        
bpytop.noarch                               1:1.0.54-3.el8                        @epel                                          
cgdcbxd.x86_64                              1.0.2-9.el8                           @AppStream                                     
cri-o.x86_64                                1.22.5-2.2.el8                        @devel_kubic_libcontainers_stable_cri-o_1.22   
iptstate.x86_64                             2.2.6-6.el8                           @anaconda                                      
iwl6000-firmware.noarch                     9.221.4.1-110.el8.1                   @baseos                                        
javapackages-filesystem.noarch              5.3.0-1.module_el8.0.0+11+5b8c10bd    @AppStream                                     
kernel-devel.x86_64                         4.18.0-408.el8                        @baseos                                        
libXxf86misc.x86_64                         1.0.4-1.el8                           @AppStream                                     
libatomic_ops.x86_64                        7.6.2-3.el8                           @AppStream                                     
libcgroup.x86_64                            0.41-19.el8                           @anaconda                                      
libcroco.x86_64                             0.6.12-4.el8_2.1                      @anaconda                                      
libertas-usb8388-firmware.noarch            2:20220726-110.git150864a4.el8        @baseos                                        
libmcpp.x86_64                              2.7.2-20.el8                          @AppStream                                     
libmodman.x86_64                            2.0.1-17.el8                          @anaconda                                      
man-pages-overrides.noarch                  8.6.0.0-1.el8                         @appstream                                     
mcpp.x86_64                                 2.7.2-20.el8                          @AppStream                                     
mozjs60.x86_64                              60.9.0-4.el8                          @anaconda                                      
openwsman-client.x86_64                     2.6.5-9.el8                           @appstream                                     
python38-pip-wheel.noarch                   19.3.1-6.module_el8.7.0+1184+30eba247 @appstream                                     
python38-setuptools-wheel.noarch            41.6.0-5.module_el8.6.0+929+89303463  @appstream                                     
shim-x64.x86_64                             15-15.el8_2                           @anaconda                                      
terminus-fonts-console.noarch               4.48-1.el8                            @epel                                          
wireguard-dkms.noarch                       1:1.0.20220627-1.el8                  @copr:copr.fedorainfracloud.org:jdoss:wireguard
xorg-x11-font-utils.x86_64                  1:7.5-41.el8                          @appstream      

注意, 这里有些包不能直接 dnf remove 卸载, 比如:

❯ dnf info kernel-devel
Last metadata expiration check: 1:58:17 ago on Tue 08 Nov 2022 01:35:37 AM CST.
Installed Packages
Name         : kernel-devel
Version      : 4.18.0
Release      : 408.el8
Architecture : x86_64
Size         : 52 M
Source       : kernel-4.18.0-408.el8.src.rpm
Repository   : @System
From repo    : baseos
Summary      : Development package for building kernel modules to match the kernel
URL          : http://www.kernel.org/
License      : GPLv2 and Redistributable, no modification permitted
Description  : This package provides kernel headers and makefiles sufficient to build modules
             : against the kernel package.

Name         : kernel-devel
Version      : 5.14.0
Release      : 183.el9
Architecture : x86_64
Size         : 61 M
Source       : kernel-5.14.0-183.el9.src.rpm
Repository   : @System
From repo    : appstream
Summary      : Development package for building kernel modules to match the kernel
URL          : https://www.kernel.org/
License      : GPLv2 and Redistributable, no modification permitted
Description  : This package provides kernel headers and makefiles sufficient to build modules
             : against the kernel package.

我们不是要卸载 kernel-devel, 而是只要卸载 kernel-devel-4.18.0-408.el8:

dnf remove kernel-devel-4.18.0-408.el8

terminus-fonts-console 不要卸载, epel9 里面没有了. 这个只是个字体包, 不影响系统.

https://packages.fedoraproject.org/pkgs/terminus-fonts/terminus-fonts-console/epel-8.html

不过没关系, 卸载了也可以安装回来:

dnf install -y https://download-ib01.fedoraproject.org/pub/epel/8/Everything/x86_64/Packages/t/terminus-fonts-console-4.48-1.el8.noarch.rpm

其它

升级过程中会有一些警告信息, 目前看来没有什么影响.

信息1:

/usr/sbin/ldconfig: /lib64/ld-linux-x86-64.so.2 is not a symbolic link

/sbin/ldconfig: /lib64/ld-linux-x86-64.so.2 is not a symbolic link

/sbin/ldconfig: /lib64/libslapi-2.4.so.2 is not a symbolic link

/sbin/ldconfig: /lib64/libldap_r-2.4.so.2 is not a symbolic link

/sbin/ldconfig: /lib64/libldap-2.4.so.2 is not a symbolic link

/sbin/ldconfig: /lib64/liblber-2.4.so.2 is not a symbolic link

/sbin/ldconfig: /lib64/ld-linux-x86-64.so.2 is not a symbolic link

信息2:

failed to link /usr/bin/python3 -> /etc/alternatives/python3: /usr/bin/python3 exists and it is either not a symlink or --keep-foreign was set and link points outside /etc/alternatives
failed to link /usr/bin/pip-3 -> /etc/alternatives/pip-3: /usr/bin/pip-3 exists and it is either not a symlink or --keep-foreign was set and link points outside /etc/alternatives
failed to link /usr/bin/pip3 -> /etc/alternatives/pip3: /usr/bin/pip3 exists and it is either not a symlink or --keep-foreign was set and link points outside /etc/alternatives
failed to link /usr/bin/pydoc3 -> /etc/alternatives/pydoc3: /usr/bin/pydoc3 exists and it is either not a symlink or --keep-foreign was set and link points outside /etc/alternatives
failed to link /usr/bin/python3-config -> /etc/alternatives/python3-config: /usr/bin/python3-config exists and it is either not a symlink or --keep-foreign was set and link points outside /etc/alternatives
failed to link /usr/share/man/man1/python3.1.gz -> /etc/alternatives/python3-man: /usr/share/man/man1/python3.1.gz exists and it is either not a symlink or --keep-foreign was set and link points outside /etc/alternatives

另外还有一些配置升级的信息:

只要软件没有破坏性变更, 这些配置不 migration 一般也没事.

warning: /etc/nsswitch.conf created as /etc/nsswitch.conf.rpmnew

warning: /etc/systemd/system.conf created as /etc/systemd/system.conf.rpmnew

warning: /etc/samba/smb.conf created as /etc/samba/smb.conf.rpmnew

warning: /etc/systemd/resolved.conf created as /etc/systemd/resolved.conf.rpmnew

warning: /etc/containers/registries.conf created as /etc/containers/registries.conf.rpmnew

warning: /etc/chrony.conf created as /etc/chrony.conf.rpmnew

/etc/yum.repos.d 残余的 cs8 repo 文件问题: 其实我是在升级之前备份, 然后手动删除了这些 xxx.repo 文件的, 但是升级完后会有这些警告信息.

❯ dnf module list       
Last metadata expiration check: 0:10:14 ago on Tue 08 Nov 2022 12:58:15 AM CST.
Modular dependency problems:

 Problem 1: conflicting requests
  - nothing provides module(platform:el8) needed by module nodejs:14:8070020220601142310:3b9f49c4.x86_64
 Problem 2: conflicting requests
  - nothing provides module(platform:el8) needed by module perl-DBD-SQLite:1.58:8030020200716174729:3a70019f.x86_64
  - nothing provides module(perl:5.26) needed by module perl-DBD-SQLite:1.58:8030020200716174729:3a70019f.x86_64
 Problem 3: conflicting requests
  - nothing provides module(platform:el8) needed by module perl-DBI:1.641:8030020200716150652:1e4bbb35.x86_64
  - nothing provides module(perl:5.26) needed by module perl-DBI:1.641:8030020200716150652:1e4bbb35.x86_64
 Problem 4: conflicting requests
  - nothing provides module(platform:el8) needed by module perl-IO-Socket-SSL:2.066:8040020200924212038:1aedcbfe.x86_64
  - nothing provides module(perl:5.26) needed by module perl-IO-Socket-SSL:2.066:8040020200924212038:1aedcbfe.x86_64
 Problem 5: conflicting requests
  - nothing provides module(platform:el8) needed by module perl-libwww-perl:6.34:8040020211102170116:bf75fe78.x86_64
  - nothing provides module(perl:5.26) needed by module perl-libwww-perl:6.34:8040020211102170116:bf75fe78.x86_64
 Problem 6: conflicting requests
  - nothing provides module(platform:el8) needed by module python36:3.6:8050020210825152031:982725ab.x86_64
 Problem 7: conflicting requests
  - nothing provides module(platform:el8) needed by module python38:3.8:8070020220920211024:bd194b04.x86_64
 Problem 8: conflicting requests
  - nothing provides module(platform:el8) needed by module virt:rhel:8070020220921151759:3b9f49c4.x86_64

解决办法:

dnf module reset nodejs perl-DBD-SQLite perl-DBI perl-IO-Socket-SSL perl-libwww-perl python36 python38 virt

然后再执行 dnf module list 就没有问题了:

❯ dnf module list                 
Last metadata expiration check: 0:10:51 ago on Tue 08 Nov 2022 12:58:15 AM CST.
@modulefailsafe
Name                                                  Stream                                      Profiles                                                               Summary     
javapackages-runtime                                  201801 [e]                                  common                                                                 Basic runtime utilities to support Java applications                                   

CentOS Stream 9 - AppStream
Name                                                  Stream                                      Profiles                                                               Summary     
maven                                                 3.8                                         common [d]                                                             Java project management and project comprehension tool                                 
nodejs                                                18                                          common [d], development, minimal, s2i                                  Javascript runtime                                                                     
php                                                   8.1                                         common [d], devel, minimal                                             PHP scripting language                                                                 
ruby                                                  3.1                                         common [d]                                                             An interpreter of object-oriented scripting language                                   

Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled

可以看到 CS9 的 module 比 CS8 少很多.

Refs

主要参考 https://ahelpme.com/linux/centos-stream-9/how-to-upgrade-to-centos-stream-9-from-centos-stream-8/

https://github.com/Ink-33/OhMyStream9