Rocky 與 AlmaLinux 找不到套件:啟用 EPEL、CRB
Rocky Linux 與 AlmaLinux 出現「No match for argument」時,了解 BaseOS、AppStream、CRB 的用途,安全加入 EPEL,並避免第三方軟體庫取代基礎套件。
為什麼 dnf 找不到您要的套件
EPEL 和 CRB 是新安裝的 Rocky Linux 或 AlmaLinux 伺服器不會預先提供的 2 個軟體庫,因此在新主機上執行 dnf install htop 時,會得到 No match for argument: htop,接著得到 Error: Unable to find a match: htop。這不是系統故障,也不是鏡像站台離線。基礎發行版刻意只提供一小部分套件;CRB 雖然已存在,但處於停用狀態,而 EPEL 則是必須另外加入的社群軟體庫。
在 Ubuntu 上,同一個套件位於 universe,而 universe 幾乎在每個雲端映像檔中都已啟用,因此通常不會遇到這個問題。Red Hat 系列採用不同的套件分類方式,預設提供的內容也較少。修正方式只需要 3 個指令。本指南接下來要說明的是一般人在第一週不會得知的部分:這些軟體庫提供哪些內容、不提供哪些內容,以及如何避免第三方軟體庫在未察覺的情況下接管基礎系統。
這些指令的檢查方式。我們用於測試指令的容器僅執行 Ubuntu,因此下方的 dnf 指令並未在我們自己的測試機器上執行。這些指令依據 Rocky Linux 和 AlmaLinux 的文件撰寫。每個步驟都列出您應看到的輸出,因此請在自己的伺服器上逐一檢查,不要一次貼上整個區塊。
什麼是 BaseOS、AppStream 與 CRB?
BaseOS 就是作業系統本身,包括 kernel、glibc、systemd 及核心 userland。這些版本會在整個 major release 生命週期內固定,安全性修正則回移植到這些固定版本中。BaseOS 中看起來已經過時多年的版本號,不代表套件未套用修正,而是已套用修正的舊版本。這正是 enterprise distribution 的設計目的。
AppStream 提供執行於作業系統之上的元件,例如 web server、database、language runtime、editor 及 monitoring agent。在 version 8 中,AppStream 很大一部分以具有 alternate stream 的 module 提供,因此 dnf module list 很重要,你必須選擇例如某個 PHP stream。在 version 9 中,幾乎所有 modularity 都已移除,因此在 Rocky 9 和 Alma 9 上,通常會直接取得某個元件的一個版本,不必先啟用 module。
Extras 預設已啟用,而且內容很少。它主要提供其他 repository 的 release package,而 epel-release 本身就是由這裡提供。正因如此,在 Rocky 或 Alma 上安裝 EPEL 時,完全不需要信任隨機 URL。
CRB 是 CodeReady Builder repository,在 version 8 中稱為 PowerTools。它提供 distribution 的建置內容,包括 development header、static library,以及套件在建置時需要的測試和文件工具。它已存在於 mirror 上,但預設停用。在 Red Hat 自有產品中,相同內容稱為 CodeReady Linux Builder,包含在 subscription 中,且 Red Hat 表示不提供支援。Rocky 和 Alma 同時繼承這些內容及預設停用的設定。
對於從 Debian 或 Ubuntu 轉來的讀者:main 會在同一個 archive 中同時提供 runtime package 和 -dev header,因此不需要在其中啟用 CRB。與 EPEL 最接近的是 universe,它由社群維護,且不包含 vendor support 承諾。
EPEL 是什麼,以及由誰維護
EPEL 代表 Extra Packages for Enterprise Linux。這是 Fedora 專案:將 Fedora 中已有的套件,針對目前的企業版發行版本重新建置,再由 EPEL Special Interest Group 維護;該群組成員主要是 Fedora 社群的志願者。Red Hat 提供建置與鏡像基礎架構,也有部分 Red Hat 工程師負責維護其中的套件。雙方的關係僅止於此。EPEL 不是 Red Hat 產品。 EPEL 套件不論用於 RHEL 或其重建版本,都沒有支援合約,也沒有 SLA(服務等級協議)。
有一項政策讓啟用 EPEL 成為安全的作法:EPEL 套件不得取代基礎發行版本中的套件。如果 AppStream 提供 nginx,EPEL 就不會提供。這項規則由負責審查 EPEL 套件的人員執行,因此只代表 EPEL 本身的承諾。它無法保護你之後加入的其他套件來源。
EPEL 的生命週期承諾也不同於基礎發行版本,這種差異通常會在第三年造成問題。BaseOS 套件版本會在主要版本的十年生命週期內維持凍結。EPEL 維護者承諾的時間短得多:至少維持一個 RHEL 次要版本或 13 個月,以較短者為準。實務上,多數套件的維護時間遠長於此。有些套件會在維護者停止維護後退役;有些套件則會在發行版本的生命週期中途升級至新的主要版本,因為 EPEL 會跟隨 Fedora。因此,一次例行的 dnf upgrade 可能會在你以為穩定的機器上,安裝 EPEL 工具的新主要版本;而你所依賴的套件也可能在沒有任何通知送達你的情況下停止取得更新。新版本也不會套用至已在執行的服務,因此交易完成後,needs-restarting 可告訴你哪些程序仍在使用舊的二進位檔。
啟用 EPEL 前,還有一項值得了解的影響:EPEL 是針對最新的 RHEL 次要版本建置。如果你使用凍結的鏡像或供應商的特定版本儲存庫,讓伺服器停留在較舊的次要版本,EPEL 套件可能會要求比你目前版本更新的基礎函式庫。dnf 會將此回報為缺少相依性,看起來像是鏡像問題,但實際上是版本不一致問題。
啟用 CRB 並在 Rocky 或 Alma 上安裝 EPEL
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --set-enabled crb
sudo dnf install -y epel-release
sudo dnf makecache
dnf repolist --enableddnf repolist --enabled 現在應列出 baseos、appstream、extras、crb 和 epel。你也可能會看到一個小型的 epel-cisco-openh264 項目,這是由 epel-release 加入的。如果清單中缺少 crb,表示啟用步驟未生效,下一節會說明原因。
在 Rocky 8 和 Alma 8 上,該 repository 仍稱為 PowerTools,因此中間的命令會變成 sudo dnf config-manager --set-enabled powertools。Repository ID 區分大小寫。較舊的 CentOS 8 文件會將其寫成帶大寫字母的 PowerTools,這樣不會相符。在 AlmaLinux 10 上,自 10.0 起 CRB repository 預設已啟用(於 2025 年 9 月變更),因此只需執行 epel-release 步驟。
epel-release 來自 extras,而該 repository 已經啟用,因此不需要信任 URL,也不需要手動匯入金鑰。此套件會寫入 /etc/yum.repos.d/epel.repo,並將 EPEL 簽署金鑰安裝至 /etc/pki/rpm-gpg/。確認該檔案中有 gpgcheck=1,並忽略任何建議使用 --nogpgcheck 來規避簽章錯誤的指南。簽章驗證失敗表示套件不是其宣稱的內容,或系統時鐘不正確。
在 Rocky 上,epel-release 也會在 /usr/bin/crb 安裝一個小型輔助工具,因此 sudo crb enable 和 crb status 不使用該 plugin 也能執行相同工作。依賴它之前,先使用 command -v crb 檢查是否已安裝,因為並非每個重建版本分支都包含此工具。
若要確認 EPEL 確實可連線,而不只是已列出,請要求它提供只有該 repository 提供的套件:
dnf repoquery --repo=epel htop此命令會輸出套件名稱、版本和架構。沒有輸出表示 repository 已啟用,但未回傳任何內容。這通常是 mirror 或 metadata 問題,而非設定問題,因此接著嘗試 sudo dnf clean all && sudo dnf makecache。
dnf 顯示找不到 config-manager 指令的原因
這是最常讓人卡住的地方,而且通常發生在 VPS 供應商提供的映像檔上。
No such command: config-manager. Please use /usr/bin/dnf --help
It could be a DNF plugin command, try: "dnf install 'dnf-command(config-manager)'"config-manager 是 plugin,不是內建的 dnf 子命令。它包含在 dnf-plugins-core 中。完整的伺服器安裝會一併安裝該套件,但 minimal image、cloud image 和 container image 通常會省略。dnf 提供的建議之所以有效,是因為該套件宣告了這項虛擬功能:
sudo dnf install -y 'dnf-command(config-manager)'請直接使用該指令。括號是 shell 語法的一部分,因此未加引號的版本會產生語法錯誤,而不是 dnf 錯誤。
如果需要的 repository 正好是停用的 repository,導致你無法安裝這個 plugin,請直接編輯檔案。找出包含該區段的檔案,開啟後在 [crb] 下設定 enabled=1:
grep -rl crb /etc/yum.repos.d/這正是 config-manager 寫入的內容,因此手動設定不會遺漏任何項目。dnf repolist --enabled 可確認結果。
部分 EPEL 套件必須先啟用 CRB 才能安裝
第二個常見陷阱所顯示的錯誤訊息不會提到 CRB。某個 EPEL 套件若相依於僅由 CRB 提供的程式庫,便會在解析相依性時失敗。訊息會列出該程式庫,以及需要它的套件:
Error:
Problem: conflicting requests
- nothing provides libexample.so.0()(64bit) needed by examplepkg-1.4-2.el9.x86_64 from epel原因是 CRB 已停用,因此 dnf 無法找到唯一提供該程式庫的套件庫。請依序檢查以下兩項:
dnf repolist --enabled
dnf --enablerepo=crb repoquery --whatprovides 'libexample.so.0()(64bit)'如果第二個指令列出某個套件,但直接執行安裝仍然失敗,表示 CRB 未啟用。這類錯誤相當常見,因此 AlmaLinux 在版本 10 中特別預設啟用 CRB,以避免發生這個問題。--enablerepo=crb 也可以作為單次安裝的旗標使用;但只要使用 EPEL,就應永久啟用 CRB,因為下一次 EPEL 更新可能在未事先提示的情況下引入新的 CRB 相依性。
這個套件來自哪個 repository?
啟用 4 個 repository 幾週後,真正實用的問題不再是安裝了哪些套件,而是這些套件來自哪裡。
dnf repolist --all
dnf info htop
dnf repoquery --installed --qf '%{from_repo} %{name}' | sort | uniq -c | sort -rn
dnf repository-packages epel list installed對已安裝的套件執行 dnf info 會輸出 From repo 行。dnf list installed 會在第三欄顯示相同資訊,並在前面加上 @。因此,@epel 表示套件是從 EPEL 安裝,@System 表示 dnf 不知道套件來源。這通常代表有人對下載的檔案執行了 rpm -i。repoquery 行會統計各 repository 的套件數量。這是找出繼承而來的伺服器中有 40 個套件來自未知 repository 的最快方式。最後一個指令會精確列出某個 repository 提供的內容。移除該 repository 前,必須先取得這份清單。
這裡對應的 apt 習慣是 apt-cache policy <package>。第一個月建議在第二個分頁開啟dnf 與 apt 指令對照,因為即使旗標不同,兩者的概念仍能直接對應。
如何阻止第三方儲存庫取代基礎套件?
EPEL 承諾不會這麼做。其他儲存庫則沒有這項承諾。資料庫、代理程式或語言執行環境的廠商儲存庫,可能會提供 BaseOS 也有的程式庫版本。dnf 會安裝該版本,因為 dnf 的預設規則很簡單:無論套件來自何處,都以版本最高者為準。
有兩項控制設定最重要,且都位於 /etc/yum.repos.d/ 下的儲存庫檔案中。
priority= 決定多個儲存庫提供相同套件名稱時,哪個儲存庫優先。數值越低,優先順序越高;預設值為 99。因此,請為基礎儲存庫設定較低的數值,為第三方儲存庫設定較高的數值。即使第三方版本較新,dnf 仍會採用基礎套件。現代版本的 dnf 會自行處理這項功能,因此 CentOS 7 時代的獨立 yum-plugin-priorities 套件已不再是解決方案的一部分。
includepkgs= 是較強的篩選選項。excludepkgs= 會阻擋儲存庫提供指定名稱的套件,但這要求你預先推測它可能提供哪些套件。includepkgs= 則反向運作:此儲存庫只能提供指定名稱的套件,其他套件一律不得提供。若某個廠商儲存庫只應提供自有代理程式,只需設定一行即可。
[vendor-tools]
name=Vendor tools for EL9
baseurl=https://packages.example.com/el9/x86_64/
enabled=1
gpgcheck=1
gpgkey=https://packages.example.com/RPM-GPG-KEY-vendor
priority=90
includepkgs=vendor-agent,vendor-agent-plugins在版本 8 中,還有一項設定需要注意。當 AppStream 模組提供相同名稱的套件時,第三方儲存庫的套件可能會被隱藏。該儲存庫區段中的 module_hotfixes=1 會告訴 dnf 停止套用這項篩選。如果套件對 dnf repoquery 可見,但無法在版本 8 的主機上安裝,通常就是這個原因。版本 9 幾乎移除了所有模組,因此這種情況很少出現。
若要將一個套件固定為指定版本,請安裝 python3-dnf-plugin-versionlock,並使用 sudo dnf versionlock add <package>。這相當於 apt-mark hold。請注意一項容易讓 Debian 使用者混淆的差異:apt 會採用較高的 Pin-Priority,dnf 則會採用較低的 priority。
混用 RHEL 衍生版套件庫會讓伺服器無法升級
Rocky、Alma、CentOS Stream、Oracle Linux 與 RHEL 的相容程度足以讓彼此安裝套件,但差異也大到最後會形成無人能支援的系統。它們為何如此接近,以及為何 Stream 尤其位於 RHEL 前方而非與其並列,請參閱Red Hat Linux 如何分裂為 Fedora 與 RHEL,以及 CentOS 後來的發展。
關鍵在於版本號。CentOS Stream 9 的版本進度領先 RHEL 9,因此即使只將 Rocky 9 主機指向 Stream 套件庫一次,甚至只安裝一個套件,也會留下 Rocky 永遠不會發布的較新版本。下一個 Rocky minor release 發布時,該套件的版本反而低於目前版本,因此 dnf upgrade 不會處理它。此時系統執行的是沒有人測試過的組合,卻可能在你以為系統已完成修補的情況下,安靜地維持數年。
常見症狀是 dnf upgrade 顯示沒有可執行的動作,但 sudo dnf distro-sync 建議將一長串套件降級。distro-sync 是修復工具:它會強制所有已安裝套件符合目前啟用的套件庫所提供的版本,也包含降級。先停用外部套件庫,再執行該工具,並在接受前閱讀建議清單。若映像站已不再提供舊版 RPM,修復就會失敗。此時,使用乾淨映像重新建置伺服器,比排解相依性更快也更安全。
ELevate 遺留項目是這個問題的另一種常見形式。ELevate 是 AlmaLinux 基於 Leapp 建置的移轉工具,可用來升級 CentOS 7 主機,或在不同重建版之間轉換。倉促執行的移轉會在 /etc/yum.repos.d/ 留下 EL7 套件庫檔案,並保留已安裝的 EL7 套件。使用 rpm -qa | grep el7 找出這些項目。每個項目都是任何已啟用套件庫都無法更新的套件;之後再次執行 Leapp 時,會將它們列為無法對應的套件,成為必須手動排除的升級阻礙。伺服器狀態穩定時就應清除這些項目,不要等到需要進行下一次 major upgrade 的當天才處理。
Vendor 套件庫遮蔽 AppStream 套件,是同一問題較輕微的形式;上方的 includepkgs 行就是解法。Container tooling 最常遇到這種情況,因為 Docker 自有套件庫中的 containerd.io 會與 AppStream 中的 runc 衝突,因此必須移除其中一個。一次決定使用哪一個,記下排除規則,並依照已驗證的順序操作:Rocky Linux 上的 Docker 安裝指南說明應先移除哪些 distribution packages。
apt 到 dnf 的套件庫對照
/etc/apt/sources.list.d/*.sources對應/etc/yum.repos.d/*.repo;一個檔案可以包含多個[sections],每個都有自己的 id。add-apt-repository universe對應dnf install epel-release,但universe仍位於 Ubuntu 自有的 archive 中,而 EPEL 是獨立的專案。apt update沒有需要記住的對應項目。dnf 會依自己的排程更新中繼資料,而dnf makecache會立即強制更新。apt-cache policy <pkg>對應dnf info <pkg>,另加dnf list --showduplicates <pkg>以查看所有可用版本。apt-mark hold對應dnf versionlock add,來源是python3-dnf-plugin-versionlock。/etc/apt/preferences.d/中的套件鎖定,在套件庫區段中對應為priority=,但數字順序相反。dpkg -S /path/to/file對應rpm -qf /path/to/file。
自動更新是概念上的移植,而不是語法上的移植,因為這裡沒有 unattended-upgrades。計時器、設定檔,以及是否重新開機的問題,請參閱 Rocky 和 Alma 上的 dnf-automatic。
縮短軟體庫清單
啟用 CRB、安裝 epel-release,然後在組態管理系統或主機上的純文字檔中記錄執行內容與原因。當伺服器使用三年、且由其他人接手維護時,這份記錄的價值會超出預期。
新增前先搜尋。執行 dnf search,再執行 dnf info,最後才考慮新增軟體庫。許多人啟用 EPEL 的項目,其實已有不少包含在 AppStream 中。系統監控就是最明顯的例子,因為 Performance Co-Pilot 已包含在基礎軟體庫中,不需要任何第三方來源。每增加一個軟體庫,就多一個可能在星期二提供套件給你的來源,也會讓下一次重大升級更加困難。
如果你仍在兩個發行版之間選擇,這套配置在兩者上都相同,epel-release 的行為也完全一致。真正的差異在其他地方:Rocky Linux 與 AlmaLinux 的比較涵蓋重建理念,因為 AlmaLinux 目前以 ABI(應用程式二進位介面)相容性為目標,而不是逐行重建。
FAQ
如何在 Rocky Linux 9 或 AlmaLinux 9 啟用 EPEL?
先執行 sudo dnf install -y dnf-plugins-core,再執行 sudo dnf config-manager --set-enabled crb,接著執行 sudo dnf install -y epel-release。使用 dnf repolist --enabled 確認結果;輸出應列出 baseos、appstream、extras、crb 和 epel。安裝 EPEL 套件前,先啟用 CRB,因為其中許多套件依賴只有 CRB 提供的函式庫。版本 8 使用的 repository id 是 powertools,不是 crb。
在 production server 上啟用 EPEL 是否安全?
EPEL 已廣泛使用,並遵循 EPEL 套件不取代 base distribution 套件的政策。因此,啟用 EPEL 不會變更 BaseOS 或 AppStream 提供的內容。需要注意的是支援問題:EPEL 是由志願者維護的 Fedora project,不提供 service level agreement;維護者對某個套件的承諾期限可能只有 1 個 RHEL minor release 或 13 個月。使用 dnf repository-packages epel list installed 建立清單,並對任何相依於 EPEL 套件的 customer-facing service 使用 dnf versionlock。
為什麼 dnf 顯示 no such command: config-manager?
因為 config-manager 是 dnf plugin,不是內建命令,而 minimal 或 container image 發行時不含 dnf-plugins-core。訊息本身已指出修正方式:sudo dnf install -y 'dnf-command(config-manager)';請加上引號,避免 shell 將括號解讀為語法。如果目前還不能安裝任何套件,請執行 grep -rl crb /etc/yum.repos.d/,開啟該命令指出的檔案,然後在 [crb] section 中手動設定 enabled=1。
CRB 與 PowerTools 有什麼差異?
它們是同一個 repository 的兩個名稱。版本 8 稱為 PowerTools,id 為 powertools;版本 9 及後續版本稱為 CRB,id 為 crb。Red Hat 自有產品則將這些內容稱為 CodeReady Linux Builder。該 repository 提供 development header、static library 和 build-time tooling,且在 Rocky 及 AlmaLinux 9 上預設停用。AlmaLinux 10 從 10.0 起預設啟用,因此在該版本執行啟用命令前,先檢查 dnf repolist --enabled。
如何再次移除 EPEL 而不造成問題?
先使用 dnf repository-packages epel list installed 建立清單,因為單獨移除 epel-release 套件不會移除從 EPEL 安裝的任何內容。這些套件會繼續留在磁碟上,但失去更新來源,也不再取得安全修正,而且不會顯示任何錯誤。逐一檢查套件,移除或替換不再需要的套件,最後才執行 sudo dnf remove epel-release。如果某個 EPEL 套件沒有取代任何套件,而且確實必須移除,sudo dnf repository-packages epel remove 可在單一 transaction 中清除整組套件;確認前請仔細閱讀預計移除的清單。