SSD Nodes Learn Hosting plans →
Hướng dẫn Matt ConnorBởi Matt Connor

Bật EPEL và CRB trên Rocky Linux, AlmaLinux

dnf báo “No match for argument”? Tìm package trong BaseOS, AppStream, bật CRB và thêm EPEL an toàn mà không để third-party repo thay package hệ thống.

Vì sao dnf không tìm thấy package bạn cần

EPEL và CRB là 2 repository mà một server Rocky Linux hoặc AlmaLinux mới cài không bật sẵn. Vì vậy, dnf install htop trên một máy mới sẽ trả về No match for argument: htop rồi Error: Unable to find a match: htop. Không có gì bị hỏng và không có mirror nào ngừng hoạt động. Bản distribution cơ sở cố ý chỉ cung cấp một tập package nhỏ. CRB đã có sẵn nhưng đang bị tắt. EPEL là một community repository riêng mà bạn phải thêm vào.

Trên Ubuntu, package tương tự nằm trong universe, còn universe được bật trên gần như mọi cloud image nên vấn đề này hầu như không xuất hiện. Họ Red Hat phân chia package theo cách khác và mặc định cung cấp ít hơn. Cách sửa gồm 3 lệnh. Phần còn lại của hướng dẫn này là điều thường không ai nói trong tuần đầu: các repository đó cam kết cung cấp gì, không cam kết cung cấp gì, và cách ngăn một third-party repository âm thầm thay thế các package của hệ thống cơ sở.

Cách kiểm tra các lệnh này. Các container kiểm thử lệnh của chúng tôi chỉ chạy Ubuntu, nên các lệnh dnf dưới đây chưa được chạy trên máy kiểm thử của chúng tôi. Các lệnh này tuân theo tài liệu Rocky Linux và AlmaLinux. Mỗi bước đều nêu output bạn sẽ thấy. Vì vậy, hãy kiểm tra từng bước trên server của bạn thay vì dán toàn bộ block cùng lúc.

BaseOS, AppStream và CRB là gì?

BaseOS là chính hệ điều hành: kernel, glibc, systemd và userland cốt lõi. Các phiên bản trong kho này được giữ nguyên trong suốt vòng đời của bản major release, còn bản sửa lỗi bảo mật được backport vào những phiên bản đã cố định đó. Một version number trông như đã cũ nhiều năm trong BaseOS không có nghĩa là package chưa được vá. Đó là một phiên bản cũ đã được vá, đúng với mục đích của một enterprise distribution.

AppStream chứa những thành phần bạn chạy bên trên hệ điều hành: web server, database, language runtime, editor và monitoring agent. Trên version 8, phần lớn AppStream được cung cấp dưới dạng module với các stream khác nhau, vì vậy dnf module list rất quan trọng và bạn phải chọn, chẳng hạn, một PHP stream. Version 9 gần như loại bỏ hoàn toàn modularity, nên trên Rocky 9 và Alma 9, bạn thường nhận được một version của mỗi thành phần và không cần enable module trước.

Extras được enable mặc định và rất nhỏ. Kho này chủ yếu chứa các release package cho những repository khác. Đây là nơi epel-release xuất phát. Vì vậy, bạn không bao giờ cần tin cậy một URL ngẫu nhiên để cài EPEL trên Rocky hoặc Alma.

CRB là repository CodeReady Builder, được gọi là PowerTools trên version 8. Kho này chứa phần phục vụ build của distribution: development header, static library, cùng các công cụ test và documentation mà package cần trong lúc build. Repository này đã có trên mirror nhưng bị disable mặc định. Trên sản phẩm riêng của Red Hat, cùng nội dung đó được gọi là CodeReady Linux Builder. Nó đi kèm subscription, nhưng Red Hat nêu rõ rằng nội dung này không được support. Rocky và Alma kế thừa cả nội dung lẫn trạng thái disable mặc định đó.

Với những người chuyển sang từ Debian hoặc Ubuntu: main gộp runtime package và -dev header trong cùng một archive, nên ở đó không có CRB để enable. Thành phần gần tương đương với EPEL là universe. Thành phần này do cộng đồng duy trì và không đi kèm cam kết support từ vendor.

EPEL là gì và ai đứng sau dự án này

EPEL là viết tắt của Extra Packages for Enterprise Linux. Đây là một dự án của Fedora: các package có trong Fedora được build lại cho bản enterprise hiện tại và do EPEL Special Interest Group duy trì. Nhóm này chủ yếu gồm các tình nguyện viên trong cộng đồng Fedora. Red Hat host hạ tầng build và mirror, đồng thời một số kỹ sư Red Hat cũng duy trì package trong đó. Mối liên hệ chỉ dừng ở đó. EPEL không phải là sản phẩm của Red Hat. Không có hợp đồng hỗ trợ và không có SLA (service level agreement) cho package EPEL, dù chạy trên RHEL hay một bản rebuild.

Một policy giúp EPEL an toàn để enable: package EPEL không bao giờ được thay thế package từ bản phân phối base. Nếu AppStream ship nginx thì EPEL sẽ không có package đó. Quy tắc này được những người review package EPEL thực thi, nên đây chỉ là cam kết đối với EPEL. Nó không bảo vệ bạn khỏi bất kỳ thứ gì khác mà bạn thêm vào sau đó.

Cam kết về vòng đời cũng khác với bản phân phối base, và đây là vấn đề thường phát sinh vào năm thứ ba. Version của package BaseOS được giữ nguyên trong toàn bộ vòng đời 10 năm của bản major release. Maintainer của EPEL chỉ cam kết một khoảng thời gian ngắn hơn nhiều: ít nhất một bản RHEL minor release hoặc 13 tháng, tùy mốc nào ngắn hơn. Trên thực tế, hầu hết package được duy trì lâu hơn nhiều so với thời hạn đó. Một số package bị retire khi maintainer không còn tiếp tục duy trì. Một số package chuyển sang major version mới giữa vòng đời distro của bạn vì EPEL đi theo Fedora. Vì vậy, một lần dnf upgrade thông thường có thể cài cho bạn major version mới của một tool EPEL trên máy mà bạn nghĩ là ổn định. Một package mà bạn phụ thuộc cũng có thể ngừng nhận update mà không có thông báo nào đến được với bạn.

Trước khi enable EPEL, bạn cũng cần biết một hệ quả khác: EPEL được build dựa trên bản RHEL minor release mới nhất. Nếu bạn giữ server ở một minor release cũ hơn bằng frozen mirror hoặc repository point release của vendor, package EPEL có thể yêu cầu base library mới hơn bản đang có trên máy. dnf báo lỗi này là dependency bị thiếu. Vì vậy, lỗi trông giống vấn đề của mirror, nhưng thực tế là vấn đề lệch version.

Bật CRB và cài EPEL trên Rocky hoặc Alma

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 --enabled

dnf repolist --enabled hiện phải liệt kê baseos, appstream, extras, crbepel. Bạn cũng có thể thấy một mục epel-cisco-openh264 nhỏ, do epel-release thêm vào. Nếu crb không có trong danh sách đó, bước bật repository chưa có hiệu lực. Phần tiếp theo giải thích nguyên nhân.

Trên Rocky 8 và Alma 8, repository này vẫn có tên là PowerTools, nên lệnh ở giữa sẽ trở thành sudo dnf config-manager --set-enabled powertools. Repository id phân biệt chữ hoa chữ thường. Tài liệu CentOS 8 cũ viết tên này thành PowerTools với chữ hoa, nên sẽ không khớp. Trên AlmaLinux 10, repository CRB được bật mặc định từ 10.0 trở đi (thay đổi vào tháng 9 năm 2025), nên bạn chỉ cần thực hiện bước epel-release.

epel-release đến từ extras, repository này đã được bật sẵn, nên không cần tin cậy URL nào hoặc tự import key. Package này ghi /etc/yum.repos.d/epel.repo và cài signing key của EPEL vào /etc/pki/rpm-gpg/. Xác nhận gpgcheck=1 trong file đó, và bỏ qua mọi hướng dẫn bảo bạn xử lý signature error bằng --nogpgcheck. Signature check thất bại nghĩa là package không đúng như nó tự nhận, hoặc clock của bạn bị sai.

Trên Rocky, epel-release cũng cài một helper nhỏ tại /usr/bin/crb, nên sudo crb enablecrb status thực hiện cùng công việc mà không cần plugin. Kiểm tra xem bạn có helper này không bằng command -v crb trước khi dựa vào nó, vì không phải branch nào của mọi bản rebuild cũng có helper này.

Để xác nhận EPEL có thể truy cập được chứ không chỉ được liệt kê, hãy yêu cầu repository này cung cấp một package chỉ có nó chứa:

dnf repoquery --repo=epel htop

Lệnh này in ra tên package, version và architecture. Không có output nghĩa là repository đã được bật nhưng không trả về gì. Đây thường là vấn đề của mirror hoặc metadata, không phải lỗi cấu hình, nên tiếp theo hãy thử sudo dnf clean all && sudo dnf makecache.

Vì sao dnf báo không có lệnh con: config-manager

Đây là vướng mắc đầu tiên của nhiều người. Lỗi này xảy ra đúng trên các image mà hầu hết nhà cung cấp VPS cấp sẵn.

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 là một plugin, không phải subcommand tích hợp sẵn của dnf. Plugin này nằm trong dnf-plugins-core. Bản cài server đầy đủ sẽ cài gói này, còn các image tối giản, cloud image và container image thì thường không có. Gợi ý của chính dnf hoạt động vì package này khai báo capability ảo đó:

sudo dnf install -y 'dnf-command(config-manager)'

Hãy đặt lệnh trong dấu ngoặc kép. Dấu ngoặc đơn là cú pháp của shell, nên nếu không đặt trong dấu ngoặc kép, lệnh sẽ lỗi cú pháp thay vì báo lỗi dnf.

Nếu không thể cài plugin vì repository bạn cần chính là repository đang bị disable, hãy sửa file trực tiếp. Xác định file chứa section đó, mở file và đặt enabled=1 dưới [crb]:

grep -rl crb /etc/yum.repos.d/

Đó chính xác là nội dung config-manager ghi vào, nên sửa thủ công không làm mất thiết lập nào. dnf repolist --enabled xác nhận kết quả.

Một số package EPEL sẽ không cài được nếu chưa bật CRB

Lỗi phổ biến thứ hai không hề nhắc đến CRB. Một package EPEL liên kết với thư viện chỉ được phát hành trong CRB sẽ fail khi dnf xử lý dependency. Thông báo lỗi sẽ nêu tên thư viện và package cần thư viện đó:

Error:
 Problem: conflicting requests
  - nothing provides libexample.so.0()(64bit) needed by examplepkg-1.4-2.el9.x86_64 from epel

Nguyên nhân là CRB đang bị disable, nên dnf không thấy repository duy nhất cung cấp thư viện đó. Kiểm tra lần lượt 2 điều sau:

dnf repolist --enabled
dnf --enablerepo=crb repoquery --whatprovides 'libexample.so.0()(64bit)'

Nếu command thứ hai nêu tên một package nhưng lệnh install thông thường vẫn fail, CRB đang bị tắt. Loại lỗi này phổ biến đến mức AlmaLinux đã bật CRB mặc định từ version 10 để ngăn lỗi xảy ra. --enablerepo=crb cũng dùng được như một flag dùng một lần cho một lần install, nhưng hãy để CRB được bật vĩnh viễn nếu bạn có sử dụng EPEL, vì lần update EPEL tiếp theo có thể kéo theo dependency mới từ CRB mà không cảnh báo trước.

Gói này đến từ repository nào?

Sau vài tuần bật 4 repository, câu hỏi hữu ích không còn là đã cài gì, mà là các gói đó đến từ đâu.

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 trên một package đã cài sẽ in ra một dòng From repo. dnf list installed hiển thị cùng thông tin trong cột thứ 3, có thêm @ ở phía trước. Vì vậy, @epel nghĩa là package được cài từ EPEL, còn @System nghĩa là dnf không biết package đến từ đâu. Trường hợp này thường xảy ra khi ai đó chạy rpm -i trên một file đã tải xuống. Dòng repoquery cho biết số lượng package theo từng repository. Đây là cách nhanh nhất để phát hiện một server được bàn giao có 40 package từ một repository mà bạn chưa từng nghe đến. Lệnh cuối cùng liệt kê chính xác những gì một repository đã cung cấp. Bạn cần inventory này trước khi quyết định gỡ repository đó.

Thói quen tương đương bên apt là apt-cache policy <package>. Bạn nên mở bảng tương đương lệnh dnf và apt trong tab thứ 2 trong tháng đầu tiên. Các khái niệm tương ứng rõ ràng, ngay cả khi flag không giống nhau.

Làm thế nào để ngăn repo bên thứ ba thay thế package nền tảng?

EPEL cam kết không làm việc này. Không có repository nào khác cam kết như vậy. Repository của vendor cho database, agent hoặc language runtime có thể phát hành bản build riêng của một library mà BaseOS cũng cung cấp. dnf sẽ cài bản đó vì quy tắc mặc định của dnf rất đơn giản: phiên bản cao nhất sẽ được chọn, bất kể package đến từ đâu.

Hai cơ chế kiểm soát xử lý phần lớn trường hợp. Cả hai đều nằm trong file repository tại /etc/yum.repos.d/.

priority= quyết định repository nào được ưu tiên khi có nhiều repository cùng cung cấp một package name. Số thấp hơn được ưu tiên. Giá trị mặc định là 99. Vì vậy, hãy đặt số thấp cho các repository nền tảng và số cao cho repository bên thứ ba. dnf sẽ chọn package nền tảng ngay cả khi phiên bản từ bên thứ ba mới hơn. dnf hiện đại tự xử lý việc này, nên package yum-plugin-priorities riêng của thời CentOS 7 không còn là một phần của giải pháp.

includepkgs= là tùy chọn lọc mạnh hơn. excludepkgs= chặn các package được nêu tên khỏi một repository, nên bạn phải dự đoán repository đó có thể cung cấp những package nào. includepkgs= đảo ngược cách hoạt động này: repository chỉ được cung cấp các package có tên này và không được cung cấp package nào khác. Nếu một repository của vendor chỉ được phép cung cấp agent của chính vendor đó, bạn chỉ cần một dòng.

[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

Trên version 8 còn có một setting cần biết. Một package từ repository bên thứ ba có thể bị ẩn khi một AppStream module cung cấp cùng package name. module_hotfixes=1 trong section của repository đó yêu cầu dnf ngừng lọc package này. Nếu package hiển thị với dnf repoquery nhưng không cài được trên máy chạy version 8, đây thường là nguyên nhân. Version 9 đã loại bỏ gần như toàn bộ module, nên trường hợp này hiếm khi xảy ra ở đó.

Để cố định một package ở một version cụ thể, hãy cài python3-dnf-plugin-versionlock và dùng sudo dnf versionlock add <package>. Đây là cách tương đương với apt-mark hold. Lưu ý một điểm đảo ngược dễ gây nhầm với người chuyển từ Debian: trong apt, Pin-Priority cao hơn được ưu tiên; trong dnf, priority thấp hơn được ưu tiên.

Vì sao trộn các repository gần với RHEL khiến server không thể nâng cấp

Rocky, Alma, CentOS Stream, Oracle Linux và RHEL đủ tương đồng để package của bản này cài được trên bản kia, nhưng cũng đủ khác biệt để kết quả trở thành một hệ thống không ai có thể hỗ trợ.

Cơ chế nằm ở version number. CentOS Stream 9 đi trước RHEL 9, nên nếu trỏ một máy Rocky 9 vào repository của Stream, dù chỉ một lần và chỉ với một package, bạn sẽ có các package với version cao hơn mọi version mà Rocky có thể phát hành. Khi bản Rocky minor tiếp theo xuất hiện, version của package đó thấp hơn version đang có trên máy, nên dnf upgrade sẽ không đụng đến package này. Máy lúc đó chạy một tổ hợp mà không ai kiểm thử, và tình trạng này có thể âm thầm kéo dài nhiều năm trong khi bạn vẫn nghĩ server đã được patch.

Dấu hiệu là dnf upgrade báo không có gì cần làm, còn sudo dnf distro-sync đề xuất downgrade một danh sách dài các package. distro-sync là công cụ sửa lỗi: nó buộc mọi package đã cài khớp với những gì các repository đang enable thực sự cung cấp, bao gồm cả downgrade. Trước hết hãy disable repository bên ngoài, sau đó chạy công cụ và đọc danh sách được đề xuất trước khi chấp nhận. Việc sửa lỗi sẽ thất bại nếu RPM cũ không còn trên mirror. Khi đó, rebuild server từ một image sạch sẽ nhanh và an toàn hơn việc cố xử lý dependency solver.

Các phần còn sót lại của ELevate là biến thể phổ biến khác của vấn đề này. ELevate là công cụ migration của AlmaLinux, xây dựng trên Leapp, dùng để đưa máy CentOS 7 lên bản mới hơn hoặc chuyển đổi giữa các bản rebuild. Một lần migration thực hiện vội có thể để lại các file repository EL7 trong /etc/yum.repos.d/ và các package EL7 vẫn còn được cài. Tìm chúng bằng rpm -qa | grep el7. Mỗi package như vậy là một package mà không repository nào đang enable có thể update, và lần chạy Leapp sau đó sẽ báo chúng là các package không thể ánh xạ. Đây trở thành blocker của quá trình upgrade và bạn phải tự xử lý. Hãy dọn chúng khi server đang ổn định, không phải vào ngày bạn cần thực hiện major upgrade tiếp theo.

Một vendor repository ghi đè package AppStream là phiên bản nhẹ hơn của cùng vấn đề, và dòng includepkgs ở trên là cách xử lý. Container tooling thường gặp trường hợp này nhất, vì containerd.io từ repository riêng của Docker xung đột với runc từ AppStream, nên phải gỡ một trong hai. Hãy quyết định một lần, ghi lại exclusion và tuân theo thứ tự đã được kiểm chứng: hướng dẫn cài đặt Docker trên Rocky Linux nêu rõ cần gỡ các distribution package nào trước.

Bảng đối chiếu apt sang dnf cho các repository

  • /etc/apt/sources.list.d/*.sources trở thành /etc/yum.repos.d/*.repo, trong đó một file có thể chứa nhiều [sections], mỗi mục có một id riêng.
  • add-apt-repository universe trở thành dnf install epel-release. Điểm khác là universe vẫn nằm trong archive riêng của Ubuntu, còn EPEL là một project độc lập.
  • apt update không có thành phần tương đương cần ghi nhớ. dnf tự refresh metadata theo lịch riêng, còn dnf makecache buộc refresh ngay.
  • apt-cache policy <pkg> trở thành dnf info <pkg>, và thêm dnf list --showduplicates <pkg> để xem tất cả version đang có.
  • apt-mark hold trở thành dnf versionlock add, lấy từ python3-dnf-plugin-versionlock.
  • Pinning trong /etc/apt/preferences.d/ trở thành priority= trong phần repository, nhưng các con số chạy theo chiều ngược lại.
  • dpkg -S /path/to/file trở thành rpm -qf /path/to/file.

Automatic updates được chuyển đổi ở mức ý tưởng thay vì cú pháp, vì ở đây không có unattended-upgrades. Timer, config file và việc có reboot hay không được trình bày trong dnf-automatic trên Rocky và Alma.

Rút gọn danh sách repository

Bật CRB, cài epel-release, sau đó ghi lại bạn đã làm gì và vì sao, trong hệ thống quản lý cấu hình hoặc trong một file thường trên máy. Ghi chú này có giá trị hơn bạn nghĩ khi server đã chạy được ba năm và do người khác quản lý.

Hãy tìm kiếm trước khi thêm repository. Chạy dnf search, sau đó chạy dnf info, rồi mới cân nhắc thêm repository mới. Một phần đáng kể các gói mà người dùng bật EPEL để lấy thực ra đã có trong AppStream. Giám sát hệ thống là ví dụ rõ nhất: Performance Co-Pilot có trong các repository mặc định và không cần bất kỳ thành phần bên thứ ba nào. Mỗi repository bổ sung là thêm một bên có thể phát hành package cho bạn vào một ngày bất kỳ, và mỗi repository đều khiến lần major upgrade tiếp theo khó hơn.

Nếu bạn vẫn đang chọn giữa hai distribution này, cách bố trí hoàn toàn giống nhau trên cả hai và epel-release hoạt động giống hệt nhau. Khác biệt thực sự nằm ở nơi khác: bài so sánh Rocky Linux và AlmaLinux trình bày triết lý rebuild, vì AlmaLinux hiện hướng đến khả năng tương thích ABI (application binary interface) thay vì rebuild từng dòng giống hệt.

FAQ

Làm thế nào để bật EPEL trên Rocky Linux 9 hoặc AlmaLinux 9?

Chạy sudo dnf install -y dnf-plugins-core, sau đó chạy sudo dnf config-manager --set-enabled crb, rồi chạy sudo dnf install -y epel-release. Xác nhận bằng dnf repolist --enabled. Lệnh này phải liệt kê baseos, appstream, extras, crbepel. Hãy bật CRB trước khi cài các package EPEL, vì nhiều package trong số đó phụ thuộc vào các library chỉ có trong CRB. Trên version 8, repository id là powertools thay vì crb.

Bật EPEL trên production server có an toàn không?

EPEL được sử dụng rộng rãi và tuân theo chính sách không để các package EPEL thay thế package của bản phân phối cơ sở. Vì vậy, việc bật EPEL không thay đổi nội dung mà BaseOS hoặc AppStream cung cấp. Điểm cần lưu ý là support: EPEL là một project Fedora do cộng đồng tình nguyện duy trì và không có service level agreement. Maintainer có thể chỉ cam kết duy trì một package trong thời gian tương ứng với một minor release của RHEL hoặc 13 tháng. Hãy lập inventory bằng dnf repository-packages epel list installed, và dùng dnf versionlock cho mọi package EPEL mà service hướng đến khách hàng phụ thuộc vào.

Vì sao dnf báo no such command: config-manager?

config-manager là một dnf plugin, không phải command tích hợp sẵn. Các image minimal hoặc container thường được phát hành mà không có dnf-plugins-core. Chính thông báo lỗi đã nêu cách khắc phục: sudo dnf install -y 'dnf-command(config-manager)'. Hãy đặt lệnh trong dấu nháy để shell không đọc các dấu ngoặc đơn. Nếu chưa thể cài thêm gì, hãy chạy grep -rl crb /etc/yum.repos.d/, mở file mà lệnh này chỉ ra, rồi tự đặt enabled=1 trong section [crb].

CRB khác PowerTools như thế nào?

Đây là cùng một repository với hai tên khác nhau. Version 8 gọi repository này là PowerTools với id powertools. Version 9 trở lên gọi là CRB với id crb. Product tương ứng của Red Hat gọi nội dung này là CodeReady Linux Builder. Repository này chứa development header, static library và tooling phục vụ build. Trên Rocky và AlmaLinux 9, repository này bị disable theo mặc định. AlmaLinux 10 bật repository này theo mặc định từ 10.0, vì vậy hãy kiểm tra dnf repolist --enabled trước khi chạy command bật repository.

Làm thế nào để gỡ EPEL mà không gây lỗi?

Trước tiên hãy lập inventory bằng dnf repository-packages epel list installed, vì chỉ gỡ package epel-release không gỡ các package đã cài từ EPEL. Các package đó vẫn nằm trên disk nhưng không còn nguồn cập nhật, nên không tiếp tục nhận security fix. Hệ thống cũng không báo lỗi cho bạn về việc này. Hãy xem xét từng package, gỡ hoặc thay thế những package không còn cần, rồi mới chạy sudo dnf remove epel-release. Nếu một package từ EPEL không thay thế package nào khác và bắt buộc phải gỡ, sudo dnf repository-packages epel remove sẽ xóa toàn bộ set trong một transaction. Hãy đọc kỹ danh sách được đề xuất trước khi xác nhận.

#rocky-linux#almalinux#dnf#epel#repositories