利用Dockerfile构建镜像时无法从互联网下载package的问题解决方法

在macOS的Parallels Desktop运行的Ubuntu虚拟机上,构建Docker镜像时遇到apt-get更新或安装package失败。问题源于DNS配置。解决方案包括:1) 查看macOS的DNS服务器地址;2) 在Ubuntu虚拟机的Docker配置文件中添加主机的DNS地址,取消DOCKER_OPTS注释;3) 使用命令使Docker配置生效,确保启动时使用新DNS设置。

运行环境:macOS,利用parallels Desktop在macOS上运行ubuntu16.04虚拟机,在该虚拟机上运行Docker。

问题介绍:想利用Dockerfile构建一个带有vim的ubuntu镜像时,发现使用apt-get update 或apt-get install 命令时,报如下错误:


             尝试进行更换下载源,问题依然存在,考虑是网络连通性问题。依据前一个解决容器里无法联网问
             题的经验,初步断定是由于DNS地址的设置问题,查阅相关资料发现由于某些学校,企业要求访问其指定的私有DNS服务             器或者所在网络封锁了谷歌8.8.8.8的DNS服务器的访问,导致Docker daemon无法连接互联网并从网上下载安装包。所               以我们要做的事在启动Docker daemon 时为它指定一个指向该私有DNS服务器的地址。

            首先在主机,本环境中即macOS中查看DNS服务器地址,可使用命令

cat /etc/resolv.conf

              然后在虚拟机ubuntu中使用编辑docker daemon的默认配置

xxxxxx@ubuntu ~ $ cat /etc/default/docker
... ...
CKER_OPTS to modify the daemon startup options. DOCKER_
# Use D OOPTS="--dns xx.xx.xx.xx --dns xx.xx.xx.xx --dns 8.8.8.8"
...

               即取消DOCKER_OPTS这一行的注释并在其后加入我们刚刚在主机中查看到的DNS服务器地址。

               注意在该配置文件的注释中我们发现,当使用 service docker restart 命令时,并不会运行这个配置文件,即目前该修                   改无效,使用如下命令,使得重新运行docker时能让我们的配置生效。

xxxxx@ubuntu:~$ sudo mkdir -p /etc/systemd/system/docker.service.d
xxxxx@ubuntu:~$ sudo vi /etc/systemd/system/docker.service.d/Using_Environment_File.conf
[Service]
e is sufficient if DOCKER_OPTS variable does not have to be expanded: #Environm
# This li nentFile=-/etc/default/docker # Use this line to expand DOCKER_OPTS variable:
nt DOCKER_OPTS=\"$DOCKER_OPTS\"" ExecStart= ExecStart=/usr/bin/dockerd -H fd:// $DOCKER_OPTS
ExecStartPre=/bin/sh -c ". /etc/default/docker && /bin/systemctl set-environm
e
         重启docker
systemctl daemon-reload
service docker restart
       重新执行docker build命令,成功。

                       

<think>好的,我现在需要帮用户解决构建Docker镜像出现的GPG公钥缺失导致的签名验证错误。用户提到错误是NO_PUBKEY,涉及Debian Bookworm的InRelease签名未验证。首先,我得回顾用户之前的对话和提供的引用,确保解决方案符合他们的实际情况。 首先,用户之前的问题是关于Debian Bookworm系统中多个GPG密钥缺失的问题,我已经给出了一些解决方案,括安装gnupg、使用循环添加密钥、现代方法替代apt-key等。现在用户在Docker构建过程中遇到类似的问题,需要调整这些方法以适应Dockerfile的环境。 接下来,我需要考虑Dockerfile的特殊性。在Docker构建过程中,不能像在普通系统中那样交互式地运行命令,所以需要确保所有步骤都能在非交互模式下完成。例如,使用apt-get install可能需要加上-y参数,或者处理gpg命令可能需要的额外选项。 用户提供的引用中,引用[2]提到在docker内执行apt update报错,涉及Docker官方仓库的密钥7EA0A9C3F273FCD8,而用户现在的问题是关于Debian Bookworm的InRelease,可能与之前的密钥不同,但解决方法类似。引用[3]显示用户尝试使用apt-key但失败,因为缺少dirmngr,这提示在Docker镜像中可能需要先安装相关的软件,如dirmngr,以确保gpg命令能正常工作。 现在,我需要将之前的解决方案适配到Dockerfile中。可能的步骤括: 1. 确保在Dockerfile中安装必要的工具,如gnupg、dirmngr,因为这些可能在基础镜像中默认未安装。 2. 在运行apt-get update之前,先添加缺失的GPG公钥。 3. 使用适合Docker的非交互式方法,避免提示或用户输入。 4. 根据用户之前的回答,可能需要使用现代的方法,如将密钥放入/etc/apt/keyrings/目录,并在sources.list中引用。 另外,用户提到的错误是NO_PUBKEY,所以需要确定具体的密钥ID。用户的问题中涉及的是Debian Bookworm的仓库,可能需要添加对应的密钥。根据之前的回答,密钥如0E98404D386FA1D9(Docker)、54404762BBB6E853(Debian安全仓库)等,可能需要含这些。 在Dockerfile中,步骤可能如下: - 安装gnupg和dirmngr:因为有些基础镜像可能没有这些工具,导致gpg命令失败。 - 使用gpg --batch --keyserver来获取密钥,避免交互式问题。 - 将密钥导出到适当的位置,如/etc/apt/keyrings/,并在sources.list.d中配置对应的仓库,使用signed-by参数指向密钥文件。 同,要处理多个密钥的情况,可能需要循环添加,或者针对每个缺失的密钥单独处理。例如,在用户提供的错误中,NO_PUBKEY 0E98404D386FA1D9等,需要确保这些密钥都被正确添加。 此外,需要注意Docker镜像的层次结构,尽量合并RUN指令以减少层数,提高构建效率。例如,将安装软件、添加密钥、更新apt等步骤合并到一个RUN指令中,利用&&和换行符来连接命令。 还要考虑缓存问题,有候apt-get update需要与添加密钥分开,或者在添加密钥后立即更新,但需要确保顺序正确。例如,先添加密钥,再执行apt-get update,否则可能仍然无法验证签名。 最后,验证步骤也很重要,在Dockerfile中可能需要检查apt-get update是否成功,或者在构建过程中捕获错误。但通常,如果正确添加了密钥,后续的apt-get install应该能正常工作。 总结,解决方案需要: 1. 安装必要的工具(gnupg, dirmngr)。 2. 非交互式获取并添加缺失的GPG密钥。 3. 配置APT源,使用signed-by指向密钥文件。 4. 更新列表并安装所需软件。</think>### Dockerfile构建解决GPG密钥缺失的完整方案 #### 技术原理 Docker镜像构建过程中出现`NO_PUBKEY`错误,是由于APT仓库的GPG公钥未正确导入。签名验证流程采用$RSA/SHA256$算法,密钥长度$4096-bit$,密钥指纹通过OpenPGP证书传递[^1]。传统`apt-key`命令在容器环境中易出现依赖缺失问题[^3]。 --- ### 分步解决方案 #### 1. 基础镜像优化(Dockerfile) ```dockerfile FROM debian:bookworm # 安装必要组件(必须含dirmngr) RUN apt-get update && apt-get install -y --no-install-recommends \ gnupg2 \ dirmngr \ ca-certificates \ && rm -rf /var/lib/apt/lists/* ``` #### 2. 密钥注入方法(推荐方案) ```dockerfile # 使用现代密钥管理方式(Debian 11+标准) RUN mkdir -p /etc/apt/keyrings \ && gpg --batch --keyserver hkps://keyserver.ubuntu.com --recv-keys 0E98404D386FA1D9 54404762BBB6E853 BDE6D2B9216EC7A8 \ && gpg --batch --yes --output /etc/apt/keyrings/debian-bookworm.gpg --export 0E98404D386FA1D9 \ && gpg --batch --yes --output /etc/apt/keyrings/debian-security.gpg --export 54404762BBB6E853 BDE6D2B9216EC7A8 # 配置APT源(带signed-by参数) RUN echo "deb [signed-by=/etc/apt/keyrings/debian-bookworm.gpg] http://deb.debian.org/debian bookworm main" > /etc/apt/sources.list \ && echo "deb [signed-by=/etc/apt/keyrings/debian-security.gpg] http://deb.debian.org/debian-security bookworm-security main" >> /etc/apt/sources.list ``` #### 3. 构建验证步骤 ```dockerfile # 强制更新软件源 RUN apt-get update -o Acquire::AllowInsecureRepositories=false \ && apt-get install -y your-package ``` --- ### 关键技术解析 1. **密钥获取优化**: - `--batch`参数消除交互提示 - `hkps://`协议强制加密连接 - 多密钥合并导出减少文件数量 2. **安全强化配置**: ```dockerfile # 禁用不安全仓库 RUN echo 'APT::Get::AllowUnauthenticated "false";' > /etc/apt/apt.conf.d/99verify ``` 3. **Docker构建缓存处理**: ```bash # 若需强制刷新密钥,构建添加--no-cache docker build --no-cache -t your-image . ``` --- ### 异常处理指南 | 错误类型 | 解决方案 | |-----------------------------|------------------------------------------------------------------------| | `gpg: keyserver receive failed` | 增加`--keyserver hkp://pgp.mit.edu:80`备用服务器 | | `NO_PUBKEY`残留 | 执行`RUN rm -rf /var/lib/apt/lists/*`清除缓存后再试 | | 证书过期 | 更新基础镜像:`FROM debian:bookworm-20240515`(带最新安全补丁) | --- ### 安全最佳实践 1. 密钥指纹验证示例: ```dockerfile RUN echo "0E98404D386FA1D9:6D67 DC44 3B8D A34D 41F2 C3E9 0E98 404D 386F A1D9" | gpg --verify-fingerprint ``` 2. 最小化密钥范围: ```dockerfile # 仅对特定仓库授权 RUN echo "deb [signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable" > /etc/apt/sources.list.d/docker.list ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值