1、概述
使用 Distroless 鏡像來保護 Kubernetes 上的容器。
容器改變了我們看待技術基礎設施的方式。這是我們運行應用程序方式的一次巨大飛躍。容器編排和雲服務一起為我們提供了一種近乎無限規模的無縫擴展能力。
根據定義,容器應該包含 應用程序 及其 運行時依賴項。然而,在現實中,它們包含的遠不止這些。標准容器基礎鏡像包含標准 Linux 發行版中可以找到的包管理器、shell 和其他程序。
雖然這些都是構建容器鏡像所必需的,但它們不應該成為最終鏡像的一部分。例如,一旦你把包安裝好了,就不再需要在容器中使用 apt 等包管理工具了。
這不僅使你的容器里充滿了不必要的軟件包和程序,而且還為網絡罪犯提供了攻擊特定程序漏洞的機會。
你應該始終了解容器運行時中存在什么,並且應該精確地限制其只包含應用程序所需的依賴項。
除了那些必要的,你不應該安裝任何東西。一些領先的科技巨頭,如谷歌,有多年在生產中運行容器的經驗,已經采用了這種方法。
谷歌現在通過提供 Distroless 鏡像向全世界開放這種能力。谷歌構建的這些鏡像的目標是只包含你的應用程序及其依賴項,同時它們將沒有常規 Linux 發行版的所有特性,包括 shell。
這意味着雖然可以像以前一樣運行應用程序的容器,但不能在容器運行的時候進入容器內。這是一個重大的安全改進,因為你現在已經為黑客通過 shell 進入你的容器關上了大門。
2、Distroless 基礎鏡像
谷歌為大多數流行的編程語言和平台提供了 Distroless 的基礎鏡像。
以下基礎鏡像是正式發布的版本:
- gcr.io/distroless/static-debian10
- gcr.io/distroless/base-debian10
- gcr.io/distroless/java-debian10
- gcr.io/distroless/cc-debian10
- gcr.io/distroless/nodejs-debian10
下面的基礎鏡像仍在實驗階段,不推薦用於生產環境:
- gcr.io/distroless/python2.7-debian10
- gcr.io/distroless/python3-debian10
- gcr.io/distroless/java/jetty-debian10
- gcr.io/distroless/dotnet
3、構建 Distroless 鏡像
谷歌在內部使用 Bazel 來構建容器映像,但是我們可以使用 Docker 來做同樣的事情。關於使用 Distroless 鏡像的一個有爭議的問題是:當我們有一個 Distroless 鏡像時,我們如何使用 Dockerfile 來構建我們的應用程序呢?
通常,Dockerfile 以一個標准的 OS 基礎鏡像開始,然后是創建適當的運行時構建所需執行的多個步驟。這包括包的安裝,為此需要像 apt 或 yum 這樣的包管理器。
有兩種方法:
- 先在
Docker外部構建好你的應用程序,然后使用Dockerfile中的 ADD 或 COPY 指令將二進制包復制到容器中。 - 使用多階段
Docker構建。這是 Docker 17.05 及以后版本的一個新特性,它允許你將構建分為不同的階段。第一階段可以從標准的 OS 基礎鏡像開始,可以幫助你構建應用程序;第二階段可以簡單地從第一階段獲取構建的文件並使用Distroless作為基礎鏡像。
為了理解它是如何工作的,讓我們使用多階段構建流程進行一個實際操作練習。
4、如何調試基於distroless 鏡像的容器
distroless 鏡像沒有 sh,要想進入基於distroless鏡像的容器內部需要通過 busybox,下面以fluentbit鏡像為例介紹如何調試基於distroless鏡像的容器。
下載 busybox 到宿主機:
wget https://busybox.net/downloads/binaries/1.21.1/busybox-x86_64
拷貝bubybox到當前宿主機的flentbit容器內部
chmod 777 busybox-x86_64 mv busybox-x86_64 busybox docker ps | grep fluent-bit docker cp busybox 35a8129b9702:/
通過busybox在容器內部調試基於distroless鏡像的容器
kubectl exec -it -n logging-system fluent-bit-98d94 /busybox sh / # /busybox ls
5、Distroless 鏡像和 Alpine 鏡像應該如何選擇?
如果是在生產環境中運行,並且注重安全性, Distroless鏡像可能會更合適。
Docker鏡像中每增加一個二進制程序,就會給整個應用程序帶來一定的風險。在容器中只安裝一個二進制程序即可降低整體風險。
舉個例子,如果黑客在運行於Distroless的應用中發現了一個漏洞,他也無法在容器中創建Shell,因為根本就沒有。
如果更在意要是大小,則可以換成Alpine基礎鏡像。
這兩個都很小,代價是兼容性。Alpine用了一個稍稍有點不一樣的C標准庫——muslc,時不時會碰到點兼容性的問題。
說明:
原生基礎鏡像非常適合用於測試和開發。它的尺寸比較大,不過用起來就像你主機上安裝的Ubuntu一樣。並且,你能訪問該操作系統里有的所有二進制程序。
6、結論
使用 Distroless 作為基礎鏡像是一種令人興奮的保護容器安全的方式。它僅包含您的應用程序及其運行時依賴項。它們不包含您希望在標准 Linux 發行版中找到的包管理器、shell或任何其他程序。容器里並沒有Shell!如果黑客入侵了我們的應用程序並獲取了容器的訪問權限,他也無法造成太大的損害。由於鏡像小並且僅包含應用程序和依賴項,因此它為應用程序提供了最小的攻擊面。它在更大程度上提高了應用程序的安全性,所以它是保護容器安全的好方法。不過,代價是調試更麻煩。
相關推薦博文:《使用 Alpine 作為基礎鏡像時可能會遇到的常見問題的解決方法 》
參考:https://segmentfault.com/a/1190000040255793
參考:https://zhuanlan.zhihu.com/p/406666870
