yum 依赖项解析在 docker 构建与 docker 运行 中表现不同

yum dependency resolution behaves differently in docker build vs docker run

看来 yum 的依赖项解析行为不同,具体取决于它是从 Dockerfile 的 RUN 语句调用,还是从 docker run.

调用

考虑这个 Dockerfile:

FROM themattrix/centos5-vault-i386
RUN rpm -i http://www.tuxad.com/rpms/tuxad-release-5-1.noarch.rpm
RUN yum update -y

docker 构建在最后一个命令上失败。完整的输出包含在下面,但基本上 yum 会为 i386 和 x86_64.

选择软件包

但是 运行使用 docker run 中的相同命令有效!没有选择 x86_64 的包。

docker run --rm themattrix/centos5-vault-i386 sh -c "
    rpm -i http://www.tuxad.com/rpms/tuxad-release-5-1.noarch.rpm &&
    yum update -y"

什么可以解释这种奇怪的行为?

以及如何获取要构建的 Dockerfile?

环境

$ uname -srmp
Darwin 17.7.0 x86_64 i386

$ docker -v
Docker version 18.09.2, build 6247962

docker 构建的输出

$ docker build .
Sending build context to Docker daemon  6.656kB
Step 1/3 : FROM themattrix/centos5-vault-i386
 ---> 5706f03d3346
Step 2/3 : RUN rpm -i http://www.tuxad.com/rpms/tuxad-release-5-1.noarch.rpm
 ---> Using cache
 ---> ee89f27432c1
Step 3/3 : RUN yum update -y
 ---> Running in 19e822b9dccc
Loaded plugins: fastestmirror
Determining fastest mirrors
 * epel: ftp-stud.hs-esslingen.de
Reducing CentOS-5 - libselinux to included packages only
Finished
Setting up Update Process
Resolving Dependencies
--> Running transaction check
--> Processing Dependency: libselinux = 1.33.4-5.7.el5 for package: libselinux-python
--> Processing Dependency: libselinux = 1.33.4-5.7.el5 for package: libselinux-utils
---> Package libselinux.i386 0:1.33.4-5.7.el5.centos set to be updated
---> Package libselinux-devel.i386 0:1.33.4-5.7.el5.centos set to be updated
---> Package tuxad-release.noarch 0:5-7 set to be updated
--> Running transaction check
---> Package libselinux.x86_64 0:1.33.4-5.7.el5 set to be updated
--> Processing Dependency: libc.so.6(GLIBC_2.2.5)(64bit) for package: libselinux
--> Processing Dependency: ld-linux-x86-64.so.2(GLIBC_2.3)(64bit) for package: libselinux
--> Processing Dependency: ld-linux-x86-64.so.2()(64bit) for package: libselinux
--> Processing Dependency: libc.so.6(GLIBC_2.3)(64bit) for package: libselinux
--> Processing Dependency: libc.so.6(GLIBC_2.4)(64bit) for package: libselinux
--> Processing Dependency: libc.so.6(GLIBC_2.3.4)(64bit) for package: libselinux
--> Processing Dependency: libdl.so.2()(64bit) for package: libselinux
--> Processing Dependency: libc.so.6()(64bit) for package: libselinux
--> Processing Dependency: libsepol.so.1()(64bit) for package: libselinux
--> Running transaction check
---> Package glibc.x86_64 0:2.5-123.el5_11.3 set to be updated
---> Package libsepol.x86_64 0:1.15.2-3.el5 set to be updated
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package              Arch       Version                   Repository      Size
================================================================================
Updating:
 libselinux           i386       1.33.4-5.7.el5.centos     libselinux      77 k
 libselinux-devel     i386       1.33.4-5.7.el5.centos     libselinux     144 k
 tuxad-release        noarch     5-7                       tuxad           13 k
Installing for dependencies:
 glibc                x86_64     2.5-123.el5_11.3          updates        4.8 M
 libselinux           x86_64     1.33.4-5.7.el5            base            78 k
 libsepol             x86_64     1.15.2-3.el5              base           131 k

Transaction Summary
================================================================================
Install       3 Package(s)
Upgrade       3 Package(s)

Total download size: 5.2 M
Downloading Packages:
--------------------------------------------------------------------------------
Total                                           925 kB/s | 5.2 MB     00:05
warning: rpmts_HdrFromFdno: Header V3 DSA signature: NOKEY, key ID a95f6f37
Importing GPG key 0xA95F6F37 "Frank W. Bergmann (tuxad.com) <gpg20160322@tuxad.com>" from /etc/pki/rpm-gpg/RPM-GPG-KEY-TUXAD-A95F6F37
Running rpm_check_debug
ERROR with rpm_check_debug vs depsolve:
libselinux is needed by (installed) libselinux-utils-1.33.4-5.7.el5.i386
libselinux is needed by (installed) libselinux-python-1.33.4-5.7.el5.i386
Complete!
(1, [u'Please report this error in http://bugs.centos.org/yum5bug'])
The command '/bin/sh -c yum update -y' returned a non-zero code: 1

来自docker的输出运行

$ docker run --rm themattrix/centos5-vault-i386 sh -c "rpm -i http://www.tuxad.com/rpms/tuxad-release-5-1.noarch.rpm && yum update -y"
warning: /var/tmp/rpm-xfer.ZSEYyZ: Header V3 DSA signature: NOKEY, key ID a95f6f37
Loaded plugins: fastestmirror
Determining fastest mirrors
 * epel: ftp-stud.hs-esslingen.de
Reducing CentOS-5 - libselinux to included packages only
Finished
Setting up Update Process
Resolving Dependencies
--> Running transaction check
---> Package curl.i386 0:7.15.5-17.el5_11.1 set to be updated
--> Processing Dependency: libcrypto.so.10(OPENSSL_1.0.1) for package: curl
--> Processing Dependency: libssl.so.10 for package: curl
--> Processing Dependency: libcrypto.so.10(libcrypto.so.10) for package: curl
--> Processing Dependency: libcrypto.so.10 for package: curl
--> Processing Dependency: libssl.so.10(libssl.so.10) for package: curl
---> Package kernel-headers.i386 0:2.6.18-419.el5 set to be updated
---> Package libselinux.i386 0:1.33.4-5.7.el5.centos set to be updated
---> Package libselinux-devel.i386 0:1.33.4-5.7.el5.centos set to be updated
---> Package libselinux-python.i386 0:1.33.4-5.7.el5.centos set to be updated
---> Package libselinux-utils.i386 0:1.33.4-5.7.el5.centos set to be updated
---> Package openldap.i386 0:2.3.43-29.el5_11.openssl1 set to be updated
---> Package openssl.i686 0:0.9.8e-40.el5_11.1 set to be updated
---> Package openssl-devel.i386 0:0.9.8e-40.el5_11.1 set to be updated
---> Package tuxad-release.noarch 0:5-7 set to be updated
---> Package tzdata.i386 0:2017b-1.el5 set to be updated
---> Package wget.i386 0:1.11.4-3.el5_11.2.1 set to be updated
--> Running transaction check
---> Package openssl1.i686 0:1.0.1e-57.1.el5_11 set to be updated
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package             Arch     Version                        Repository    Size
================================================================================
Updating:
 curl                i386     7.15.5-17.el5_11.1             tuxad        893 k
 kernel-headers      i386     2.6.18-419.el5                 updates      1.5 M
 libselinux          i386     1.33.4-5.7.el5.centos          libselinux    77 k
 libselinux-devel    i386     1.33.4-5.7.el5.centos          libselinux   144 k
 libselinux-python   i386     1.33.4-5.7.el5.centos          libselinux    73 k
 libselinux-utils    i386     1.33.4-5.7.el5.centos          libselinux    55 k
 openldap            i386     2.3.43-29.el5_11.openssl1      tuxad        717 k
 openssl             i686     0.9.8e-40.el5_11.1             tuxad        2.9 M
 openssl-devel       i386     0.9.8e-40.el5_11.1             tuxad        1.9 M
 tuxad-release       noarch   5-7                            tuxad         13 k
 tzdata              i386     2017b-1.el5                    updates      757 k
 wget                i386     1.11.4-3.el5_11.2.1            tuxad        593 k
Installing for dependencies:
 openssl1            i686     1.0.1e-57.1.el5_11             tuxad        3.5 M

Transaction Summary
================================================================================
Install       1 Package(s)
Upgrade      12 Package(s)

Total download size: 13 M
Downloading Packages:
--------------------------------------------------------------------------------
Total                                           1.4 MB/s |  13 MB     00:09
warning: rpmts_HdrFromFdno: Header V3 DSA signature: NOKEY, key ID a95f6f37
Importing GPG key 0xA95F6F37 "Frank W. Bergmann (tuxad.com) <gpg20160322@tuxad.com>" from /etc/pki/rpm-gpg/RPM-GPG-KEY-TUXAD-A95F6F37
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
  Updating       : openssl                                                 1/25
  Updating       : libselinux                                              2/25
  Updating       : libselinux-devel                                        3/25
  Updating       : openssl-devel                                           4/25
  Updating       : tzdata                                                  5/25
  Updating       : kernel-headers                                          6/25
  Updating       : tuxad-release                                           7/25
  Installing     : openssl1                                                8/25
  Updating       : openldap                                                9/25
  Updating       : curl                                                   10/25
  Updating       : wget                                                   11/25
  Updating       : libselinux-utils                                       12/25
  Updating       : libselinux-python                                      13/25
  Cleanup        : libselinux                                             14/25
  Cleanup        : tuxad-release                                          15/25
  Cleanup        : wget                                                   16/25
  Cleanup        : libselinux-devel                                       17/25
  Cleanup        : openssl-devel                                          18/25
  Cleanup        : kernel-headers                                         19/25
  Cleanup        : tzdata                                                 20/25
  Cleanup        : libselinux-utils                                       21/25
  Cleanup        : openldap                                               22/25
  Cleanup        : curl                                                   23/25
  Cleanup        : libselinux-python                                      24/25
  Cleanup        : openssl                                                25/25

Dependency Installed:
  openssl1.i686 0:1.0.1e-57.1.el5_11

Updated:
  curl.i386 0:7.15.5-17.el5_11.1
  kernel-headers.i386 0:2.6.18-419.el5
  libselinux.i386 0:1.33.4-5.7.el5.centos
  libselinux-devel.i386 0:1.33.4-5.7.el5.centos
  libselinux-python.i386 0:1.33.4-5.7.el5.centos
  libselinux-utils.i386 0:1.33.4-5.7.el5.centos
  openldap.i386 0:2.3.43-29.el5_11.openssl1
  openssl.i686 0:0.9.8e-40.el5_11.1
  openssl-devel.i386 0:0.9.8e-40.el5_11.1
  tuxad-release.noarch 0:5-7
  tzdata.i386 0:2017b-1.el5
  wget.i386 0:1.11.4-3.el5_11.2.1

Complete!

原因是包管理器依赖内核提供的信息(通过uname(2))来决定应该安装哪个版本的包(针对哪个目标体系结构)。尽管您的基本映像内部有 i386 环境,但您仍然 运行 在 x86_64 内核上构建,所以事情变得有点棘手。

当您 运行 使用 docker run 的容器时,您会通过入口点 linux32 - 一个要求内核 假装 它 运行 在 i386 硬件上。然而,当你 运行 docker build 时,RUNs 没有使用入口点,所以 yum 看到它 运行s 在 x86_64 内核上,因此平台混乱。您可以查看以获得更详细的解释;问题很相似。

要正确构建映像(仅安装 i386 包),运行 yumlinux32 下的 RUN 中的其他架构敏感命令, 例如:

RUN linux32 yum update -y