解决离线部署气隙相关问题

阶段一:在线准备(在有互联网连接的机器上)

这一步的目标是收集所有需要的 RPM 包及其所有依赖,还有创建仓库所需的工具。

  1. 准备一个"镜像"环境:

    • 最重要的一点 : 需要一个可以上网的、与你最终要部署的离线 ARM 虚拟机 操作系统版本完全相同架构也完全相同 (比如都是 CentOS 8.x aarch64) 的机器或虚拟机。这是为了确保依赖关系被正确解析。

    • 在这个在线机器上配置好官方源、EPEL 源或任何你需要的第三方软件源。

  2. 确定根软件包列表:

    • 列出为了部署容器环境(如 Docker CE, Podman, Kubernetes components: kubelet, kubeadm, kubectl 等)直接需要安装的那些包的名称。
  3. 下载所有必需的 RPM 包 (包括依赖):

    • 创建一个专门的目录来存放所有下载的 RPM 文件,例如:

      bash 复制代码
      mkdir ~/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)。

  4. 下载仓库创建工具 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 目录中。

阶段二:传输文件到离线机器

  1. 打包传输:

    • 将包含所有 .rpm 文件的 ~/offline-arm-repo 整个目录,通过 USB 驱动器、内部网络传输工具 (如 scp 如果有内部网络) 等方式,复制到你的目标离线 ARM 虚拟机上。

    • 假设你将它放在离线机器的 /opt/offline-repo 目录下。

阶段三:在离线机器上创建本地仓库

  1. 安装 createrepo_c:

    • 在离线机器上,进入你复制过来的目录:

      bash 复制代码
      cd /opt/offline-repo
    • 找到 createrepo_c (或 createrepo) 的 RPM 文件以及它可能需要的依赖的 RPM 文件(这些应该都在这个目录里)。

    • 使用 rpm 命令手动安装它。你可能需要先安装它的依赖。最保险的方式是按依赖顺序安装,或者如果依赖不多且都在当前目录,可以尝试用 dnfyum 直接安装(但这可能会因仓库未配置而失败)。

      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
  2. 生成仓库元数据:

    • 确保你仍然在包含所有 RPM 文件的目录 (/opt/offline-repo) 下。

    • 运行 createrepo_c (或 createrepo) 命令来扫描当前目录下的所有 RPM 文件并创建仓库索引(元数据):

      bash 复制代码
      # 使用 createrepo_c (推荐用于较新系统)
      sudo createrepo_c .  # "." 表示在当前目录下创建
      
      # 或者使用 createrepo (用于较旧系统)
      # sudo createrepo . 
    • 这个命令执行成功后,会在当前目录 (/opt/offline-repo) 下创建一个名为 repodata 的子目录。这个子目录包含了 dnfyum 识别仓库所需的索引文件 (如 repomd.xml)。

阶段四:在离线机器上配置 YUM/DNF 使用本地仓库

  1. 创建 .repo 文件:

    • /etc/yum.repos.d/ 目录下创建一个新的配置文件,例如 offline.repo

      bash 复制代码
      sudo 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` 回车)。
  1. 禁用其他仓库 (非常重要) :
    • 为了确保 dnf/yum 只使用你的本地仓库,你需要禁用所有其他的 .repo 文件(特别是那些指向互联网的官方源)。

    • 方法一:编辑 /etc/yum.repos.d/ 下的其他所有 .repo 文件,将 enabled=1 改为 enabled=0

    • 方法二:将其他 .repo 文件移动到别处或修改扩展名,例如:

      bash 复制代码
      sudo 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/ 

阶段五:验证本地仓库

  1. 清理缓存并生成新缓存:

    bash 复制代码
    # dnf 系统
    sudo dnf clean all
    sudo dnf makecache
    
    # yum 系统
    sudo yum clean all
    sudo yum makecache fast 
  2. 测试列出可用包:

    • 尝试列出仅来自你本地仓库的包,确认它被识别:

      bash 复制代码
      dnf list available --disablerepo="*" --enablerepo="offline-local" # 将 offline-local 替换为你的仓库 ID
      # 或者
      yum list available --disablerepo="*" --enablerepo="offline-local" 
    • 应该能看到 /opt/offline-repo 目录下的那些 RPM 包被列出来。

  3. 尝试安装:

    • 尝试使用 dnfyum 来安装之前下载到仓库里的任何一个包了:

      bash 复制代码
      sudo dnf install <some-package-name> 
      # 例如: sudo dnf install docker-ce
    • 如果一切配置正确,dnfyum 会在 /opt/offline-repo 中找到包及其依赖,并成功安装。

  4. 交互式输入: 像之前的脚本一样,让你输入想要检查和安装的包名。

  5. 列出依赖 : 对于你输入的 每个 包,它会首先使用 dnf deplistyum deplist 显示其依赖关系,让你知晓需要哪些东西。

  6. 检查安装状态 : 接着,它会检查你输入的这个包 本身 是否已经安装。

  7. 自动安装 (如果需要) : 如果该包尚未安装,脚本会自动尝试使用你预先配置好的 离线本地仓库 (offline-local 或你指定的名字) 来安装它。它会强制 dnf/yum 只使用这个离线仓库。

  8. 报告结果: 脚本会告诉你每个包是已安装、成功安装还是安装失败。

重要前提:

  • 你必须已经在离线 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

如何使用:

  1. 配置:

    • 打开脚本文件 (check_install_deps.sh)。

    • 修改 OFFLINE_REPO_ID="offline-local" 这一行,确保 "offline-local" 是你实际的离线仓库 ID。

  2. 保存: 将修改后的脚本保存在你的离线 ARM 虚拟机上。

  3. 赋执行权限 : 在终端运行 chmod +x check_install_deps.sh

  4. 运行 : 在终端运行 ./check_install_deps.sh

    • 重要 : 因为脚本内部会调用 sudo 来执行安装命令,所以运行脚本本身不需要 sudo,但在执行过程中,系统会提示你输入 sudo 密码(如果需要的话)。
  5. 交互:

    • 脚本会提示你输入包名。

    • 输入你想检查和(如果需要)安装的包名,用空格隔开,然后按 Enter。

    • 脚本会为每个你输入的包名:

      • 显示它的依赖列表。

      • 告诉你它是否已安装。

      • 如果未安装,尝试用 sudo dnf/yum install ... 从你的离线仓库安装它。

      • 报告安装尝试的结果。

    • 最后,脚本会给出一个总结。

相关推荐
牛角上的男孩2 小时前
ubuntu-24.04.2-live-server-arm64基于cloud-init实现分区自动扩容(LVM分区模式)
linux·运维·ubuntu
w23617346012 小时前
Nginx中间件的解析
运维·nginx·中间件
努力努力再努力wz3 小时前
【c++深入系列】:万字string详解(附有sso优化版本的string模拟实现源码)
java·运维·c语言·开发语言·c++
迷迷的k3 小时前
基于 SpringAI 整合 DeepSeek 模型实现 AI 聊天对话
linux·运维·服务器
咸鱼睡不醒_4 小时前
CentOS7系统安装Docker教程
运维·docker·容器
YuSun_WK4 小时前
conda和pip的区别
linux·运维·服务器
华纳云IDC服务商4 小时前
Debian服务器环境下env变量丢失怎么办
运维·服务器·debian
Yang三少喜欢撸铁5 小时前
【通过Docker快速部署Tomcat9.0】
linux·运维·服务器·docker·容器·tomcat
无敌 喵星人5 小时前
ubuntu的各种工具配置
linux·运维·windows
李菠菜5 小时前
iptables限制CentOS互联网访问,仅允许局域网通信
linux·运维·centos