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

问题描述

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 图像静态将 busybox 与 glibc 链接起来(当前版本由于使用 libnss 甚至在静态配置中动态地将 busybox 与 glibc 链接) ,而 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),那么您不需要'受益于动态链接;您不需要 libc 中未使用的部分,因为无论如何您都不会使用它们。

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