天天看點

尋根究底,為什麼Docker中的Alpine Linux鏡像能這麼小

作者:微言碼道

去年我發表了文章對Docker基礎鏡像的思考,該不該選擇alpine,其中對于Alpine Linux鏡像如此之小的原因我解釋為它使用了musl而不是glibc

有人發現并指出了我的這個錯誤,說musl與glibc的大小差别不足以造成如此大的差距,應該别有原因。

我一直記着這事,最近抽時間再次研究了下,确實如其所說,Alpine Linux之是以這麼小的原因,雖然musl是其中一個原因,但它是多種因素導緻的。

在此我有必要表示歉意,同時我需要補充這篇文章,對于Alpine Linux之是以這麼小,再解釋的更清楚一些。

尋根究底,為什麼Docker中的Alpine Linux鏡像能這麼小

1. 探究

在這篇文章中,我以Docker中的Alpine與Debian鏡像來詳細對比它們的大小,及導緻它們大小的原因。我們都知道,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才能造福世界。