当前位置: 首页>>技术教程>>正文


在Docker中,apt-get安装失败,出现“无法获取http://archive.ubuntu.com/… 404 Not Found”错误。为什么?我们怎样才能超越它?

,

问题描述

我的团队使用Docker(带有ubuntu:14.04基本映像)进行本地开发,我们经常需要重建部分或全部图像。但是,即使在运行apt-get -y update之后,我们也常常无法使用apt-get install下载软件包。例如,今天我看到了

Err http://archive.ubuntu.com/ubuntu/ trusty-security/main libxml2 amd64 2.9.1+dfsg1-3ubuntu4.7
  404  Not Found [IP: 91.189.88.161 80]
Err http://archive.ubuntu.com/ubuntu/ trusty-security/main libxml2-dev amd64 2.9.1+dfsg1-3ubuntu4.7
  404  Not Found [IP: 91.189.88.161 80]
Fetched 84.7 MB in 1min 6s (1281 kB/s)
Unable to correct missing packages.
E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/libx/libxml2/libxml2_2.9.1+dfsg1-3ubuntu4.7_amd64.deb  404  Not Found [IP: 91.189.88.161 80]

E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/libx/libxml2/libxml2-dev_2.9.1+dfsg1-3ubuntu4.7_amd64.deb  404  Not Found [IP: 91.189.88.161 80]

E: Aborting install.

显然,特定软件包的特定版本已从存档中删除,并替换为名称略有不同的修补程序版本。例如,上面的错误是查找libxml2_2.9.1+dfsg1-3ubuntu4.7_amd64.deb,但服务器上的版本是libxml2_2.9.1+dfsg1-3ubuntu4.8_amd64.deb

通常这可以通过删除基本图像(docker rmi ubuntu:14.04)和重建来解决;新下载的ubuntu映像具有正确的修补程序编号,并找到正确的存档文件。但即使这并不总是有效 – 可能是由于新的次要升级到Ubuntu的依赖数据库和将新的ubuntu:14.04映像部署到Docker Hub之间的延迟。

我们尝试过使用apt-get标记--fix-missing--fix-broken,但这些标记并不能始终如一。

还有其他想法吗?

apt-get install fails with Not Found error because package removed from repository是一个类似的问题,但接受的答案是不可接受的,因为它不可能自动化。我们的日常开发过程,包括自动构建和部署,都是使用Docker编写脚本的,每次特定存档丢失时(在几小时或几天后删除hack),在Dockerfile内部进行黑客攻击是不切实际的。


在回复@ prateek05时,这是来自官方ubuntu:14.04泊坞窗图像的/etc/apt/sources.list

root@72daa1942714:/# cat /etc/apt/sources.list
# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.

deb http://archive.ubuntu.com/ubuntu/ trusty main restricted
deb-src http://archive.ubuntu.com/ubuntu/ trusty main restricted

## Major bug fix updates produced after the final release of the
## distribution.
deb http://archive.ubuntu.com/ubuntu/ trusty-updates main restricted
deb-src http://archive.ubuntu.com/ubuntu/ trusty-updates main restricted

## Uncomment the following two lines to add software from the 'universe'
## repository.
## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team. Also, please note that software in universe WILL NOT receive any
## review or updates from the Ubuntu security team.
deb http://archive.ubuntu.com/ubuntu/ trusty universe
deb-src http://archive.ubuntu.com/ubuntu/ trusty universe
deb http://archive.ubuntu.com/ubuntu/ trusty-updates universe
deb-src http://archive.ubuntu.com/ubuntu/ trusty-updates universe

## N.B. software from this repository may not have been tested as
## extensively as that contained in the main release, although it includes
## newer versions of some applications which may provide useful features.
## Also, please note that software in backports WILL NOT receive any review
## or updates from the Ubuntu security team.
# deb http://archive.ubuntu.com/ubuntu/ trusty-backports main restricted
# deb-src http://archive.ubuntu.com/ubuntu/ trusty-backports main restricted

deb http://archive.ubuntu.com/ubuntu/ trusty-security main restricted
deb-src http://archive.ubuntu.com/ubuntu/ trusty-security main restricted
deb http://archive.ubuntu.com/ubuntu/ trusty-security universe
deb-src http://archive.ubuntu.com/ubuntu/ trusty-security universe
# deb http://archive.ubuntu.com/ubuntu/ trusty-security multiverse
# deb-src http://archive.ubuntu.com/ubuntu/ trusty-security multiverse

最佳解决方法

您已声明您的Dockerfile包含RUN apt-get -y update作为其自己的RUN指令。但是,由于build caching,如果Dockerfile的所有更改都发生在文件的后面,那么当运行docker build时,Docker将重用上次执行RUN apt-get -y update时创建的中间映像,而不是再次运行命令,因此任何recently-added或编辑的apt-get install行将使用旧数据,导致您观察到的错误。

有两种方法可以解决这个问题:

  1. --no-cache选项传递给docker build,强制每次构建映像时都运行Dockerfile中的每个语句。

  2. 重写Dockerfile以在单个RUN指令中组合apt-get命令:RUN apt-get update && apt-get install foo bar ...。这样,每当编辑要安装的软件包列表时,docker build将被强制为re-execute整个RUN指令,因此在安装之前重新运行apt-get update

Dockerfile best practices page实际上有一个关于Dockerfiles中apt-get命令的整个部分。我建议你看看。

次佳解决方法

这个问题可能与ubuntu来源有关

检查/etc/apt/sources.list

如果你看到deb http://archive.ubuntu.com/ubuntu main universe restricted multiverse,那可能是潜在的问题。

通过将其替换为deb http://archive.ubuntu.com/ubuntu/ trusty main universe restricted multiverse来解决此问题

或者它可能是镜像本身没有响应。 archive.ubuntu.com

Name:   archive.ubuntu.com
Address: 91.189.88.152
Name:   archive.ubuntu.com
Address: 91.189.88.161
Name:   archive.ubuntu.com
Address: 91.189.88.149

将archive.ubuntu.com替换为更值得信赖的镜像us.archive.ubuntu.com

Name:   us.archive.ubuntu.com
Address: 91.189.91.23
Name:   us.archive.ubuntu.com
Address: 91.189.91.26

(由原始提问者编辑):

谢谢,prateek05!我的Dockerfile现在启动:

FROM ubuntu:14.04
RUN sed -i'' 's/archive\.ubuntu\.com/us\.archive\.ubuntu\.com/' /etc/apt/sources.list
RUN apt-get -y update

它似乎工作。但由于这是一个零星的问题,只有时间会告诉……

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/6721.html,未经允许,请勿转载。