阶段一:在线准备(在有互联网连接的机器上)
这一步的目标是收集所有需要的 RPM 包及其所有依赖,还有创建仓库所需的工具。
-
准备一个"镜像"环境:
-
最重要的一点 : 需要一个可以上网的、与你最终要部署的离线 ARM 虚拟机 操作系统版本完全相同 、架构也完全相同 (比如都是 CentOS 8.x aarch64) 的机器或虚拟机。这是为了确保依赖关系被正确解析。
-
在这个在线机器上配置好官方源、EPEL 源或任何你需要的第三方软件源。
-
-
确定根软件包列表:
- 列出为了部署容器环境(如 Docker CE, Podman, Kubernetes components: kubelet, kubeadm, kubectl 等)直接需要安装的那些包的名称。
-
下载所有必需的 RPM 包 (包括依赖):
-
创建一个专门的目录来存放所有下载的 RPM 文件,例如:
bashmkdir ~/offline-arm-repo cd ~/offline-arm-repo
-
使用
dnf download
(推荐) 或yumdownloader
(需要yum-utils
) 命令,配合--resolve
选项来下载你的根软件包以及它们的所有依赖项。bash# 如果是 dnf 系统 (如 CentOS 8+, Fedora) # 将 <package1> <package2> ... 替换为你的根软件包列表 dnf download --resolve <package1> <package2> ... # 如果是 yum 系统 (如 CentOS 7) # 确保已安装 yum-utils: sudo yum install yum-utils yumdownloader --resolve --destdir=. <package1> <package2> ...
-
--resolve
参数至关重要,它会确保所有依赖包(包括依赖的依赖)都被下载。 -
这个命令只会下载 RPM 文件,不会安装它们。
-
所有下载的
.rpm
文件都会保存在你当前所在的目录 (~/offline-arm-repo
)。
-
-
-
下载仓库创建工具
createrepo_c
:-
千万不要忘记 : 你在离线机器上创建仓库需要
createrepo_c
(较新系统) 或createrepo
(较旧系统) 这个工具。你也必须把它(以及它的依赖!)下载下来。bash# dnf 系统 dnf download --resolve createrepo_c # yum 系统 yumdownloader --resolve --destdir=. createrepo_c # 或者 createrepo,取决于你的系统版本
-
确保
createrepo_c
(或createrepo
) 及其所有依赖的 RPM 文件也在你的~/offline-arm-repo
目录中。
-
阶段二:传输文件到离线机器
-
打包传输:
-
将包含所有
.rpm
文件的~/offline-arm-repo
整个目录,通过 USB 驱动器、内部网络传输工具 (如 scp 如果有内部网络) 等方式,复制到你的目标离线 ARM 虚拟机上。 -
假设你将它放在离线机器的
/opt/offline-repo
目录下。
-
阶段三:在离线机器上创建本地仓库
-
安装
createrepo_c
:-
在离线机器上,进入你复制过来的目录:
bashcd /opt/offline-repo
-
找到
createrepo_c
(或createrepo
) 的 RPM 文件以及它可能需要的依赖的 RPM 文件(这些应该都在这个目录里)。 -
使用
rpm
命令手动安装它。你可能需要先安装它的依赖。最保险的方式是按依赖顺序安装,或者如果依赖不多且都在当前目录,可以尝试用dnf
或yum
直接安装(但这可能会因仓库未配置而失败)。bash# 找到 createrepo_c 的确切 rpm 文件名,例如: # sudo rpm -ivh createrepo_c-libs-*.aarch64.rpm # 如果有 createrepo_c-libs 依赖 sudo rpm -ivh createrepo_c-*.aarch64.rpm # 安装主包 # 如果 rpm 安装提示缺少依赖,你需要先安装提示的那个依赖包(它也应该在此目录下) # 或者尝试(可能有效,也可能无效): # sudo dnf install createrepo_c-*.aarch64.rpm # sudo yum install createrepo_c-*.aarch64.rpm
-
-
生成仓库元数据:
-
确保你仍然在包含所有 RPM 文件的目录 (
/opt/offline-repo
) 下。 -
运行
createrepo_c
(或createrepo
) 命令来扫描当前目录下的所有 RPM 文件并创建仓库索引(元数据):bash# 使用 createrepo_c (推荐用于较新系统) sudo createrepo_c . # "." 表示在当前目录下创建 # 或者使用 createrepo (用于较旧系统) # sudo createrepo .
-
这个命令执行成功后,会在当前目录 (
/opt/offline-repo
) 下创建一个名为repodata
的子目录。这个子目录包含了dnf
或yum
识别仓库所需的索引文件 (如repomd.xml
)。
-
阶段四:在离线机器上配置 YUM/DNF 使用本地仓库
-
创建
.repo
文件:-
在
/etc/yum.repos.d/
目录下创建一个新的配置文件,例如offline.repo
:bashsudo vi /etc/yum.repos.d/offline.repo
-
在该文件中添加以下内容:
-
ini
[offline-local] # 这是仓库的唯一 ID,你可以自定义,但要记住它
name=My Offline Local Repository # 仓库的描述性名称
baseurl=file:///opt/offline-repo/ # 关键!指向包含 repodata 目录的那个目录的绝对路径
# 注意是 file:// 协议和三个斜杠 ///
enabled=1 # 启用这个仓库
gpgcheck=0 # 通常本地文件仓库不进行 GPG 签名检查,设为 0
# 如果你管理了 GPG 密钥,可以设为 1 并指定 gpgkey=file:///path/to/your/RPM-GPG-KEY
- 保存并关闭文件 (在 `vi` 中按 `Esc`,然后输入 `:wq` 回车)。
- 禁用其他仓库 (非常重要) :
-
为了确保
dnf
/yum
只使用你的本地仓库,你需要禁用所有其他的.repo
文件(特别是那些指向互联网的官方源)。 -
方法一:编辑
/etc/yum.repos.d/
下的其他所有.repo
文件,将enabled=1
改为enabled=0
。 -
方法二:将其他
.repo
文件移动到别处或修改扩展名,例如:bashsudo find /etc/yum.repos.d/ -type f -name "*.repo" ! -name "offline.repo" -exec mv {} {}.disabled \; # 或者创建一个备份目录并移动它们 # sudo mkdir /etc/yum.repos.d/disabled # sudo mv /etc/yum.repos.d/CentOS-*.repo /etc/yum.repos.d/disabled/ # sudo mv /etc/yum.repos.d/epel*.repo /etc/yum.repos.d/disabled/
-
阶段五:验证本地仓库
-
清理缓存并生成新缓存:
bash# dnf 系统 sudo dnf clean all sudo dnf makecache # yum 系统 sudo yum clean all sudo yum makecache fast
-
测试列出可用包:
-
尝试列出仅来自你本地仓库的包,确认它被识别:
bashdnf list available --disablerepo="*" --enablerepo="offline-local" # 将 offline-local 替换为你的仓库 ID # 或者 yum list available --disablerepo="*" --enablerepo="offline-local"
-
应该能看到
/opt/offline-repo
目录下的那些 RPM 包被列出来。
-
-
尝试安装:
-
尝试使用
dnf
或yum
来安装之前下载到仓库里的任何一个包了:bashsudo dnf install <some-package-name> # 例如: sudo dnf install docker-ce
-
如果一切配置正确,
dnf
或yum
会在/opt/offline-repo
中找到包及其依赖,并成功安装。
-
-
交互式输入: 像之前的脚本一样,让你输入想要检查和安装的包名。
-
列出依赖 : 对于你输入的 每个 包,它会首先使用
dnf deplist
或yum deplist
显示其依赖关系,让你知晓需要哪些东西。 -
检查安装状态 : 接着,它会检查你输入的这个包 本身 是否已经安装。
-
自动安装 (如果需要) : 如果该包尚未安装,脚本会自动尝试使用你预先配置好的 离线本地仓库 (
offline-local
或你指定的名字) 来安装它。它会强制dnf
/yum
只使用这个离线仓库。 -
报告结果: 脚本会告诉你每个包是已安装、成功安装还是安装失败。
重要前提:
- 你必须已经在离线 ARM 虚拟机上成功创建并配置了本地 YUM/DNF 仓库。
- 你需要知道这个本地仓库的 Repository ID (在
/etc/yum.repos.d/
下你创建的.repo
文件中,方括号[...]
里的那个名字,比如offline-local
)。 - 建议禁用所有其他的
.repo
文件,或者至少确保此脚本运行时网络不可达,以防意外。脚本本身也会尝试强制只使用本地仓库。
脚本 (check_install_deps.sh
):
bash
#!/bin/bash
# --- 配置 ---
# 重要:设置你的离线仓库 ID
# (在 /etc/yum.repos.d/your-offline.repo 文件中 [ ] 里的名字)
OFFLINE_REPO_ID="offline-local"
# --- 结束配置 ---
# --- 检测包管理器 ---
PKG_MGR=""
INSTALL_CMD=""
if command -v dnf &> /dev/null; then
PKG_MGR="dnf"
INSTALL_CMD="dnf install -y"
elif command -v yum &> /dev/null; then
PKG_MGR="yum"
INSTALL_CMD="yum install -y"
else
echo "错误: 未找到 'dnf' 或 'yum' 命令。请先安装其中一个。"
exit 1
fi
echo "使用 '$PKG_MGR' 进行依赖查询和安装。"
echo "将从离线仓库 '$OFFLINE_REPO_ID' 安装缺失的包。"
echo
# --- 获取用户输入的包列表 ---
echo "请输入需要检查和安装的 RPM 包名,用空格分隔:"
read -p "> " -a package_list
# 检查用户是否输入了内容
if [ ${#package_list[@]} -eq 0 ]; then
echo "未输入包名。正在退出。"
exit 0
fi
echo
echo "========================================"
echo "开始处理包列表..."
echo "========================================"
echo
# --- 标记整体是否成功 ---
all_processed_successfully=true
# --- 循环处理每个输入的包 ---
for pkg_name in "${package_list[@]}"; do
echo "--- 处理包: $pkg_name ---"
# 1. 列出依赖 (信息性)
echo "查询 '$pkg_name' 的依赖关系..."
"$PKG_MGR" deplist "$pkg_name"
if [ $? -ne 0 ]; then
echo "警告: 查询 '$pkg_name' 的依赖时出错 (可能是仓库中不存在此包?)"
fi
echo "----------------------------------------"
# 2. 检查包是否已安装
echo -n "检查 '$pkg_name' 是否已安装... "
rpm -q "$pkg_name" >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "已安装。"
else
echo "未安装。"
# 3. 尝试从离线仓库安装
echo "尝试从离线仓库 '$OFFLINE_REPO_ID' 安装 '$pkg_name'..."
# 构建安装命令,强制使用离线仓库
# 注意:需要 root/sudo 权限来安装
install_command="$INSTALL_CMD --disablerepo='*' --enablerepo='$OFFLINE_REPO_ID' '$pkg_name'"
echo "执行命令: sudo $install_command" # 显示将要执行的命令
# 执行安装 (需要 sudo)
sudo $PKG_MGR install -y --disablerepo='*' --enablerepo="$OFFLINE_REPO_ID" "$pkg_name"
# 检查安装结果
if [ $? -eq 0 ]; then
echo "成功从 '$OFFLINE_REPO_ID' 安装了 '$pkg_name' (及其依赖)。"
else
echo "错误: 从 '$OFFLINE_REPO_ID' 安装 '$pkg_name' 失败。" >&2
echo " 请检查 '$OFFLINE_REPO_ID' 仓库中是否包含 '$pkg_name' 及其所有依赖包。" >&2
all_processed_successfully=false # 标记出现错误
fi
fi
echo "========================================"
echo # 添加空行增加可读性
done
# --- 最终总结 ---
echo "所有请求处理完毕。"
if $all_processed_successfully; then
echo "所有指定的包现在都已安装或之前已安装。"
exit 0
else
echo "处理过程中遇到错误,部分包可能未能成功安装。"
exit 1
fi
如何使用:
-
配置:
-
打开脚本文件 (
check_install_deps.sh
)。 -
修改
OFFLINE_REPO_ID="offline-local"
这一行,确保"offline-local"
是你实际的离线仓库 ID。
-
-
保存: 将修改后的脚本保存在你的离线 ARM 虚拟机上。
-
赋执行权限 : 在终端运行
chmod +x check_install_deps.sh
。 -
运行 : 在终端运行
./check_install_deps.sh
。- 重要 : 因为脚本内部会调用
sudo
来执行安装命令,所以运行脚本本身不需要sudo
,但在执行过程中,系统会提示你输入sudo
密码(如果需要的话)。
- 重要 : 因为脚本内部会调用
-
交互:
-
脚本会提示你输入包名。
-
输入你想检查和(如果需要)安装的包名,用空格隔开,然后按 Enter。
-
脚本会为每个你输入的包名:
-
显示它的依赖列表。
-
告诉你它是否已安装。
-
如果未安装,尝试用
sudo dnf/yum install ...
从你的离线仓库安装它。 -
报告安装尝试的结果。
-
-
最后,脚本会给出一个总结。
-