原文連結:https://mp。weixin。qq。com/s/wW3Qaz7vERjAEHd9yzChZA
大多數情況下,我們構建容器映象時選擇的基礎映象無外乎是
busybox
、
alpine
和
google/distroless
這幾種,這幾個基礎映象在雲原生的世界很吃香,被廣泛應用於各個應用的容器化。
那麼問題來了,為什麼這幾個基礎映象如此受歡迎呢?
我們先來看下這幾個基礎映象的大小:
→ podman image ls REPOSITORY TAG IMAGE ID CREATED SIZEdocker。io/library/alpine latest 14119a10abf4 6 days ago 5。87 MBdocker。io/library/busybox latest 42b97d3c2ae9 13 days ago 1。46 MBgcr。io/distroless/static latest e0851a4aa136 51 years ago 3。06 MB
可以看到這些映象的體積都非常小,幾乎可以忽略不計。
Busybox
先啟動一個 Busybox 容器進去一探究竟:
這個映象的大小隻有
1。24MB
,卻容納了這麼多 GNU 命令,麻雀雖小五臟俱全啊,這到底是怎麼做到的?
事實上這一切都要歸功於
Multi-Call binary
。什麼是
Multi-Call binary
呢?
顧名思義,Multi-Call binary 就是
多重呼叫二進位制檔案
,是一個用C語言編寫的程式,它允許多次呼叫來執行二進位制檔案。它包含了很多函式,每個執行獨特動作的函式都可以透過一個名字來呼叫,這個名字同時也是 Multi-Call binary 的一個符號連結。Multi-Call binary 最好的應用範例便是 Busybox。
Busybox 裡面的函式可以透過兩種方式來呼叫:
busybox ls
ls
例如:
很明顯,這些不是我們所熟知的 GNU 二進位制檔案,因為所有的二進位制檔案都具有相同的屬性,比如大小、日期等。這些都不是獨立的二進位制檔案,而是 Multi-Call binary 每個呼叫函式的別名。這個 Multi-Call binary 就叫
Busybox
。
遺憾的是,這些 Busybox 命令並不完全等同於 GNU 命令,某些命令的某些引數是無法執行的,相當於閹割版。
Alpine
看完了 Busybox,我們再來看看 Alpine 是怎麼做的。
巧了,Alpine 的二進位制檔案竟然是指向 busybox 二進位制檔案的,這就很明顯了,Alpine 映象的底層使用了 busybox 二進位制檔案。除此之外,Alpine 還包含了
apk
包管理器和一些額外的可執行檔案,所以 Alpine 映象的體積才會比 Busybox 大。
Distroless
Distroless
就不用說了,它來自
[1]。該映象幾乎就是空的,只包含應用程式及其執行時所需的依賴,不包含軟體包管理器、shell 和其他 GNU 二進位制檔案,當然還包含一些時區配置和部分 ca-certificates。
可以看到這個映象中有沒有
shell
也沒有
bash
,為了一探究竟,可以先把映象儲存為 tar 包,然後把
rootfs
解壓出來:
→ mkdir image → tar xvf distroless。tar。gz -C image/16679402dc206c982b5552ab8de7d898547100e5468be29d4f67d393c0eadfdb。tare0851a4aa13657fc8dcd01e0e5e08cb817123ccb82e2c604b34f9ec9c1755e3f。json2e18de03719583329b7fa8374130e57cc7cddf2b5a487fe4a4988622ca60575c/layer。tar2e18de03719583329b7fa8374130e57cc7cddf2b5a487fe4a4988622ca60575c/VERSION2e18de03719583329b7fa8374130e57cc7cddf2b5a487fe4a4988622ca60575c/jsonmanifest。jsonrepositories → cd image → ls -lhtotal 3。0M-r——r——r——。 1 root root 3。0M Jan 1 1970 16679402dc206c982b5552ab8de7d898547100e5468be29d4f67d393c0eadfdb。tardrwxr-xr-x。 2 root root 50 Sep 3 17:42 2e18de03719583329b7fa8374130e57cc7cddf2b5a487fe4a4988622ca60575c-r——r——r——。 1 root root 462 Jan 1 1970 e0851a4aa13657fc8dcd01e0e5e08cb817123ccb82e2c604b34f9ec9c1755e3f。json-r——r——r——。 1 root root 213 Jan 1 1970 manifest。json-r——r——r——。 1 root root 106 Jan 1 1970 repositories → mkdir rootfs → tar xf 16679402dc206c982b5552ab8de7d898547100e5468be29d4f67d393c0eadfdb。tar -C rootfs → tree rootfsrootfs├── bin├── boot├── dev├── etc│ ├── debian_version│ ├── default│ ├── dpkg│ │ └── origins│ │ └── debian│ ├── group│ ├── host。conf│ ├── issue│ ├── issue。net│ ├── nsswitch。conf│ ├── os-release│ ├── passwd│ ├── profile。d│ ├── protocols│ ├── rpc│ ├── services│ ├── skel│ ├── ssl│ │ └── certs│ │ └── ca-certificates。crt│ └── update-motd。d│ └── 10-uname├── home│ └── nonroot├── lib├── proc├── root├── run├── sbin├── sys├── tmp├── usr│ ├── bin│ ├── games│ ├── include│ ├── lib│ │ └── os-release│ ├── sbin│ │ └── tzconfig│ ├── share│ │ ├── base-files│ │ │ ├── dot。bashrc│ │ │ ├── dot。profile│ │ │ ├── dot。profile。md5sums│ │ │ ├── info。dir│ │ │ ├── motd│ │ │ ├── profile│ │ │ ├── profile。md5sums│ │ │ └── staff-group-for-usr-local……
該映象只有一層,大小為 3MB,也沒有二進位制檔案,只有一些證書檔案和目錄。如果向下滾動,還能看到許可證和時區配置。看來 Distroless 採取的是非常極端的手段,直接把不需要的二進位制檔案全部拋棄了,只留下一個空映象和部分必需品。
總結
由此看來,這幾個基礎映象如此受歡迎的主要原因就是體積小。映象越小,漏洞就越少,可攻擊面也會大幅減少,而且很容易維護。所以大家構建映象時儘量選擇這些映象作為基礎映象。
引用連結
[1]Google:
https://github。com/GoogleContainerTools/distroless