我正在尝试将我们的一个docker基础映像升级到Ubuntu的最新稳定版本。我已经将这个问题孤立到一个简单的可重复的案例中。我有一个像这样的Dockerfile:
FROM ubuntu:22.04
MAINTAINER mep-dev@zulily.com
# Install java and clean-up
RUN apt-get update
当我在本地机器上构建它时,我没有任何问题。然而,当我在CICD上构建它时,有时会出现以下错误:
步骤3/3:运行apt-get更新
--->在6ca01b60de64中运行
获取:1http://archive.ubuntu.com/ubuntujammy InRelease[270 kB]
获取:2http://security.ubuntu.com/ubuntujammy security InRelease[110 kB]
获取:3http://archive.ubuntu.com/ubuntujammy更新InRelease[109 kB]
获取:4http://archive.ubuntu.com/ubuntujammy后台端口InRelease[99.8 kB]
错误:1http://archive.ubuntu.com/ubuntujammy InRelease
由于公钥不可用,无法验证以下签名:NO_PUBKEY 871920D1991BC93C
错误:3http://archive.ubuntu.com/ubuntujammy更新InRelease
由于公钥不可用,无法验证以下签名:NO_PUBKEY 871920D1991BC93C
错误:4http://archive.ubuntu.com/ubuntujammy backports InRelease
由于公钥不可用,无法验证以下签名:NO_PUBKEY 871920D1991BC93C
错误:2http://security.ubuntu.com/ubuntujammy security InRelease
由于公钥不可用,无法验证以下签名:NO_PUBKEY 871920D1991BC93C
正在读取包列表
W:http://archive.ubuntu.com/ubuntu/dists/jammy/InRelease:keyring/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-dimage.gpg中的密钥被忽略,因为执行apt-key的用户"_apt"无法读取该文件
W:http://archive.ubuntu.com/ubuntu/dists/jammy/InRelease:keyring/etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg中的密钥被忽略,因为执行apt-key的用户"_apt"无法读取该文件
W:GPG错误:http://archive.ubuntu.com/ubuntujammy InRelease:由于公钥不可用,无法验证以下签名:NO_PUBKEY 871920D1991BC93C
E:存储库'http://archive.ubuntu.com/ubuntu"jammy InRelease"未签名
W:http://archive.ubuntu.com/ubuntu/dists/jammy-updates/InRelease:keyring/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-dimage.gpg中的密钥被忽略,因为执行apt-key的用户"_apt"无法读取该文件
W:http://archive.ubuntu.com/ubuntu/dists/jammy-updates/InRelease:keyring/etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg中的密钥被忽略,因为执行apt-key的用户"_apt"无法读取该文件
W:GPG错误:http://archive.ubuntu.com/ubuntujammy更新InRelease:由于公钥不可用,无法验证以下签名:NO_PUBKEY 871920D1991BC93C
E:存储库'http://archive.ubuntu.com/ubuntu"jammy updates InRelease"未签名
W:http://archive.ubuntu.com/ubuntu/dists/jammy-backports/InRelease:keyring/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-dimage.gpg中的密钥被忽略,因为执行apt-key的用户"_apt"无法读取该文件
W:http://archive.ubuntu.com/ubuntu/dists/jammy-backports/InRelease:keyring/etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg中的密钥被忽略,因为执行apt-key的用户"_apt"无法读取该文件
W:GPG错误:http://archive.ubuntu.com/ubuntujammy backports InRelease:由于公钥不可用,无法验证以下签名:NO_PUBKEY 871920D1991BC93C
E:存储库'http://archive.ubuntu.com/ubuntujammy backports InRelease未签名
W:http://security.ubuntu.com/ubuntu/dists/jammy-security/InRelease:keyring/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-dimage.gpg中的密钥被忽略,因为执行apt-key的用户"_apt"无法读取该文件
W:http://security.ubuntu.com/ubuntu/dists/jammy-security/InRelease:keyring/etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg中的密钥被忽略,因为执行apt-key的用户"_apt"无法读取该文件
W:GPG错误:http://security.ubuntu.com/ubuntujammy security InRelease:由于公钥不可用,无法验证以下签名:NO_PUBKEY 871920D1991BC93C
E:存储库'http://security.ubuntu.com/ubuntu"jammy security InRelease"未签名
E:执行脚本时出现问题APT::Update::Post Invoke'rm-f/var/cache/APT/archives/.deb/var/cache/APT/aArchives/partial/.deb/var/cache-APT/*.bin||true'
E:子进程返回错误代码
命令'/bin/sh-c APT-get-Update'返回非零代码:100
如果我注释掉RUN apt-get update
,那么它成功了,我可以进入容器,看到/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-cdimage.gpg
和/etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg
确实存在,并且已经读取了所有权限:
root@b778220b39d8:/#ls-l/etc/apt/ctrusted.gpg.d
总计8
-rw-r-1根根目录2794 2021年3月26日ubuntu-keyring-2012-dimage.gpg
-rw-r--1根目录1733 2021年3日ubuntu-keyring-2018-archive.gpg
我还检查了父目录,它们至少都有r-x。
这个答案可能是相关的,但当基本映像在一个环境中使用而不是在另一个环境下使用时,为什么文件会有正确的结构?
更新:
通过使用--pull
,我可以看到它使用的确切图像。
$docker构建--pull-t$EMAIL_DELIVERABILITY_ARN
步骤1/3:从ubuntu:22.04
22.04:从库中提取/uuntu
摘要:sha256:b6b83d3c331794420340093eb706a6f152d9c1fa51b262d9bf34594887c2c7ac
状态:已下载ubuntu的新映像:22.04
--->27941809078c
这与我在本地构建时看到的sha和image id相同,这很有效。
我对ubuntu没有同样的问题:20.04。
花了半天时间修复Ubuntu映像(这些映像没有损坏)后,我终于开始调试主机了。
这是一个docker
问题。Ubuntu使用系统调用来获得更好的密钥安全性,而Docker还不支持这一点解决方案是更新docker。。。或者使用nerdctl、runc或类似的东西。
apt
没有得到系统调用不受支持的消息,而是得到权限被拒绝的消息,这导致了令人困惑的错误消息
从技术上讲,你可以对ubuntu进行补丁,以降低安全性,并与旧的docker合作,但遗憾的是,这不是一个长期的解决方案。
这是在Docker(/moby)项目中修复它的PR。请注意,这个问题也可能发生在其他Docker映像(或Ubuntu中的其他软件)中,因为它最终是由glibc中的一个更改引起的,该更改与Docker的默认seccomp配置文件不兼容。
对于一些docker黑客攻击来说,一个非常肮脏但可能可以接受的黑客攻击是:
apt update --allow-insecure-repositories
它只是忽略了签名。错误仍然会打印出来,但软件包存储库会更新,之后您可以安装新的软件包。即使你被警告并被问到这是否真的是你想做的。
完全相同的问题
错误:3http://security.ubuntu.com/ubuntu干扰安全InRelease由于公钥不可用,无法验证以下签名:NO_PUBKEY 871920D1991BC93C正在读取程序包列表。。。[91mW:http://archive.ubuntu.com/ubuntu/dists/jammy/InRelease:keyring/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-dimage.gpg中的密钥被忽略,因为执行apt-key的用户"_apt"无法读取该文件。
Dockerfile(简单的复制方法)docker版本:18.x或19.03/
FROM ubuntu:latest
RUN apt-get -y update
对于最新的Docker版本20.10.9,我没有看到这个问题。
尝试tshoot的一些选项:
- sed-i的/jamy/focus/g'/etc/apt/sources.list
- 运行apt-key adv--keyserver keyserver.ubuntu.com--recv keys 871920D1991BC93C在另一个子问题上失败gnupg、gnupg2和gnupg1似乎没有安装,但此操作需要其中一个
SO,解决方案似乎要么是更新docker版本,要么是使用以前使用过的标记图像。
当您按名称引用docker映像时,docker只检查它是否在本地存在,而不检查更新。因此,如果已经有可用的命名映像版本,即使它可能已经过时,它也会使用它。我怀疑这就是您所看到的:您的一些CI节点必须具有存在问题的映像的缓存版本。
有几种方法可以解决这个问题:
-
在调用
docker run
之前显式docker pull ubuntu:22.04
;这将拉下一个新版本的图像(如果有的话)。 -
将
--pull always
添加到docker run
命令行中。这完成了同样的事情,但不需要额外的命令执行。 -
通过摘要而不是标记引用图像。如果你使用这样的图像参考:
FROM ubuntu@sha256:bace9fb0d5923a675c894d5c815da75ffe35e24970166a48a4460a48ae6e0d19
然后docker将使用精确的图像。你可以在docker hub上找到图片摘要。