還在用Alpine做Docker鏡像?看看大牛怎麼說

聞數起舞 發佈 2022-05-07T09:42:31.113960+00:00

大家都喜歡Alpine的鏡像,因為它們很輕,攻擊面較小,但也許它們不再是最佳選擇。在 SumUp我們經常使用Kubernetes和Docker鏡像,所以我們一直在尋找基礎鏡像的最佳選擇。

大家都喜歡Alpine的鏡像,因為它們很輕,攻擊面較小,但也許它們不再是最佳選擇。現在又到了談論distroless版鏡像的時候了。

在 SumUp我們經常使用Kubernetes和Docker鏡像,所以我們一直在尋找基礎鏡像的最佳選擇。distroless鏡像並不是什麼新東西,但由於某些原因,我覺得它們並沒有得到應有的採納。

什麼是distroless圖像?

我不得不說這不是什麼新東西,我是說真的。它已經存在很多年了,你可以在以下內容中查看 GoogleContainerTools/distroless.

"distroless無發行版 "只包含你的應用程式和它的運行時依賴。它們不包含軟體包管理器、外殼或任何其他你期望在標準Linux發行版中找到的程序。

這足以理解你的容器不會有任何東西,但你正在使用的東西。

我為什麼要使用它們?

現在每個人都有一個CI和CD管道,但有時需要花費很長時間來構建、推送和拉動鏡像。無發行版的鏡像更輕,這意味著拉動和推送更快。

distroless鏡像不一定會讓你的構建步驟更快,但它們會改善拉取和推送的時間。Docker提供了一個最小當你使用它作為鏡像的基礎時,它不會創建額外的層。更少的層等於更快的下載和上傳。

更快的管道意味著對開發人員的反饋更快,花費的CI時間更少,這在你使用像.NET這樣的工具時非常重要。

安全也是一個重要的問題,因為你應該儘可能地減少你的攻擊面。如果你不打算使用像sudo或ping這樣的工具,你就不應該在你的容器中設置這些工具。

如果你的代碼有漏洞,你就不太容易受到導致shell的RCE的影響,但RCE仍然在發生。

- 埃里克-杜蘭

應始終避免使用幫助惡意行為者收集更多信息或執行特權升級的工具。你應該看一下 erickduran/docker-distroless-pocREADME。

不應該使用distroless的場景

說什麼時候使用distroless很容易,但什麼時候不應該使用它們?

如果你想在容器內調試你的應用程式,你可以從shell和其他一些安裝的工具中獲益,但distroless沒有這些工具。顯而易見的答案是使用正常的鏡像進行開發,而將無發行版保留給生產。

在開發中使用不同的圖像使開發人員遠離真實的生產環境,這並不理想,但在你的CI管道中創建測試步驟,使用與生產中相同的環境,應該可以解決這個問題。對這種權衡要小心。

那就舉個例子吧?

儲存庫 GoogleContainerTools/distroless有一個關於如何為Golang工具製作無發行版distroless鏡像的例子。

這是一個簡單易行的例子,主要是因為Golang產生的二進位文件默認沒有運行時的依賴性。

相反,讓我們假設我們需要創建一個distroless的鏡像來使用ping二進位,因為我們將在我們的一個服務中使用它來檢查一個主機是否正常。這意味著我們需要找到所有的運行時依賴項,但我將儘可能地保持簡單。

我在Ubuntu中運行了ldd命令,它向我們顯示了它的依賴性,所以我開發了以下Dockerfile。另外,請注意,並不是每個運行時的依賴都在ldd命令的輸出中,我不得不使用其他方法來發現它們。

然而,這並不是最聰明的解決方案。上面的Docker文件創建了一個5.44MB的鏡像,我們可以通過使用Alpine而不是Ubuntu來改進它。如果你在Alpine環境中運行同樣的ldd命令,你也會有更少更輕的依賴性。

它運行良好,只用了1.43MB,比Alpine圖像和我們在第一階段使用Ubuntu建立的鏡像少了74%的空間

總結

標題說你應該停止使用Alpine,但我想我向你表明,這只是在正確場合做正確選擇的問題。另外,將alpine和 scratch創造出令人驚奇的distroless。

問題是,為你的應用程式建立distroless仍然是相當手動的,並不像你希望的那樣有趣。由於它需要開發人員付出更大的努力,所以通常被拋在後面,而支持著名的Alpine鏡像。

我認為我們的想法是在生產環境中以及在進行手動和自動測試時使用distroless。你不想讓開發人員在調試應用程式時承受更大的壓力。

我希望社區給予distroless應有的關注,這將導致更多的改進,比如儘可能地自動創建鏡像。

關鍵字: