Red hat Linux 使用 yum 離線安裝套件 (RHEL / CentOS / Rocky Linux)

情境是這樣的,因為一些特殊需求與限制,你需要在一台沒有網際網路連線的 Linux 主機上面安裝軟體,離線安裝 (offline install),
本來單純的以為只要把 rpm 檔案複製好就好,但發現事情並不想像中的那麼簡單,
所以筆記一下操作方式,以及需要注意的地方。

材料準備

講一下我們需要準備的材料:

  • 一台離線要安裝的目標主機(它沒有對外網路)
  • 一台能連網的主機,安裝對應版本的 VM (虛擬機)
  • 與目標主機對應版本的安裝 ISO 映象檔

操作步驟

你需要利用 yum 這個強大的套件管理工具,解析套件間的依賴 (dependency),
做自己所需要的套件庫,然後整個複製到目標機器,最後安裝它。

首先,調查清楚目標離線主機要安裝的 Linux 版本
整理出以下對照表:

  • RHEL 7.9 對應 CentOS 7-2009
  • RHEL 8.8 對應 Rocky Linux 8.8
  • RHEL 9.2 對應 Rocky Linux 9.2

然後下載對應的 ISO 映象檔:

Step 1. 準備一台可連網的虛擬機

在能連網的電腦上,
準備好虛擬機環境(例如:VMware、Hyper-V、VirtualBox)
找到對應版本的 minimal iso 來安裝系統(越小越好)

新增一個,規格小小的 VM,例如:

  • CPU: 2 core
  • RAM: 2GB
  • Disk: 20GB

掛載指定版本 ISO 來安裝 VM
Linux 的安裝過程就暫時跳過

重點是要「最小安裝」
到時候在循環檢查套件依賴的時候,
才可以抓得比較完整

確認網路

RHEL 預設網路不會開,你可能會遇到沒有網路可用的情況
需要自行設定網路與開啟網路

先用 ip a 找到所有的網卡裝置

# ip a

檢查網路卡名稱,然後編輯對應的網路卡設定檔

編輯 ifcfg-XXX 檔案

$ sudo vi /etc/sysconfig/network-scripts/ifcfg-eth0

(假設你的網卡叫做 eth0

設定靜態 IP 位址

DEVICE=eth0
BOOTPROTO=none
IPADDR=192.168.1.2     # 修改 IP 位址
NETMASK=255.255.255.0  # 子網路遮罩
GATEWAY=192.168.2.254  # 網路閘道
DNS1=192.168.1.1
DNS2=8.8.8.8
DNS3=8.8.4.4
DEFROUTE=yes

ONBOOT=yes

或者 DHCP

DEVICE=eth0
BOOTPROTO=dhcp
ONBOOT=yes

最重要的就是修改 ONBOOT 區段,要設定成 yes

ONBOOT=yes

然後 :wq 存檔

最後重啟網路服務

$ sudo systemctl restart NetworkManager

因版本不同,也有可能是這樣,看發行版本

$ sudo systemctl restart network

或者可以用新版 nmcli 指令

$ sudo nmcli con mod "eth0" \
  ipv4.method "manual" \
  ipv4.addresses "192.168.1.2/24" \
  ipv4.gateway "10.200.1.1" \
  ipv4.dns "8.8.8.8,1.1.1.1"

或者修改 XXX.nmconnection 檔案

$ sudo vi /etc/NetworkManager/system-connections/eth0.nmconnection

修改 [ipv4] 段落

[ipv4]
method=manual
dns=8.8.8.8,1.1.1.1;
address1=192.168.1.2/24,192.168.1.1

最後存檔

Step 2. 安裝套件

首先在 root 身份下,
執行 yum update 指令,將套件清單更新一下

# yum update -y  

在這台能連網的電腦裝一下套件

# yum install -y tar yum-utils createrepo

然後建立一個資料夾,
前者存放所有套件,後者存放其暫存檔

# mkdir -p /tmp/yumrepo
# mkdir -p /tmp/yumrepo-installroot

Step 3. 加入你需要的來源庫 (Optional)

這裡看你的需要加入你所需要的來源庫,
例如我需要加入 docker 與 kubernetes (k8s) 的來源庫

這裡要參考 docker 安裝說明kubernetes 安裝說明 文件

加入 docker 參考
(指令僅供參考,來源庫可能隨時會更新)

# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

加入 kubeernetes 參考
(指令僅供參考,來源庫可能隨時會更新)

# cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.28/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.28/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF

Step 4. 下載你所需的套件

萬事俱備!用 yum install --downloadonly 來下載所有你所需要的套件
注意 releasever 要根據你的版本做修改,
RHEL 7.9 就用 7,RHEL 8.8 就用 8,RHEL 9.2 就用 9,以此類推

# yum install --downloadonly --releasever=7 
--installroot=/var/tmp/yumrepo-installroot 
--downloaddir=/var/tmp/yumrepo -y
docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin sudo openssh-clients openssh-server tmux python3 vim net-tools tar yum-utils createrepo

它會很神奇的全自動去解析相依性的套件,並全部下載下來

Step 5. 建立離線 yum 來源庫

最後這邊是關鍵ㄧ步,
我們使用 createrepo 指令,將剛剛下載的一堆 rpm 建立成 yum 來源庫

# createrepo --database /var/tmp/yumrepo

不然只是散的一堆 rpm 而已

Step 6. 打包並複製到目標機

你可以用 tar 指令整個資料夾打包成 tar.gz 檔案

# tar zcvf yumrepo.tar.gz /var/tmp/yumrepo

唯有要注意的是,
RHEL 8.8/9.2 的最小安裝可能並不包含 tar 指令,
記得去資料夾找到 tar 的 rpm 多複製一份出來
(我的版本與檔案叫 tar-1.34-6.el9_1.x86_64.rpm 供參考)

至於怎麼複製到目標機?方式很多種,就不多做介紹了


Step 7. 目標機解壓縮並安裝

這裡來到離線無網路的目標機
假設你準備的檔案,一樣複製到了 /var/tmp 底下

剛剛提到 RHEL 8.8/9.2 的最小安裝可能並不包含 tar 指令,
rpm 指令安裝一下(檔名請換成你當下的)

# rpm -ivh tar-1.34-6.el9_1.x86_64.rpm

然後解壓縮

# tar zxvf yumrepo.tar.gz

Step 8. 製作來源庫描述檔

我們在離線目標機上面,直接用 cat 指令,製作一個來源庫描述檔

# cat <<EOF | sudo tee /etc/yum.repos.d/offline-yumrepo.repo
[offline-yumrepo]
name=CentOS-$releasever - yumrepo
baseurl=file:///var/tmp/yumrepo
enabled=1
gpgcheck=0
EOF

注意 baseurl 為到時候放入離線目標機的檔案路徑,可能要依據情境來修改

(其實也可以在前面的連網的虛擬機先做好一起打包,再複製到指定位置也可以)

這下你已經設定好離線的 yum 來源了

Step 9. 離線安裝

接下來的步驟就跟一般 yum 一樣了,安裝你需要的套件即可

# yum --disablerepo=\* --enablerepo=offline-yumrepo -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-compose vim net-tools yum-utils python3 sudo kubelet kubeadm kubectl --disableexcludes=kubernetes

這邊多了二個參數 --disablerepo=\*--enablerepo=offline-yumrepo
意思就是,關掉全部的來源,只開我們指定的 offline-yumrepo 來源

這樣子就完成了。
咦?我剛剛不小心幫你裝了 docker 跟 kubeadm 嗎?

參考資料