为了避免 XY 问题,让我先描述一下情况。
我们有一个客户项目,情况非常特殊。我们有一个相对现代的软件堆栈(Keras DNN 东西),需要在客户的系统上运行。该系统是 Cloudera CentOS 6 集群,处于生产状态,出于安全考虑,已设置隔离。我们无法保证这个东西曾经见过互联网。
我们开发了一个 bash 脚本,使用 RPM 从磁盘安装所需的软件包,并在我们本地的模拟(容器化)集群上进行了测试(YUM 失败,因为 repo 数据库不是最新的)。经过一番调整,我们能够在没有来自互联网的数据包的情况下运行 Keras。
客户设置了自己的虚拟化系统,该系统应该非常接近实际集群(就配置而言)。然而,当他运行它时,却出现了完全的灾难。出现了很多错误,例如:
(通过 安装 glibc-common-2.12 及相关软件
sudo rpm -Uvh glibc-common-2.12-1.209.el6_9.1.x86_64.rpm glibc-2.12-1.209.el6_9.1.x86_64.rpm glibc-headers-2.12-1.209.el6_9.1.x86_64.rpm glibc-devel-2.12-1.209.el6_9.1.x86_64.rpm
)
warning: ./rpm/glibc-common-2.12-1.209.el6_9.1.x86_64.rpm: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY
error: Failed dependencies
tzdata >= 2015g-4 is needed by glibc-common-2.12-1.209.el6_9.1.x86_64.rpm
libc.so.6(GLIBC_2.13)(64bit) is needed by (installed) util-linux-2.23.2-26.el7.x86_64
libc.so.6(GLIBC_2.13)(64bit) is needed by (installed) systemd-219-19.el7.x86_64
...(more of the same)...
libc.so.6(GLIBC_2.13)(64bit) is needed by (installed) xz-libs-5.1.2-12alpha.el17.x86_64
(或者运行命令sudo rpm -Uvh gcc-c++-4.4.7-18.el6.x86_64.rpm gcc-4.4.7-18.el6.x86_64.rpm libstdc++-4.4.7-18.el6.x86_64.rpm libstdc++-devel-4.4.7-18.el6.x86_64.rpm
:)
libstdc++.so.6(GLIBCXX_3.4.15)(64bit) is needed by (installed) {name of a package}
libstdc++.so.6(GLIBCXX_3.4.15)(64bit) is needed by (installed) {name of another package}
...
Y 需要 X 是最常见的错误,但我们也看到类似的错误
openssl < 1:1.0.1-0.3.beta3 is obsoleted by (installed) openssl-libs-1:1.0.1e-42.el4.9x86_64
和
file /etc/rpm/macros.ghc-srpm from install of epel-release-6-8.noarch conflicts with file from package redhad-rpm-config-9.1.0-68.el7.centos.noarch
尤其是许多冲突都源于
- libc.so.6
- 库文件.so.6
- 库文件.so.3
- 库文件.so.4
- 库.so.6
- libffi.so.6
这些都是非常关键的库,并且我 1)不能假设任何特定版本都会在集群上,并且 2)不能随意修改,以免其中一个出现故障。
我更擅长机器学习,我的 Linux 技能足以设置和维护 CUDA 盒等,但这对我来说开始变得很困难,因此任何意见,即使是简单的东西,也值得赞赏。有没有办法创建一个单独的库环境,我们可以在其中安装必要的依赖项而不会干扰已经存在的依赖项?我知道这chroot
是一回事,但我不知道如何正确使用它。
tl;dr - 在没有远程管理能力的隔离系统上存在依赖地狱,并且系统结构老旧、维护不善。
非常感谢!
答案1
我必须经常在隔离环境中工作。
到目前为止我发现的最佳方法是拥有一个具有完全相同环境的虚拟机(即,所有软件包的版本完全相同,如果可能的话,其安装遵循与生产环境相同的过程) - 让该虚拟机访问互联网,并使用适当的包管理器仅下载所有必需的包。
为了仅下载软件包而不安装它们,我使用:
yum install --downloadonly <requiredpackage>
至少在 CentOS 6 上,此功能开箱即用 - 在其他基于 RPM 的发行版中,您可能需要安装yum-downloadonly包,因为此功能是由 yum 插件提供的。
然后,我将所有下载的包存档到一个 .tar.gz 文件中,将该存档传输到生产系统,在临时目录中解压缩并使用以下命令安装包:
rpm -i <directory>/*.rpm
使用小版本而不是仅使用主要 CentOS 版本或 /etc/yum.repos.d/*.repo 配置文件中的“$releaseversion”变量也很重要,因为具有主要版本的存储库会随时间更新。此小版本应与用于下载的 VM 和隔离系统上安装的版本相匹配。
例如,使用:
http://mirror.centos.org/centos/7.7.1908/os/x86_64/
代替
http://mirror.centos.org/centos/7/os/x86_64/
因为后者将有软件包更新,直到 CentOS 7 维护结束(2020 年 11 月 30 日 - 根据CentOS 常见问题) 。
根据您的描述,您提到的虚拟机似乎已经从 CentOS 存储库以某种方式更新,因此您遇到了一些版本依赖冲突。
希望这可以帮助。