【问题标题】:Docker Ruby 2.6.6-alpine is twice as big as Ruby-2.6.5-alpineDocker Ruby 2.6.6-alpine 是 Ruby-2.6.5-alpine 的两倍
【发布时间】:2020-07-25 07:42:01
【问题描述】:

使用 ruby​​-2.6.6-alpine 的 Docker 镜像创建一个 498mb 的镜像大小。但是,当我降级到 ruby​​-2.6.5-alpine 时,它​​又回到了 266mb。 2.6.6 版本几乎是原来的两倍。为什么会这样?

# RESULTS IN 266MB
FROM ruby:2.6.5-alpine
RUN apk add --update --no-cache \
        build-base \
        postgresql-dev \
        vim \
        tzdata \
        bash \
        less

# RESULTS IN 498MB
FROM ruby:2.6.6-alpine
RUN apk add --update --no-cache \
        build-base \
        postgresql-dev \
        vim \
        tzdata \
        bash \
        less

【问题讨论】:

  • 我已经编辑了更多分析的答案:postgresql-dev 似乎是这里的罪魁祸首。
  • 我已经用一个可能的解决方法编辑了答案,基于ruby-2.6.6-alpine 的图像大小为 305Mo,仅比基于ruby-2.6.5-alpine 大 40Mo

标签: ruby docker alpine


【解决方案1】:

TLDR;将postgresql-dev 替换为'postgresql-dev<12.2-r0'

如:

RUN apk add --update --no-cache \
...\
'postgresql-dev<12.2-r0'\
...

您将获得(以ruby:2.6.6-alpine 作为基础图像)305Mo 图像大小,与基础图像为ruby:2.6.5-alpine 时的 265Mo 足够接近。


详情:

我似乎无法让imagelayers.io 正常工作,所以我转而使用wagoodman/dive 来检查这两个图像的层。

在这两种情况下,我都得到了 50Mo 的图像(2.6.5-alpine 为 49.5)

所以基础镜像在这里不是问题。

区别在于:

从 2.6.6 完成后,您的依赖项列表将安装以下 附加 包:

{+Installing xz-libs (5.2.5-r0)+}
{+Installing libxml2 (2.9.10-r4)+}
{+Installing llvm10-libs (10.0.0-r2)+}
{+Installing clang-libs (10.0.0-r2)+}
{+Installing clang (10.0.0-r2)+}
{+Installing llvm10 (10.0.0-r2)+}
{+Installing icu-libs (67.1-r0)+}
{+Installing icu (67.1-r0)+}
{+Installing icu-dev (67.1-r0)+}

这是由于:

我已将this gist 添加到您的 Dockerfile 中

RUN apk info | xargs -n1 -I{} apk info -s {} | xargs -n4 | awk '{print $4,$1}' | sort -rn

我明白了

85360640 gcc-9.2.0-r4

对比

109056000 gcc-9.3.0-r2
63430656 llvm10-libs-10.0.0-r2
62976000 clang-libs-10.0.0-r2
  • gcc 更大(从 85Mo 到 109)
  • llvm10-libsclang-libs 添加 125Mo

Jérôme Petazzoni 中的“The Quest for Minimal Docker Images, part 2”所示,最好使用 multi-stage build,例如:

FROM alpine
RUN apk add build-base
COPY hello.c .
RUN gcc -o hello hello.c

FROM alpine
COPY --from=0 hello .
CMD ["./hello"]

注意,寻找大小增加的根本原因:

额外的依赖是patch,它本身依赖musl:非常小。
大小问题与build-base无关

让我们将您的Dockerfile 更改为:

RUN apk add --update
RUN apk info build-base
RUN apk add --update --no-cache build-base
RUN apk add --update --no-cache postgresql-dev
RUN apk add --update --no-cache vim
RUN apk add --update --no-cache tzdata
RUN apk add --update --no-cache bash
RUN apk add --update --no-cache less

实用程序dive 将显示postgresql-dev 是Alpine 3.12 需要clang 的那个。

这三个附加依赖项是:

Alpine 3.10+ to 3.12 开始,安装postgresql 意味着启动clang,但postgresql-dev 的大小差异在两者之间巨大

  • Alpine 3.11 或更低版本:postgresql-dev 为 15Mo

  • Alpine 3.12:215Mo for postgresql-dev

这是因为 Alpine postgresql APKBUILD 的依赖关系最近发生了变化。
见:

第一次提交的评论提到:

由于我们在构建 PostgreSQL 时启用了 JIT 支持,因此使用 PGXS 构建扩展需要 clangllvm-lto

可能是因为docker-library/postgres issue 475: "JIT --with-llvm"

... 这导致 docker-library/postgres issue 651: "postgres:12.0-alpine upgrade to postgres:12.1-alpine double size"。

见“Postgresql 12: What Is JIT compilation?

即时 (JIT) 编译是将某种形式的解释程序评估转换为本机程序并在运行时执行此操作的过程。

例如,可以生成一个特定于该表达式的函数,并且可以由CPU,产生加速。

当 PostgreSQL 使用 --with-llvm 构建时,PostgreSQL 已内置支持使用 LLVM 执行 JIT 编译。

because now:

对于支持LLVM 的 PostgreSQL 12 系统,默认启用即时编译,即“JIT”。

这反映在how postgresql is built for Docker:从issue 643 看到commit c8bf23b,并在docker-library/official-images PR 7042 中合并。

所以...可能的解决方法:限制postgresql-dev 的版本,如“How to install a specific package version in Alpine?”中所述:

RUN apk add --update --no-cache 'postgresql-dev<12.2-r0'

这将确保使用 15Mo postgresql 而不是 215Mo。

【讨论】:

  • 有趣。就像您推荐的那样,我通过使用多阶段构建解决了这个问题。尽管对于升级到最新 ruby​​ 2.6 alpine 系列版本的任何人来说,这种显着的大小增加似乎仍然是一个很大的问题。感谢您花时间分析docker镜像,以后一定会使用dive工具来分析我的docker镜像。
  • 用于 postgresql 的该死的 JIT(请参阅上面我编辑的答案)。好处似乎并不总是显而易见的:dba.stackexchange.com/questions/264955/…postgresql.org/message-id/flat/…。另见severalnines.com/database-blog/…
  • 而且...您不能强制删除额外的依赖项:unix.stackexchange.com/questions/475226/…: "the following packages are not removed due to: llvm10: postgresql-dev"
  • 感谢您的详细解答。 postgres 默认启用 JIT 似乎很奇怪。我最近将一个 RDS 实例从 11 升级到了 12,我注意到一些查询的性能相当慢。答案是调整默认的 JIT 参数。谁知道这个问题是相关的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-22
  • 2018-01-25
相关资源
最近更新 更多