指南)
凌晨一點值班手機響了。業(yè)務(wù)那邊反饋所有新環(huán)境初始化失敗我登錄一臺故障機執(zhí)行yum update日志干凈利落地甩出一行紅字Could not resolve host: mirrorlist.centos.org??吹竭@行報錯我心里基本有數(shù)了這多半不是網(wǎng)絡(luò)抽風而是 CentOS 7 的 yum 源進了生命周期終止后的“失聯(lián)區(qū)”。CentOS 7 在 2024 年 6 月 30 日停止維護官方維護計劃早就公布過。但 CentOS 7 至今仍是存量最大的 Linux 發(fā)行版之一大量線上業(yè)務(wù)、離線機房、老構(gòu)建機都還在用它。官方源退役后默認請求的mirrorlist.centos.org和mirror.centos.org/centos/7/路徑會逐步不可用表現(xiàn)就是 yum install 報錯、yum update 失敗、依賴解析直接崩潰。更麻煩的是這類報錯不只有一種長相有時是 DNS 解析失敗有時是 404有時干脆卡在 mirrorlist 測速上。排查不仔細很容易繞彎子。這篇文章把我實際處理這個問題的完整過程寫出來包含報錯類型辨別、排查順序、Base 源和 EPEL 源的配置修改、緩存清理以及幾個特別容易踩的坑。如果你正被 CentOS 7 的 yum 源問題折磨或者想提前儲備這個運維操作場景的處理方案直接照做即可。1. 報錯現(xiàn)場CentOS 7 源失效的幾種典型長相1.1 最容易遇到的幾類報錯先說結(jié)論CentOS 7 源失效不會只有一種表現(xiàn)形式。我實際處理過的服務(wù)器里最常見的是下面這三種。第一種DNS 解析類型Could not retrieve mirrorlist http://mirrorlist.centos.org/?release7archx86_64repoosinfracontainer error was 14: curl#6 - Could not resolve host: mirrorlist.centos.org第二種倉庫校驗失敗類型One of the configured repositories failed (CentOS-7 - Base), and yum will now exit第三種元數(shù)據(jù) 404 類型http://mirror.centos.org/centos/7/os/x86_64/repodata/repomd.xml: [Errno 14] HTTP Error 404 - Not Found這三種表面癥狀差異很大。第一種看起來像 DNS 沒配好第二種像是倉庫配置損壞第三種像文件路徑寫錯。但它們的根因是同一件事CentOS 7 進入生命周期終止EOL狀態(tài)后官方倉庫維護重點已經(jīng)轉(zhuǎn)移到歸檔目錄老倉庫不再生成新的repomd.xml部分 URL 直接返回 404部分mirrorlist接口干脆不再對版本 7 返回可用鏡像列表。也就是說不是你的網(wǎng)絡(luò)壞了而是遠端真的“沒有這個東西了”。1.2 為什么 CentOS 7 的源會集體消失CentOS 7 的完整版本是 7.9.2009這也是該系列最后一個正式版本。任何軟件發(fā)行版只要停止維護官方通常會把歷史倉庫從“主下載目錄”挪到“歸檔目錄”避免占用主目錄的空間也避免用戶繼續(xù)收到已不維護的包。CentOS 項目的歸檔位置就是vault.centos.org。對 yum 源來說默認情況下 CentOS 7 的 Base、Updates、Extras 三個倉庫會去請求mirrorlist.centos.org/?release7archx86_64repoosmirror.centos.org/centos/7/os/x86_64/repodata/repomd.xml一旦官方把主目錄里的centos/7/內(nèi)容移走這兩個地址就變成無效狀態(tài)。鏡像列表返回不了可用鏡像主目錄返回 404yum 自然拉不到任何倉庫元數(shù)據(jù)。需要注意EPEL 源Extra Packages for Enterprise Linux也存在類似問題。EPEL 7 同樣停止維護默認的download.fedoraproject.org/pub/epel/7/路徑也會失效需要切到歸檔路徑archives.fedoraproject.org/pub/archive/epel/7/。2. 動手前的排查先分清楚是真的源失效還是本地網(wǎng)絡(luò)故障2.1 三步定位問題改配置之前我建議先花幾分鐘做一遍快速定位避免把網(wǎng)絡(luò)問題錯怪到源頭上。第一步用yum repolist看具體是哪個倉庫報錯。報錯信息里通常寫了倉庫名比如 CentOS-7 - Base、CentOS-7 - Updates或者 EPEL。記住這個名字后面要定向處理。第二步手動用 curl 測試關(guān)鍵 URL。如果報錯里帶著 mirrorlist 地址就測 mirrorlist如果帶著具體 repodata 路徑就測 repodata。curl -I --connect-timeout 5 http://mirrorlist.centos.org/?release7archx86_64repoos curl -I --connect-timeout 5 http://mirror.centos.org/centos/7/os/x86_64/repodata/repomd.xml如果 curl 返回 200 或 302說明網(wǎng)絡(luò)和域名解析都沒問題問題在別的倉庫或配置細節(jié)。如果 curl 返回 404可以基本確認是遠端歸檔問題。如果 curl 報Could not resolve host先查 DNScat /etc/resolv.conf再用ping或者dig試幾個常見域名。如果 curl 超時檢查出網(wǎng)防火墻和代理配置。公司內(nèi)網(wǎng)環(huán)境經(jīng)常有代理限制yum 默認不走代理需要在/etc/yum.conf里顯式配置proxy。第三步把/etc/yum.repos.d/目錄里的.repo文件全部列出來確認系統(tǒng)里除了默認源之外還有沒有第三方源。很多服務(wù)器會殘留各種第三方軟件源它們?nèi)绻仓赶?CentOS 7 時代的老地址一樣會報錯。2.2 備份配置文件修改任何系統(tǒng)配置文件前備份是底線操作。yum 源配置文件雖然改動量不大但一旦替換出錯連恢復(fù)現(xiàn)場都很麻煩。mkdir -p /root/yum-repo-backup/$(date %F) cp -r /etc/yum.repos.d/* /root/yum-repo-backup/$(date %F)/如果后續(xù)改動出問題直接把這個目錄里的文件拷回去就能恢復(fù)。另外我習慣順手記錄一下當前系統(tǒng)版本和架構(gòu)cat /etc/redhat-release uname -mCentOS 7 的最終版本號是 7.9.2009架構(gòu)一般是x86_64這兩個信息在下一步配置里會用到。若服務(wù)器是aarch64等 ARM 架構(gòu)路徑中的架構(gòu)參數(shù)要對應(yīng)替換。3. 核心修復(fù)把 yum 源切換到歸檔源3.1 修改 CentOS-Base.repoCentOS 7 的默認源配置位于/etc/yum.repos.d/CentOS-Base.repo。修復(fù)原則其實很簡單把失效的mirrorlist和mirror.centos.org地址全部替換成vault.centos.org/7.9.2009/下的對應(yīng)路徑。最穩(wěn)妥的方式是手工編輯逐段替換。下面是我實際用過的配置片段[base] nameCentOS-$releasever - Base baseurlhttp://vault.centos.org/7.9.2009/os/$basearch/ gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 [updates] nameCentOS-$releasever - Updates baseurlhttp://vault.centos.org/7.9.2009/updates/$basearch/ gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 [extras] nameCentOS-$releasever - Extras baseurlhttp://vault.centos.org/7.9.2009/extras/$basearch/ gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7注意這里有三個關(guān)鍵點。第一mirrorlist行必須注釋掉或者刪除。否則即使你寫了正確的baseurlyum 有時仍會去請求 mirrorlist 接口輕則多繞一段請求重則直接報錯。第二路徑里的7.9.2009是 CentOS 7 的最終版本號。不要寫成7。vault.centos.org/7/不一定穩(wěn)定官方歸檔目錄按完整版本號組織7.9.2009才是準確的歸檔目錄名。第三$basearch變量可以保留yum 會自動替換成x86_64或aarch64。$releasever在 CentOS 7 上通常等于7但我建議直接寫死完整版本號減少變量解析帶來的不確定性。如果你不想手工編輯也可以用 sed 快速替換。默認的 CentOS-Base.repo 里baseurl是注釋狀態(tài)mirrorlist是啟用狀態(tài)處理方式就是取反再換地址sed -i s|^mirrorlist|#mirrorlist|g /etc/yum.repos.d/CentOS-Base.repo sed -i s|^#baseurl|baseurl|g /etc/yum.repos.d/CentOS-Base.repo sed -i s|http://mirror.centos.org/centos/$releasever|http://vault.centos.org/7.9.2009|g /etc/yum.repos.d/CentOS-Base.repo這套命令在絕大多數(shù)默認配置的 CentOS 7 系統(tǒng)上可以直接復(fù)用。第三行的目的是把文件里的變量形式地址替換成固定的歸檔地址注意單引號防止 shell 展開。3.2 處理 EPEL 源EPEL 是 CentOS 7 里最常用的第三方軟件源很多額外包都依賴它。如果系統(tǒng)里裝了epel-release/etc/yum.repos.d/epel.repo同樣需要改。先確認一下rpm -qa | grep epel-release有輸出就說明 EPEL 源存在。編輯/etc/yum.repos.d/epel.repo把mirrorlist注釋掉baseurl改成歸檔地址[epel] nameExtra Packages for Enterprise Linux $releasever - $basearch baseurlhttps://archives.fedoraproject.org/pub/archive/epel/7/$basearch enabled1 gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7如果你用了 epel-testing同樣處理[epel-testing] nameExtra Packages for Enterprise Linux $releasever - Testing - $basearch baseurlhttps://archives.fedoraproject.org/pub/archive/epel/7/testing/$basearch enabled0 gpgcheck1 gpgkeyfile:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7這里有個特殊情況。如果系統(tǒng)里根本沒有安裝epel-release卻需要使用 EPEL 中的軟件包那就先別急著裝包。因為老版本的epel-releaserpm 文件自帶的倉庫配置也會指向失效地址。正確做法是先到 EPEL 歸檔目錄下載與 CentOS 7 匹配的epel-releaserpm然后用rpm -ivh安裝裝完再按上面的方式修改倉庫文件。3.3 清理緩存并驗證修復(fù)結(jié)果源配置改完后第一件事不是直接 yum install而是清理緩存和重建元數(shù)據(jù)。原因很簡單本地/var/cache/yum里可能還殘留著舊的倉庫元數(shù)據(jù)它會把 yum 引導(dǎo)到老地址上導(dǎo)致改了半天仍然報錯。yum clean all yum makecacheyum clean all會清掉所有倉庫的元數(shù)據(jù)緩存和臨時文件。yum makecache會按當前配置文件重新拉取所有啟用倉庫的repomd.xml這一步如果順利執(zhí)行說明源配置已經(jīng)生效。接下來跑一遍yum repolist確認倉庫數(shù)量正常yum repolist輸出里應(yīng)該能看到base、updates、extras和epel等倉庫狀態(tài)正常。最后做個實際測試yum -y update這里注意CentOS 7 已經(jīng) EOL別指望還能拉到大量更新但命令執(zhí)行過程不報 404、不報Could not resolve host就說明 yum 源本身已經(jīng)恢復(fù)可用。如果只想裝某個軟件也可以直接yum -y install package驗證。4. 實操中的坑這些情況我全遇到過4.1 DNS 正常但依舊報錯元兇可能是 fastestmirror有一次我處理一臺服務(wù)器curl 測試 mirrorlist 地址完全正常但 yum 就是慢吞吞地報錯。排查到最后發(fā)現(xiàn)是fastestmirror插件在搗亂。fastestmirror插件會在 yum 執(zhí)行時自動測試多個鏡像的速度優(yōu)先選擇最快的一個。當配置文件里的mirrorlist還指向失效地址時插件會反復(fù)做無效請求結(jié)果就是長時間等待最終報錯或回退失敗。解決辦法有兩個。一是改配置時堅持把mirrorlist注釋掉從根上避免插件去請求它。二是直接禁用插件sed -i s/enabled1/enabled0/ /etc/yum/pluginconf.d/fastestmirror.conf或者修改/etc/yum.conf把默認啟用插件的開關(guān)關(guān)掉plugins0我個人的習慣是在 EOL 系統(tǒng)上直接禁用 fastestmirror。反正所有倉庫都指向固定歸檔地址了測速已經(jīng)沒有意義反而多一層故障隱患。4.2 GPG 簽名校驗報錯別急著關(guān) gpgcheck切換到 vault 源后有時會遇到公鑰缺失或簽名校驗失敗的報錯Public key for xxx.rpm is not installed這種情況多發(fā)生在長期未更新的機器上系統(tǒng)缺少 CentOS 7 的 GPG 公鑰。不要條件反射式地把gpgcheck1改成gpgcheck0這是把安全底線降級了。正確的是導(dǎo)入對應(yīng)的公鑰文件rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7如果公鑰文件本身丟失可以重新安裝對應(yīng)密鑰包centos-release或epel-release或者從歸檔源下載公鑰再導(dǎo)入。4.3 clean all 之后 makecache 卡死有臺機器執(zhí)行yum makecache時卡在“determining fastest mirrors”這一步二十分鐘沒動。這不是網(wǎng)絡(luò)問題是插件逐個測試鏡像站點超時。按 4.1 的方式關(guān)掉 fastestmirror 之后makecache 十幾秒就完成了。所以如果你用的還是默認配置文件我建議先禁用插件再執(zhí)行清理緩存。另外還有一種情況倉庫配置里baseurl寫成了https://但服務(wù)器時間不準SSL 握手報證書錯誤。CentOS 7 的老機器時間同步服務(wù)經(jīng)常失靈如果 makecache 報證書或校驗錯誤先date看下系統(tǒng)時間再用ntpdate或 chrony 同步一遍。4.4 內(nèi)網(wǎng)離線機連 vault 都訪問不了外網(wǎng)可達的機器按第 3 章操作就能修復(fù)。但很多內(nèi)網(wǎng)服務(wù)器只開放了特定端口根本訪問不到vault.centos.org。這種情況下最實用的方案是做一個本地 yum 源。最簡單的做法是用 CentOS 7 的 ISO 鏡像做本地源。把 ISO 上傳到服務(wù)器然后掛載mkdir -p /mnt/cdrom mount -o loop /opt/CentOS-7-x86_64-DVD-2009.iso /mnt/cdrom新建一個本地源配置文件例如/etc/yum.repos.d/local.repo[localiso] nameCentOS 7 Local ISO baseurlfile:///mnt/cdrom/ enabled1 gpgcheck0然后把所有原來失效的源文件移走mkdir -p /etc/yum.repos.d/disabled mv /etc/yum.repos.d/CentOS-*.repo /etc/yum.repos.d/disabled/ mv /etc/yum.repos.d/epel*.repo /etc/yum.repos.d/disabled/最后執(zhí)行yum clean all yum makecache。ISO 源雖然軟件包版本是固定的但作為應(yīng)急安裝基礎(chǔ)依賴已經(jīng)完全夠用。需要注意gpgcheck0只適合這種離線臨時環(huán)境不要用到生產(chǎn)環(huán)境常規(guī)源上。如果內(nèi)網(wǎng)有專門的軟件倉庫服務(wù)器那就用一臺有外網(wǎng)的機器通過reposync把歸檔倉庫同步下來再用createrepo生成元數(shù)據(jù)。注意reposync和createrepo分別屬于yum-utils和createrepo包在源失效前就要提前安裝準備。4.5 容器里跑的 CentOS 7 同樣要改Docker 容器里使用 CentOS 7 鏡像源失效問題一樣會爆。我曾經(jīng)遇到一個構(gòu)建環(huán)境容器內(nèi)執(zhí)行 yum install 時報同樣錯誤。由于容器鏡像大多是精簡版可能沒有 vim 和 curl直接用 sed 處理更省事sed -i s|^mirrorlist|#mirrorlist|g /etc/yum.repos.d/CentOS-Base.repo sed -i s|^#baseurl|baseurl|g /etc/yum.repos.d/CentOS-Base.repo sed -i s|http://mirror.centos.org/centos/$releasever|http://vault.centos.org/7.9.2009|g /etc/yum.repos.d/CentOS-Base.repo yum clean all yum makecache如果容器里連 sed 都沒有那就換基礎(chǔ)鏡像吧這個系統(tǒng)太精簡了后面維護也會很痛苦。5. 源修復(fù)只是應(yīng)急CentOS 7 之后的長期打算5.1 修復(fù)完源系統(tǒng)依然處于“裸奔”狀態(tài)yum 源修復(fù)可以讓系統(tǒng)繼續(xù)安裝軟件、繼續(xù)做依賴解析但這里必須把話說清楚 CentOS 7 已經(jīng)停止維護后續(xù)不會再有任何官方安全更新。修復(fù)源只是讓這臺機器“能繼續(xù)工作”并不代表它“安全”。線上業(yè)務(wù)如果還跑在 CentOS 7 上等于一直暴露在沒有安全補丁的狀態(tài)下。我的處理原則是能用修復(fù)方案穩(wěn)住現(xiàn)有環(huán)境但同時在項目計劃里給遷移安排一個明確的優(yōu)先級。遷移的時間窗口越長后續(xù)面臨的風險就越高。至少需要梳理清楚下面幾件事當前所有運行在 CentOS 7 上的服務(wù)清單和依賴關(guān)系各業(yè)務(wù)的數(shù)據(jù)備份方案和備份驗證結(jié)果配置文件的版本管理盡量把手工改動的配置收進代碼倉庫可回滾的遷移方案比如提前準備系統(tǒng)鏡像快照或整機備份5.2 三條遷移路線的取舍參考從實際運維角度看CentOS 7 遷移主要有三種方向。我用表格簡單列一下對比遷移方向RHEL 兼容性遷移成本維護周期適合場景CentOS Stream 8/9與 RHEL 同源屬于滾動發(fā)布的中間版本中等yum 源和軟件版本差異小按 Stream 版本獨立節(jié)奏維護想繼續(xù)留在 CentOS 生態(tài)且能接受滾動更新模式AlmaLinux / Rocky Linux面向 RHEL 兼容重建社區(qū)維護穩(wěn)定中等可直接在 CentOS 7 上做系統(tǒng)遷移工具升級跟隨 RHEL 生命周期通常 8 到 10 年生產(chǎn)環(huán)境做平滑遷移需要可靠長期維護Debian / Ubuntu LTS不兼容 RHEL 體系軟件包格式不同較高應(yīng)用需要重新編譯部署按各發(fā)行版 LTS 周期維護借機做架構(gòu)升級愿意接受更大的改動量如果你只是想把現(xiàn)有業(yè)務(wù)盡快穩(wěn)定住我建議優(yōu)先考慮 RHEL 兼容路線遷移過程中業(yè)務(wù)系統(tǒng)的改動量最小。如果本身運維團隊對 Debian 系更熟而且應(yīng)用沒有強依賴 RHEL 的某些特性第三條路線也不差。不要因為“換系統(tǒng)”聽起來成本高就一直拖著拖到官方源徹底不可用的時候連應(yīng)急修復(fù)的機會都會越來越少。5.3 建議做一個源健康監(jiān)控CentOS 7 源已經(jīng)處于“半只腳入土”的狀態(tài)它什么時候再次出現(xiàn)故障完全不可預(yù)測。與其被動等業(yè)務(wù)反饋不如主動監(jiān)控。我在處理完源問題后給相關(guān)服務(wù)器加了一個簡單的巡檢腳本#!/bin/bash REPO_URLhttp://vault.centos.org/7.9.2009/os/x86_64/repodata/repomd.xml if ! curl -sI --connect-timeout 5 $REPO_URL | grep -qE 200|301|302; then echo $(date %F %T) CentOS 7 yum repo check failed: $REPO_URL /var/log/yum-repo-check.log fi放到 crontab 里每天跑一次crontab -e 0 6 * * * /opt/scripts/check-centos7-repo.sh有告警可以直接發(fā)給值班群。這個腳本成本很低但能避免下次源出問題時全業(yè)務(wù)一起踩雷。5.4 一點個人經(jīng)驗CentOS 7 源失效這個問題我在不同環(huán)境里處理過很多次最深的體會是不要急著背命令先把報錯拆開看。是 DNS 解析失敗還是 404是單個倉庫掛掉還是所有倉庫掛掉這決定了完全不同的處理路徑。repomd.xml拉取失敗和包安裝失敗是兩回事混在一起排查會浪費大量時間。另外一點很實用修改源配置時盡量做到“最小變更”。只注釋該注釋的mirrorlist只替換該替換的 baseurl不要把倉庫文件里的其他參數(shù)順手改掉否則排查時你又多了一堆變量。每次改完都執(zhí)行一次yum clean all yum makecache做驗證別讓舊緩存掩蓋問題。最后再分享一個小技巧。處理這類問題時我會先把/etc/yum.repos.d/里所有.repo文件全部拉出來看一眼。很多 CentOS 7 服務(wù)器不止配置了官方源和 EPEL還殘留了各種第三方源和內(nèi)部私有源。它們雖然平時不顯眼但在主源失效的同一個時間點往往也會一起出問題。把整個目錄里的倉庫狀態(tài)都過一遍再針對性修復(fù)遠比盯著某一條報錯要高效得多。