網(wǎng) Rocky 9.2 批量裝軟件:基于 HTTP 的 YUM 源搭建實(shí)戰(zhàn))
簡介這份文檔面向在內(nèi)網(wǎng)隔離環(huán)境中運(yùn)維多臺 Linux 服務(wù)器的工程師針對無法訪問互聯(lián)網(wǎng)、逐臺配置本地源或手動安裝 rpm 包效率低下的痛點(diǎn)給出基于 HTTP 搭建局域網(wǎng) YUM 源的完整方案。內(nèi)容以 Rocky Linux 9.2 為例涵蓋 YUM 服務(wù)器與客戶機(jī)的角色劃分、鏡像掛載、倉庫配置文件編寫、httpd 服務(wù)部署以及客戶機(jī)緩存刷新與驗(yàn)證等關(guān)鍵環(huán)節(jié)并附有可直接參考的配置片段與命令示例。資源包共 1 個 docx 文件約 120KB以圖文步驟形式組織便于按章節(jié)對照實(shí)操。已有 1693 人學(xué)習(xí)下載適合需要統(tǒng)一軟件版本、提升批量部署效率的運(yùn)維人員參考也可為其他基于 RPM 的發(fā)行版遷移配置提供思路。1. 內(nèi)網(wǎng)幾十臺 Rocky 9.2 裝軟件為什么我最后選了 HTTP 做 YUM 源項(xiàng)目現(xiàn)場有幾十臺 Rocky Linux 9.2 服務(wù)器全部跑在跟 Internet 物理隔離的內(nèi)網(wǎng)里。每次裝個軟件要么把 rpm 包一個個 scp 上去手動rpm -ivh依賴報(bào)錯能報(bào)一屏要么每臺機(jī)器單獨(dú)掛 ISO 配本地源幾十臺重復(fù)勞動版本還容易對不齊。這兩種方式我都踩過前者費(fèi)時費(fèi)力后者維護(hù)成本高得離譜。后來我把思路換了一下與其每臺機(jī)器各自為戰(zhàn)不如在內(nèi)網(wǎng)里找一臺機(jī)器當(dāng)軟件倉庫把 Rocky 9.2 的 DVD ISO 掛上去用 HTTP 服務(wù)暴露出來其他機(jī)器通過baseurlhttp://內(nèi)網(wǎng)IP/...直接拉包。這就是基于 HTTP 的局域網(wǎng) YUM 源。它解決的核心問題就一個——內(nèi)網(wǎng)環(huán)境下讓所有 Rocky 機(jī)器共享同一份軟件源裝包、升級、版本一致性一次搞定。適合誰手上有一批內(nèi)網(wǎng) Linux 服務(wù)器、需要統(tǒng)一軟件管理的運(yùn)維和交付工程師。下面我把整套流程拆開講包括我實(shí)際踩過的坑。2. 服務(wù)端搭建掛載 ISO、裝 httpd、配本地源這一章是整件事的地基。服務(wù)端這臺機(jī)器下面統(tǒng)一叫 linux1IP 192.168.15.100要同時扮演兩個角色一是通過 HTTP 把 ISO 里的軟件包目錄暴露出去二是自己也得能裝 httpd 這個軟件所以它需要先有一個能用的本地 YUM 源。順序不能亂——先掛 ISO、配本地源、裝 httpd再談對外服務(wù)。2.1 掛載 ISO 到 Web 根目錄Rocky 9.2 的 DVD ISO 里軟件包分在兩個目錄BaseOS和AppStream。這兩個目錄就是后面 YUM 源要指向的 baseurl。掛載點(diǎn)我直接選在/var/www/html/opt因?yàn)?httpd 默認(rèn)的 Web 根目錄就是/var/www/html掛到這里HTTP 訪問路徑天然就是/opt/...省得再改 httpd 配置。# 創(chuàng)建掛載點(diǎn)目錄-p 保證父目錄不存在時一并創(chuàng)建 mkdir -p /var/www/html/opt # 把 ISO 掛載到 Web 根目錄下的 opt # 注意ISO 文件本身要先放到服務(wù)器上比如 /opt 目錄 mount -o loop /opt/Rocky-9.2-x86_64-dvd.iso /var/www/html/opt # 驗(yàn)證掛載結(jié)果應(yīng)該能看到 BaseOS 和 AppStream 兩個目錄 ls /var/www/html/opt這里有個參數(shù)值得說-o loop是讓內(nèi)核把普通文件當(dāng)成塊設(shè)備來掛載ISO 就是這種用法。掛載完ls一下如果只看到BaseOS、AppStream、EFI這些目錄說明掛對了。如果報(bào)mount: wrong fs type八成是 ISO 路徑寫錯或者文件沒傳完。提示mount是臨時的機(jī)器重啟后掛載就沒了。生產(chǎn)環(huán)境建議寫進(jìn)/etc/fstab用loop選項(xiàng)或者干脆寫個開機(jī)腳本重新掛。我一般會在 fstab 里加一行避免重啟后源突然失效這種玄學(xué)問題。2.2 配置服務(wù)端自己的本地 YUM 源linux1 要裝 httpd但它現(xiàn)在還沒有任何可用的源。所以先給它配一個指向本地掛載目錄的 repo 文件。Rocky 9 的 repo 目錄是/etc/yum.repos.d/注意別寫成/etc/yum.repo.d/少個 s 直接不生效這個拼寫坑我見過不止一次。# 文件路徑/etc/yum.repos.d/local.repo [Rocky-BaseOS] nameRocky-BaseOS baseurlfile:///var/www/html/opt/BaseOS/ enabled1 gpgcheck0 [Rocky-AppStream] nameRocky-AppStream baseurlfile:///var/www/html/opt/AppStream/ enabled1 gpgcheck0逐項(xiàng)說明baseurl用file://協(xié)議指向本地掛載點(diǎn)這是服務(wù)端自己用的enabled1表示啟用gpgcheck0是關(guān)閉 GPG 簽名校驗(yàn)——內(nèi)網(wǎng)自建源圖省事通常這么干但如果你們有安全合規(guī)要求應(yīng)該導(dǎo)入 Rocky 的 GPG key 并設(shè)成gpgcheck1。兩個倉庫缺一不可BaseOS 放基礎(chǔ)系統(tǒng)包AppStream 放應(yīng)用流包只配一個的話裝 httpd 時依賴可能找不全。配好之后把系統(tǒng)自帶的那些 repo 文件清掉避免它們干擾內(nèi)網(wǎng)訪問不到外網(wǎng)源留著只會拖慢 yum 操作# 進(jìn)入 repo 目錄 cd /etc/yum.repos.d/ # 刪除除 local.repo 以外的所有 repo 文件 # 注意這條命令依賴 extglob先確認(rèn) shell 支持 shopt -s extglob rm -rf !(local.repo) # 刷新緩存驗(yàn)證本地源可用 yum clean all yum makecacherm -rf !(local.repo)這個寫法用的是 bash 的擴(kuò)展通配意思是刪掉除了 local.repo 之外的所有東西。執(zhí)行前務(wù)必ls確認(rèn)一下當(dāng)前目錄手一抖刪錯目錄就是血淚教訓(xùn)。穩(wěn)妥點(diǎn)的做法是先mkdir /tmp/repo_bak mv *.repo /tmp/repo_bak/再單獨(dú)把 local.repo 放回來。2.3 安裝并啟動 httpd本地源通了裝 httpd 就是一條命令的事。httpd 是 Apache 的 RPM 包名在 Rocky 9 里由 AppStream 倉庫提供。# 安裝 httpd yum install -y httpd # 啟動 httpd 并設(shè)為開機(jī)自啟 systemctl start httpd systemctl enable httpd # 放行防火墻如果 firewalld 在跑 # 臨時關(guān)閉方式測試環(huán)境常用生產(chǎn)建議按端口放行 systemctl stop firewalld # 關(guān)閉 SELinux 強(qiáng)制模式臨時 setenforce 0 # 驗(yàn)證 httpd 是否在監(jiān)聽 80 端口 ss -tlnp | grep :80關(guān)于防火墻和 SELinux這里我要多說一句。原文里直接systemctl stop firewalld和setenforce 0測試環(huán)境圖快可以但生產(chǎn)環(huán)境這么干等于把安全策略全卸了。更合理的做法是防火墻只放行 80 端口firewall-cmd --add-servicehttp --permanent firewall-cmd --reloadSELinux 如果不想關(guān)需要給 Web 目錄打上正確的上下文標(biāo)簽chcon -R -t httpd_sys_content_t /var/www/html/opt否則 httpd 讀不到掛載目錄里的文件瀏覽器訪問會報(bào) 403。這個 403 是新手最容易卡住的地方——服務(wù)明明起來了就是訪問不了十有八九是 SELinux 在攔。配完之后在服務(wù)端本機(jī)先自測一下# 本機(jī)訪問應(yīng)該返回目錄列表或歡迎頁 curl -I http://127.0.0.1/opt/BaseOS/ # 如果返回 200說明 HTTP 服務(wù)正常 # 如果返回 403檢查 SELinux 上下文和目錄權(quán)限看到HTTP/1.1 200就說明服務(wù)端這半邊成了。接下來才是客戶機(jī)的事。3. 客戶機(jī)接入repo 文件怎么寫、緩存怎么刷服務(wù)端跑通只是完成一半客戶機(jī)能不能正確拉到包取決于 repo 文件寫得對不對、網(wǎng)絡(luò)通不通、緩存刷沒刷干凈。這一章把客戶機(jī)linux2192.168.15.101的配置和驗(yàn)證講透。3.1 客戶機(jī) repo 文件的關(guān)鍵差異客戶機(jī)的 repo 文件結(jié)構(gòu)跟服務(wù)端幾乎一樣唯一的區(qū)別是baseurl從file://換成了http://服務(wù)端IP。這個 IP 必須寫服務(wù)端真實(shí)的內(nèi)網(wǎng) IP別寫127.0.0.1也別寫主機(jī)名除非你配了 DNS 或 hosts。# 文件路徑/etc/yum.repos.d/local.repo [Rocky-BaseOS] nameRocky-BaseOS baseurlhttp://192.168.15.100/opt/BaseOS/ enabled1 gpgcheck0 [Rocky-AppStream] nameRocky-AppStream baseurlhttp://192.168.15.100/opt/AppStream/ enabled1 gpgcheck0注意原文里客戶機(jī)部分寫的是192.168.1.100而環(huán)境準(zhǔn)備里服務(wù)端是192.168.15.100這兩個 IP 段不一致。這大概率是原文筆誤實(shí)際配置時以你真實(shí)的服務(wù)端 IP 為準(zhǔn)。IP 寫錯是客戶機(jī)報(bào)Could not resolve host或Connection refused的頭號原因配完先ping 192.168.15.100確認(rèn)網(wǎng)絡(luò)可達(dá)。同樣客戶機(jī)上也要清掉系統(tǒng)自帶的 repo 文件只留這一個cd /etc/yum.repos.d/ shopt -s extglob rm -rf !(local.repo)3.2 刷新緩存并驗(yàn)證源可用repo 文件放好后必須清緩存再重建否則 yum 可能還在用舊的元數(shù)據(jù)。這一步是讓配置真正生效的關(guān)鍵動作。# 清除所有緩存包括元數(shù)據(jù)和包 yum clean all # 重新生成緩存這一步會去 HTTP 源拉 repodata yum makecache # 列出所有可用的包驗(yàn)證源工作正常 yum list # 更精準(zhǔn)的驗(yàn)證查一個具體包 yum list available httpdyum makecache如果成功會顯示類似Metadata cache created的字樣。如果卡住或報(bào)錯按這個順序排查先curl http://192.168.15.100/opt/BaseOS/repodata/看能不能列出文件能列出說明 HTTP 層通了再看服務(wù)端 httpd 是否在跑、防火墻是否放行最后檢查客戶機(jī) repo 文件里的 URL 拼寫。yum list能刷出一大串包名基本就成功了。想更直觀直接裝個包試試# 實(shí)際安裝一個包驗(yàn)證完整鏈路 yum install -y tree # 裝完確認(rèn) tree --version能裝上說明從客戶機(jī)到服務(wù)端的整條鏈路——網(wǎng)絡(luò)、HTTP、repo 元數(shù)據(jù)、包下載——全部打通。3.3 多臺客戶機(jī)的批量落地思路幾十臺機(jī)器一臺臺手配 repo 文件顯然不現(xiàn)實(shí)。常見做法是寫一個配置腳本把 repo 文件內(nèi)容和服務(wù)端 IP 作為變量通過批量工具比如 Ansible、pssh或者你們現(xiàn)場用的任何批量執(zhí)行手段推下去。核心邏輯就三步寫 repo 文件、清緩存、makecache。#!/bin/bash # 批量配置客戶機(jī) YUM 源的腳本骨架 # 用法把 SERVER_IP 改成你的服務(wù)端 IP然后批量執(zhí)行 SERVER_IP192.168.15.100 REPO_FILE/etc/yum.repos.d/local.repo # 備份并清理舊 repo mkdir -p /tmp/repo_bak mv /etc/yum.repos.d/*.repo /tmp/repo_bak/ 2/dev/null # 寫入新的 repo 配置 cat ${REPO_FILE} EOF [Rocky-BaseOS] nameRocky-BaseOS baseurlhttp://${SERVER_IP}/opt/BaseOS/ enabled1 gpgcheck0 [Rocky-AppStream] nameRocky-AppStream baseurlhttp://${SERVER_IP}/opt/AppStream/ enabled1 gpgcheck0 EOF # 刷新緩存 yum clean all yum makecache這個腳本用 heredoc 把變量SERVER_IP嵌進(jìn) repo 文件改 IP 只改一處。批量執(zhí)行時只要目標(biāo)機(jī)器能訪問服務(wù)端 80 端口腳本跑完就能用。注意mv那步做了備份萬一新源有問題把/tmp/repo_bak/里的文件挪回去就能回滾算是留了顆后悔藥。4. 避坑與排查那些讓 YUM 源看起來配好了卻用不了的問題這套方案步驟不多但坑都藏在細(xì)節(jié)里。下面這幾條是我在實(shí)際項(xiàng)目里真金白銀踩出來的每條按現(xiàn)象 → 原因 → 解決說清楚。4.1 客戶機(jī)報(bào) 403 Forbidden現(xiàn)象yum makecache報(bào)錯curl http://服務(wù)端IP/opt/BaseOS/返回 403。原因SELinux 攔住了 httpd 對/var/www/html/opt的讀取。掛載進(jìn)來的目錄默認(rèn)上下文不是httpd_sys_content_thttpd 沒權(quán)限讀。解決臨時setenforce 0驗(yàn)證是不是 SELinux 問題確認(rèn)后用chcon -R -t httpd_sys_content_t /var/www/html/opt給目錄打標(biāo)簽或者用semanage fcontext做持久化規(guī)則。別一上來就永久關(guān) SELinux那是把問題蓋住而不是解決。4.2 重啟后 YUM 源突然失效現(xiàn)象服務(wù)端重啟一次所有客戶機(jī)yum全報(bào)錯curl服務(wù)端返回 404。原因ISO 是mount掛上去的重啟后掛載丟失/var/www/html/opt變成空目錄HTTP 自然找不到文件。解決把掛載寫進(jìn)/etc/fstab加loop選項(xiàng)例如/opt/Rocky-9.2-x86_64-dvd.iso /var/www/html/opt iso9660 loop,ro 0 0?;蛘邔憘€ systemd 服務(wù)/開機(jī)腳本重新掛載。這個坑最陰因?yàn)榕涞臅r候一切正常重啟后才爆。4.3 repo 文件目錄拼錯導(dǎo)致配置不生效現(xiàn)象repo 文件明明寫了yum repolist里卻看不到自定義的倉庫。原因目錄寫成了/etc/yum.repo.d/少個 s或者文件擴(kuò)展名不是.repo。yum 只認(rèn)/etc/yum.repos.d/下的.repo文件。解決ls /etc/yum.repos.d/確認(rèn)路徑和文件名yum repolist all看倉庫有沒有被識別。拼寫這種事檢查一遍比 debug 半小時快。4.4 客戶機(jī)和服務(wù)端 IP 段不一致現(xiàn)象客戶機(jī)yum makecache卡很久然后超時ping服務(wù)端不通。原因repo 文件里的 IP 寫錯或者客戶機(jī)和服務(wù)端不在同一網(wǎng)段、路由不通。原文里服務(wù)端是192.168.15.100客戶機(jī)配置卻寫了192.168.1.100這種筆誤在實(shí)際操作中很常見。解決先ping服務(wù)端 IP 確認(rèn)三層可達(dá)再curl確認(rèn) 80 端口通最后核對 repo 文件里的 URL。三層排查法從下往上定位。4.5 gpgcheck 開啟后報(bào)簽名錯誤現(xiàn)象把gpgcheck改成 1 后yum install報(bào)Public key for xxx.rpm is not installed。原因開啟了簽名校驗(yàn)但沒導(dǎo)入 Rocky 的 GPG 公鑰。解決從 ISO 里找到 GPG key通常在 ISO 根目錄的RPM-GPG-KEY-Rocky-9用rpm --import導(dǎo)入或者在 repo 文件里用gpgkeyfile:///...指定路徑。內(nèi)網(wǎng)測試環(huán)境用gpgcheck0沒問題但生產(chǎn)環(huán)境建議老老實(shí)實(shí)導(dǎo)入 key。5. 進(jìn)階把 YUM 源做成可持續(xù)維護(hù)的內(nèi)網(wǎng)軟件倉庫基礎(chǔ)版跑通之后這套東西還能再往前走一步。ISO 里的包是固定的但項(xiàng)目上經(jīng)常需要裝一些 ISO 里沒有的第三方 rpm或者要同步更新。這時候可以在 HTTP 根目錄下再建一個自定義倉庫目錄把額外收集的 rpm 放進(jìn)去用createrepo生成元數(shù)據(jù)然后在客戶機(jī) repo 文件里追加一個指向它的倉庫段。# 在服務(wù)端創(chuàng)建自定義倉庫目錄 mkdir -p /var/www/html/custom/Packages # 把額外的 rpm 包拷進(jìn)去 cp /path/to/your/*.rpm /var/www/html/custom/Packages/ # 安裝 createrepo_c 工具Rocky 9 里包名帶 _c yum install -y createrepo_c # 生成倉庫元數(shù)據(jù) createrepo_c /var/www/html/custom/ # 客戶機(jī)追加 repo 段 cat /etc/yum.repos.d/local.repo EOF [Custom] nameCustom baseurlhttp://192.168.15.100/custom/ enabled1 gpgcheck0 EOF # 客戶機(jī)刷新緩存 yum clean all yum makecachecreaterepo_c會在目錄下生成repodata/子目錄里面是 yum 需要的元數(shù)據(jù)。每次往Packages里加了新 rpm都要重新跑一次createrepo_c --update /var/www/html/custom/否則新包不會被識別。這個--update參數(shù)只更新變化部分比全量重建快。驗(yàn)證方法很簡單客戶機(jī)yum repolist應(yīng)該能看到Custom倉庫yum list available | grep 你的包名能查到就說明自定義倉庫生效了。如果查不到先確認(rèn)createrepo_c跑沒跑、repodata目錄在不在、HTTP 能不能訪問到。再進(jìn)階一點(diǎn)如果內(nèi)網(wǎng)機(jī)器多、對可用性要求高可以考慮用 rsync 定期從上游鏡像站同步前提是有一臺能出網(wǎng)的跳板機(jī)或者把 ISO 內(nèi)容直接解壓到磁盤而不是掛載避免掛載丟失的問題。解壓方式占磁盤空間但勝在穩(wěn)定重啟不受影響# 解壓 ISO 到 Web 目錄替代掛載方案 mkdir -p /var/www/html/opt mount -o loop /opt/Rocky-9.2-x86_64-dvd.iso /mnt cp -a /mnt/. /var/www/html/opt/ umount /mnt這樣/var/www/html/opt就是真實(shí)目錄重啟后依然在。代價是多占幾個 G 磁盤但對內(nèi)網(wǎng)服務(wù)器來說這點(diǎn)空間通常不是問題。從那以后我每次搭內(nèi)網(wǎng)源都會先把掛載方式確認(rèn)清楚——要么寫 fstab要么直接解壓絕不留一個重啟就失效的臨時掛載在生產(chǎn)環(huán)境里。這個習(xí)慣幫我省了好幾次半夜被叫起來排查的麻煩。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取