docker 即使使用简单的命令构建也很慢

docker build is very slow even with simple commands

我正在 Raspberry Pi 上构建一个 docker 图像,这当然需要一些时间。这里的问题是,即使是 Dockerfile 中非常简单的命令,如设置环境变量、在单个文件上使用 chmod +x 或公开端口 80 也需要几分钟才能完成。

这是我的 Dockerfile 的摘录:

FROM resin/rpi-raspbian
MAINTAINER felixbr <mymail@redacted.com>

RUN export DEBIAN_FRONTEND=noninteractive && apt-get update && apt-get install -y python python-dev python-pip python-numpy python-scipy python-mysqldb mysql-server redis-server nginx dos2unix poppler-utils

COPY requirements.txt /app/

RUN pip install -r /app/requirements.txt

COPY . /app

WORKDIR /app

RUN cp /app/nginx-django.cfg /etc/nginx/sites-enabled/default
RUN chmod +x /app/start.sh

ENV DOCKERIZED="true"

CMD ./start.sh

EXPOSE 80

请记住,这是使用 ARMv6 基础映像,因此它可以 运行 在 Raspberry Pi 上,我使用的是 docker 1.5.0 构建用于骗子 Raspberry Pi OS.

它是在为每个命令复制构建层还是为什么最后几个命令中的每一个都需要几分钟才能完成?

Dockerfile 的每条指令都将 运行 放在一个容器中。这意味着对于每条指令,它将执行以下操作:

  • 从上一步创建的图像实例化一个容器,这将创建一个新层(R/W 层)
  • 执行操作(pip 安装等)
  • 提交,这会将顶层复制为图像层(我很确定它正在复制该层)
  • 并移除容器(如果指定了--rm选项)(因此,移除容器Read/Write层)

涉及一些 I/O 操作。在 SSD 上它真的很快,在一个好的硬盘驱动器上也是如此。当你在 Raspberry PI 上构建它时,如果你在 SD 卡(或 MicroSD)上构建它,SD 卡的性能可能不是那么好。这将取决于您的 MicroSD class,即便如此,我认为这对卡来说也不是很好。我尝试了一个简单的节点项目,它确实花了几分钟,而不是像在我的笔记本电脑上那样需要几秒钟。它与硬件相关(主要是 I/O 用于 SD 卡,可能有一点 CPU,但是...)。

您可能想尝试使用连接到 raspberry Pi 的外部硬盘驱动器并将 docker 文件夹移动到那里,看看性能是否更好。

这是一个老问题,但仅供参考,您可能一直在为选择的存储驱动程序而苦恼。

在 Ubuntu/Debian 上,Docker 默认使用 AUFS 存储驱动程序,速度相当快。 在其他发行版上,Docker 默认使用 devicemapper 存储驱动程序,这在默认配置下非常慢(由于 "loop-lvm" 模式,默认配置,不推荐用于生产)。

查看本指南以供参考,了解如何在生产环境中配置 devicemapper 存储驱动程序(无循环模式):https://docs.docker.com/engine/userguide/storagedriver/device-mapper-driver/

此处未提及的另一个注意事项是,在 armv7 上,您可能希望使用 pip 或 apt-get 安装的大多数软件包未打包为二进制文件。

这意味着在 amd64 架构上,pip install 下载一个二进制文件,它只是将它复制到正确的位置,但在 armv7 上,它找不到合适的二进制文件,而是下载源代码并将需要从头开始构建它。

当你有一个包含很多依赖项的包,并且需要从源代码构建它们时,这会花费很长时间。

您可以使用 pip

上的 -v 标志检查 docker 构建期间发生的情况

pip install -v -r requirements.txt

在 Arm/v7 arch 上,一些 python 库还没有准备好作为二进制文件,构建时间很长,因为您也在为 armV7 构建库。