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

news/2025/1/13 11:01:27/

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

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

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

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

Debian与Apline

1. 探究

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

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

其中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

Alpine

828.0K	/bin
72.0K	/var

2. 分析

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

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

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

  • /usr/share/locale: 国际化文件
  • /usr/share/doc: 帮助文档

可以推断,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
# 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 

可以看出,光是安装包就有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

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

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

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

第四: 没有apt与systemd

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

但在Alpine中,apk取代了apt,Alpine同样没有使用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才能造福世界。


文章原载于个人网站 微言码道


http://www.ppmy.cn/news/21508.html

相关文章

【数据结构与算法】图的基本概念 | 邻接矩阵和邻接表 | 广度优先遍历和深度优先遍历

🌠作者:阿亮joy. 🎆专栏:《数据结构与算法要啸着学》 🎇座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 目录👉…

Microsoft Office( Word、Excel、PowerPoint)的安装

1 下载Office Tool Plus 官网地址:点击下载 2 点击Office Tool Plus.exe 3 接受软件许可条款和Microsoft服务协议 4 点击安装Office 5 选择Office 专业增强版 2019 6 确认安装Office 专业增强版 2019 7 关闭安全中心警报 8 等待安装完成 9 点击关闭 10 点击返回…

用#define宏实现Add函数

✋作者:阿润菜菜 📖专栏:C语言 我们知道#define宏是一种非常暴力的替换,宏定义会在程序编译预处理阶段在调用宏的位置进行文本内容的直接替换,因此我们在使用宏定义实现Add加法函数时就要注意一些可能会报错的问题。 …

瞧不上alert 老古董?使用alert实现一个精美的弹窗

曾几何时alert陪伴了我很多歌日日夜夜,但现在人们越来越追求高端的技术,其实慢慢的我也都快淡忘了前端的世界里还有alert这么一个伟大的成员。 目录 一、为什么抛弃了alert? 1. 不同浏览器的表现 2. 第三方组件的使用 3. 代码意识的控制 二、用al…

springmvc知识巩固

文章目录回顾spring知识前言什么是SpringMVCSpringMVC的优点SpringMVC的常用注解Controller注解的作用ResponseBody注解的作用SpringMVC重定向和转发SpringMVC主要组件SpringMVC的执行流程回顾spring知识 上篇整理了“spring知识巩固”常见面试题,有需要的伙伴请点…

Docker镜像部署至Rancher全局配置 以xxl-job-admin为例

流程以xxl-job-admin为例 1.基础环境 win/mac/linuxRancherDocker 2.下载源码 从Github上下载xxl-job xxl-jobGithub xxl-job官方地址 3.修改源码 打开 xxl-job 下的 xxl-job-admin 修改 application-properties 文件 修改数据库 修改为这种格式: 大括号包…

关于【继承】这些你都了解吗?

致前行的人: 要努力,但不要着急,繁花锦簇,硕果累累,都需要过程! 目录 1.继承的概念和定义 1.1继承的概念 1.2继承的定义 2.基类和派生类对象赋值转换 3.继承中的作用域 4.派生类的默认成员函数 5.继承与友元…

C语言之初识指针

前言 🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏: 🍔🍟🌯 c语言初阶 🔑个人信条: 🌵知行合一 🍉本篇简介:>:介绍c语言中的新知识—指针有关的知识. 金句分享: ✨知…