alpine docker image 和 busybox docker image 有啥区别?

Posted

技术标签:

【中文标题】alpine docker image 和 busybox docker image 有啥区别?【英文标题】:What is the difference between alpine docker image and busybox docker image?alpine docker image 和 busybox docker image 有什么区别? 【发布时间】:2021-08-04 07:35:22 【问题描述】:

alpine docker 图像和busybox docker 图像有什么区别?

当我检查他们的停靠文件时,alpine is like this(适用于 Alpine v3.12 - 3.12.7)

FROM scratch
ADD alpine-minirootfs-3.12.7-x86_64.tar.gz /
CMD ["/bin/sh"]

busybox is like this

FROM scratch
ADD busybox.tar.xz /
CMD ["sh"]

但正如https://alpinelinux.org/about/ 所说

Alpine Linux 是围绕 musl libcbusybox 构建的。

那么到底有什么区别呢?

我也很好奇许多 docker 镜像(nodejs/nginx/php 仅举几例)提供基于 alpine 而不是busybox 的镜像。这是为什么 ? busybox 图片的用例是什么?我需要强调的是,我不是在寻找关于为什么 A 比 B 更好或反之亦然或软件推荐的答案。

我的 alpine docker 遇到了间歇性 DNS 查找失败,就像这里的 musl-libc - Alpine's Greatest Weakness 和这里的 Does Alpine have known DNS issue within Kubernetes? 所说的那样。这是我提出问题的原因之一。

PS,https://musl.libc.org/ 说“musl 是基于 Linux 系统调用 API 构建的 C 标准库的实现”,https://en.wikipedia.org/wiki/Alpine_Linux 也提到了

它以前使用 uClibc 作为其 C 标准库,而不是 最常用的传统 GNU C 库 (glibc)。虽然它是 更轻巧,它确实有一个显着的缺点是 二进制与 glibc 不兼容。因此,必须编译所有软件 与 uClibc 一起使用才能正常工作。截至 2014 年 4 月 9 日,[16] 阿尔派 Linux 切换到 musl,它部分二进制兼容 glibc。

【问题讨论】:

busybox 镜像是针对哪个 libc 构建的?我们需要分析busybox.tar.xz 才能知道。 如果它是静态链接的,我不会感到惊讶,但即便如此,静态链接的 glibc 和静态链接的 musl 之间的大小差异很大。基本上,busybox.tar.xz 是如何构建的需要成为问题才能回答。 (请注意,我认为这个问题可能是题外话,因为它是在两个替代软件之间“寻求建议”;此外,对它们之间不同之处的分析不是狭隘的或具体的因此可以说“过于宽泛”,而且随着新版本的推出可能会发生变化)。 但我真的没有寻找建议(任何东西)。我就是想知道busybox docker的用例。 ...如果alpine 提供musl 作为共享库并且busybox 静态链接musl,这意味着当您添加其他共享库时alpine 可以生成更小的图像,但是busybox 将会更小——如果这种猜测是真的,那么只有当你添加不需要更多编译二进制文件的 shell 脚本之类的东西(至少,不需要编译的二进制文件)时,它才会使 busybox 更有效率需要一个 libc)。 【参考方案1】:

它们之间的主要区别在于,旧版本的busybox 图像静态将busybox 与glibc 链接(当前版本动态链接busybox 与glibc,因为即使在静态配置中也使用libnss),而alpine 图像动态链接到 musl libc。

在这里详细讨论用于在这些之间进行选择的权重因素将是题外话(软件推荐请求),但有一些关键点:

比较 glibc 和 musl libc,有几个要点(当然还有很多其他因素):

glibc 专为提高性能和可移植性而设计(通常会添加需要大量代码的特殊情况下的性能优化)。 musl libc 是为正确性和大小而不是性能而构建的(它愿意稍微慢一些,以拥有更小的代码大小并在更少的 RAM 中运行);面对资源耗尽时,它更积极地提供正确的错误报告(而不是立即退出)。 glibc 的使用范围更广,因此对其实现表现出的错误往往会被更快地发现。通常,当一个人是第一个针对 musl 构建给定软件的人时,会遇到错误(通常在该软件中,而不是在 musl 中)或维护者明确选择使用 GNU 扩展而不是坚持 libc 标准的地方. glibc 根据 LGPL 条款获得许可;只有符合 GPL 条款的软件才能与其静态链接;而 musl 是在 MIT 许可下,并且可以在较少的限制下使用。

比较静态构建与动态构建的优势:

如果您的系统映像只有一个二进制可执行文件(用 C 编写或使用 libc 编写),则静态构建总是更好,因为它会丢弃该可执行文件实际未使用的库中的任何部分. 如果您的系统映像打算添加更多用 C 编写的二进制文件,则使用动态链接将减小整体大小,因为它允许这些二进制文件使用已经存在的 libc。 如果您的系统映像打算在不使用 libc 的语言中添加更多二进制文件(Go 和 Rust 可能就是这种情况,f/e),那么您不要' t 受益于动态链接;您不需要那里未使用的 libc 部分,因为无论如何您都不会使用它们。

老实说,这两个图像之间并没有覆盖整个可能性矩阵空间;在某些情况下,它们都不是最优的。有一个只有busybox的图像是有价值的,它静态链接到musl libc(如果你要添加的所有东西都是非C语言),或者一个带有busybox的图像动态地链接到 glibc(如果您要添加更多需要 libc 且与 musl 不兼容的二进制文件)。

【讨论】:

感谢您的详细回答。我猜麻省理工学院的许可证可能是一个关键因素。 耸耸肩。 LGPL(与常规 GPL 不同)对动态链接很友好,这就是为什么 glibc 甚至被广泛用于商业软件的原因;大多数人不需要静态链接他们的商业工具。 wiki.musl-libc.org 说“musl 相对于 glibc 和 uClibc/uClibc-ng 的一些主要优势在于它的大小、正确性、静态链接支持和干净的代码” 是的,这一切都是真的。也就是说,glibc 是“标准”意味着有一些非常强大的网络效应对其有利;需要移植软件来构建针对 musl 的工作是可行的,而基本上一切都可以使用 glibc 开箱即用。

以上是关于alpine docker image 和 busybox docker image 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

docker制作alpine初始镜像

Docker Node Alpine Image Build 在 node-gyp 上失败

sbt-native-packager:Alpine Docker Image 上的 Scala 应用程序失败,权限被拒绝

ssh 故障排除,连接到 alpine docker image ssh_exchange_identification: Connection closed by remote host

将 bcrypt 添加到 package.json 时,如何使用 docker node alpine Image 解决“找不到任何要使用的 Python 安装”?

Docker下alpine镜像安装Latex工具心得