构建更小的容器镜像

Linux Containers 已成为一个热门话题,确保容器镜像不大于应有的大小被认为是一种好习惯。 这篇文章提供了一些关于如何创建更小的提示 Fedora 容器图像。

微dnf

Fedora的 DNF 是用 Python 编写的,并且它的设计是可扩展的,因为它具有广泛的插件。 但 Fedora 有一个替代的基础容器镜像,它使用一个更小的包管理器,称为 微dnf 用 C 编写。要在 Dockerfile 中使用这个最小图像,FROM 行应该如下所示:

FROM registry.fedoraproject.org/fedora-minimal:30

如果您的图像不需要像 Python 这样的典型 DNF 依赖项,这是一个重要的节省。 为了 example,如果您正在制作 NodeJS 图像。

一层安装和清理

为了节省空间,使用 dnf clean all 或其 microdnf 等效 microdnf clean all 删除 repos 元数据很重要。 但是您不应该分两步执行此操作,因为这实际上会将这些文件存储在容器映像层中,然后将它们标记为在另一层中删除。 要正确执行此操作,您应该像这样一步完成安装和清理

FROM registry.fedoraproject.org/fedora-minimal:30 
RUN microdnf install nodejs && microdnf clean all

模块化与 microdnf

模块化是一种为您提供不同版本的堆栈供您选择的方式。 为了 example 您可能需要一个项目的非 LTS NodeJS 版本 11 和另一个项目的旧 LTS NodeJS 版本 8 和另一个项目的最新 LTS NodeJS 版本 10。 您可以使用冒号指定哪个流

# dnf module list  
# dnf module install nodejs:8

dnf 模块安装命令意味着两个命令,一个启用流,另一个从它安装 nodejs。

# dnf module enable nodejs:8 
# dnf install nodejs

尽管 microdnf 不提供任何与模块化相关的命令,但可以使用配置文件和 libdnf(microdnf 使用)启用模块 似乎 支持模块化流。 文件看起来像这样

/etc/dnf/modules.d/nodejs.module 
[nodejs]
name=nodejs
stream=8
profiles=
state=enabled

使用 microdnf 模块化的完整 Dockerfile 如下所示:

FROM registry.fedoraproject.org/fedora-minimal:30 
RUN
echo -e "[nodejs]nname=nodejsnstream=8nprofiles=nstate=enabledn" > /etc/dnf/modules.d/nodejs.module &&
microdnf install nodejs zopfli findutils busybox &&
microdnf clean all

多阶段构建

在许多情况下,您可能有大量运行软件不需要的构建时依赖项 example 构建一个 Go 二进制文件,它静态链接依赖项。 多阶段构建是分离应用程序构建和应用程序运行时的有效方式。

为了 example 下面的 Dockerfile 构建 信心 Go 应用程序。

# building container 
FROM registry.fedoraproject.org/fedora-minimal AS build
RUN mkdir /go && microdnf install golang && microdnf clean all
WORKDIR /go
RUN export GOPATH=/go; CGO_ENABLED=0 go get github.com/kelseyhightower/confd

FROM registry.fedoraproject.org/fedora-minimal
WORKDIR /
COPY --from=build /go/bin/confd /usr/local/bin
CMD ["confd"]

多阶段构建是通过在 FROM 指令之后添加 AS 并从基础容器映像中获取另一个 FROM 然后使用 COPY –from= 指令将内容从构建容器复制到第二个容器来完成的。

然后可以使用 podman 构建和运行此 Dockerfile

$ podman build -t myconfd .
$ podman run -it myconfd