寻根究底,为什么 Docker 中的 Alpine Linux 镜像能这么小?

简介: 在这篇文章中,我以 Docker 中的 Alpine 与 Debian 镜像来详细对比它们的大小,及导致它们大小的原因。我们都知道,Debian 比 Ubuntu 更精简,这样对比会更有价值。

前言

去年我发表了文章 对 Docker 基础镜像的思考,该不该选择 alpine,其中对于 Alpine Linux 镜像如此之小的原因我解释为它使用了 musl 而不是 glibc

有人发现并指出了我的这个错误,说 muslglibc 的大小差别不足以造成如此大的差距,应该别有原因。

我一直记着这事,最近抽时间再次研究了下,确实如其所说,Alpine Linux 之所以这么小的原因,虽然 musl 是其中一个原因,但它是多种因素导致的。

在此我有必要表示歉意,同时我需要补充这篇文章,对于 Alpine Linux 之所以这么小,再解释的更清楚一些。

1、探究

在这篇文章中,我以 Docker 中的 AlpineDebian 镜像来详细对比它们的大小,及导致它们大小的原因。我们都知道,DebianUbuntu 更精简,这样对比会更有价值。

1.1 镜像大小

通过 docker images ls 命令,可以查出这两个镜像当前的 latest 版本的大小对比:

REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
debian       latest    5c8936e57a38   3 weeks ago   124MB
alpine       latest    042a816809aa   3 weeks ago   7.05MB
AI 代码解读

其中 debian 的大小为 124M,而 alpine 的大小只有 7.05MB 左右,大小相差还是非常明显的。

接下来,我将探究为它们究竟差别在哪?

1.2 探究方法

通过 du -s * | sort -nr 计算文件夹大小,不断寻找两个镜像中的大小差别比较明显的一些关键目录。

1.3 结果

与大小有关的关键目录如下:(仅列出差别明显的关键目录)

  • Debian
36M   /usr/lib/x86_64-linux-gnu
31M   /usr/share/locale
13M   /usr/share/doc
8.2M  /lib/x86_64-linux-gnu
6.1M  /var
5.2M  /bin
4.0M  /sbin
AI 代码解读
  • Alpine
828.0K /bin
72.0K /var
AI 代码解读

2. 分析

通过上述目录,可以大致分析出, Alpine镜像能如此之小的原因大致能区分为几大类:

  • 第一:删除部分非必须的资源文件

可以看出,这两个目录在Alpine中压根没有

• /usr/share/locale: 国际化文件
• /usr/share/doc: 帮助文档
AI 代码解读

可以推断,Alpine 删除了类似的无用的资源文件,没有它们并不影响系统的运行。

  • 第二:使用 musl,而非 glibc

/usr/lib/x86_64-linux-gnu/lib/x86_64-linux-gnu 这两个目录大多是 glibc,libc,perl 等的共享类库所有目录。如我在以前的文章中所述,Alpine 中没有使用 glibc,而是使用了 musl,所以这一部分占据的大小也小了很多。

同时,通过在 musl官网与 glibc 官网查阅它们的压缩安装包大小分别是:

  • musl
1.1MB musl-1.2.3.tar.gz
AI 代码解读
  • glibc
18M  glibc-2.3.6.tar.gz
123K glibc-libidn-2.3.6.tar.gz
320K glibc-linuxthreads-2.3.6.tar.gz
1.8M glibc-ports-2.16.0.tar.gz
AI 代码解读

可以看出,光是安装包就有20倍左右的差别,安装后当然相差更大。

  • 第三:使用了 busybox 工具集

同样,分析上面的目录,会发现一个有趣的现象,Debian 中的 /bin/sbin 目录大小明显高于 Alpine/bin,这又是为什么呢?

这是因为,Apline 使用的是 busybox 这个工具集。那 busybox 是什么呢?

你可以把 busybox 理解为 bin 命令的瑞士军刀

我们都知道,Linux 中我们依赖各种命令去操作系统,比如 cd,ls,pwd 等,这些命令每个都是一个个可执行文件。

busybox 也是一个可执行文件,但它与众不同,它是包含了常用的 300 多个命令的工具集。

看代码更容易理解:

# 功能与ls类似
busybox ls
# 功能与pwd类似
busybox pwd
# 功能与kill类似
busybox kill
AI 代码解读

现在你明白了吗,Apline 中压根没有 ls,pwd 这些类似其它 Linux 发行版本中的执行文件,它全部都只是busyboxalias 而已。

也就是,Alpine 中最主要的一个命令文件,就是 busybox ,而 busybox 是一个 5M 不到大小的,包含近 300 多个命令的工具集。

是不是 bin 命令的瑞士军刀?

  • 第四:没有 apt 与 systemd

Debian/Ubuntu 中,包管理是 apt。同样,Debian 与大都数 Linux 类似,都是使用的 systemd

但在 Alpine 中,apk 取代了 aptAlpine 同样没有使用 systemd,而是使用了 OpenRC,无论是 apt 还是 OpenRC,都是轻而小的实现。

3. 结论

现在,我能比上一次稍微准确的说出 Alpine 能这么小的原因了。

大致为:

  1. Alpine 中删除了一些不影响系统运行的辅助性资源文件;
  2. 使用 Musl取代了 Glibc;
  3. 使用了 BusyBox, apt 以及 OpenRC等一些轻量级实现;

从这些做法上也能看出,Alpine 的定位不是普通的 Linux 系统,它应该是为嵌入式 Linux 而生,几 MB 的系统大小,当然更适合嵌入式 Linux

这也从另一个角度充分说明 Linux 系统的优秀,也就是只需要一个 Linux 内核,其它外围的一切几乎都是可以替代的,而仍然能保证 Linux 系统的运行与一致性。

幸运的是,Linux 内核是开源的。而正因为它是开源的,今天 Linux 才能造福世界。

关于基础镜像是否使用 Alpine Linux 构建的建议

  • 如果你的服务,不依赖C,那 alpine 是合适的选择,否则不应当使用 alpine 做为基础镜像;
  • 考虑到部署的一致性,就算是容器,使用同一系的 Linux基础镜像是更妥当的选择,比如全是 Debian 系或 RHEL 系等;
  • 优化镜像的空间非常有必要,各种建议仍然非常有价值,但不要走的太过,镜像的空间问题并没有你想像的那么严重;
  • 在公司或项目级别,不要使用 Docker Hub 或其它公有云镜像,使用简易的 registry 或企业级 Harbor,Nexus 等搭建一个内网镜像中心,能让容器镜像的上传下载更快捷方便。

参考

转载声明

目录
相关文章
《docker基础篇:4.Docker镜像》包括是什么、分层的镜像、UnionFS(联合文件系统)、docker镜像的加载原理、为什么docker镜像要采用这种分层结构呢、docker镜像commit
《docker基础篇:4.Docker镜像》包括是什么、分层的镜像、UnionFS(联合文件系统)、docker镜像的加载原理、为什么docker镜像要采用这种分层结构呢、docker镜像commit
137 70
Docker-基础(数据卷、自定义镜像、Compose)
通过数据卷实现持久化存储,通过自定义镜像满足特定需求,通过Docker Compose方便地管理多容器应用
51 27
|
11天前
|
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
81 6
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
Docker-基础(数据卷、自定义镜像、Compose)
通过数据卷实现持久化存储,通过自定义镜像满足特定需求,通过Docker Compose方便地管理多容器应用。掌握这些Docker基础概念和操作,可以显著提高开发和部署效率,确保应用程序的可移植性和可扩展性。
54 22
《docker基础篇:6.本地镜像发布到私有库》包括本地镜像发布到私有库流程、docker regisry是什么、将本地镜像推送到私有库
《docker基础篇:6.本地镜像发布到私有库》包括本地镜像发布到私有库流程、docker regisry是什么、将本地镜像推送到私有库
87 29
os-copilot在Alibaba Cloud Linux镜像下的安装与功能测试
我顺利使用了OS Copilot的 -t -f 功能,我的疑惑是在换行的时候就直接进行提问了,每次只能写一个问题,没法连续换行更有逻辑的输入问题。 我认为 -t 管道 功能有用 ,能解决环境问题的连续性操作。 我认为 -f 管道 功能有用 ,可以单独创建可连续性提问的task问题。 我认为 | 对文件直接理解在新的服务器理解有很大的帮助。 此外,我还有建议 可以在非 co 的环境下也能进行连续性的提问。
28 7
将本地的应用程序打包成Docker镜像
将本地的应用程序打包成Docker镜像
docker push推送自己搭建的镜像
本文详细介绍了如何搭建和复盘两个Web安全挑战环境:人力资源管理系统和邮件管理系统。首先,通过Docker搭建MongoDB和PHP环境,模拟人力资源管理系统的漏洞,包括nosql注入和文件写入等。接着,复盘了如何利用这些漏洞获取flag。邮件管理系统部分,通过目录遍历、文件恢复和字符串比较等技术,逐步绕过验证并最终获取flag。文章提供了详细的步骤和代码示例,适合安全研究人员学习和实践。
52 3
docker push推送自己搭建的镜像
Docker在现代软件开发中扮演着重要角色,通过Dockerfile自动化构建Docker镜像,实现高效、可重复的构建过程。
Docker在现代软件开发中扮演着重要角色,通过Dockerfile自动化构建Docker镜像,实现高效、可重复的构建过程。Dockerfile定义了构建镜像所需的所有指令,包括基础镜像选择、软件安装、文件复制等,极大提高了开发和部署的灵活性与一致性。掌握Dockerfile的编写,对于提升软件开发效率和环境管理具有重要意义。
73 9

热门文章

最新文章