唱衰Docker,給大紅大火的Docker潑點冷水

jopen 9年前發布 | 8K 次閱讀 Docker

原文  http://www.infoq.com/cn/articles/bad-mouthing-docker


從我上一次對Docker進行 評價 到現在已然經過了一年有余,想當初我在文章里對這套容器技術方案的架構設計缺陷與糟糕的用戶體驗做出了嚴厲的批判。不過在這段時間當中,Docker項目也開始逐步走向成熟,迎來自己的 1.0版本 并在Amazon的推動下 聲名大噪 ,但同時用戶挫敗感、 過度宣傳 引發的指責甚至因 漏洞遭利用 而引發主機感染越來越多。當然, Docker Hub 中私有庫的引入讓用戶不必再為了托管部署而運行自有Registry系統,再配合webhook以及同GitHub的緊密 集成 , Docker看起來有一個良好的前途。

有鑒于此,我決定再給Docker一次機會,并以六個月為周期將其引入生產環境。結果非常糟糕,Docker性能極差,而旁門左道的解決方案加上以用戶體驗為代表的種種短板簡直令人抓狂。實際上,Docker的性能表現實在太差,禁用緩存功能竟然能夠加快build速度。

(感興趣的朋友可以查看 redditycombinator 網站上與該主題相關的討論內容)。

Dockerfile

Dockerfile存在著一系列問題,它令人討厭、充滿局限、不倫不類而且包含根本性缺陷。假如要構建一個庫的多個鏡像,例如第二個鏡像包含內容調試工具,但兩個鏡像擁有同樣的基礎運行要求。Docker不支持這種做法(詳見 9198號問題 ),我們無法擴展Dockerfile(詳見 735號問題 ),使用子目錄會破壞構建上下文并導致用戶無法使用ADD/COPY(詳見 2224號問題 )或者“管道(piping)”(詳見 2112號問題 ),我們也不能在構建過程中通過環境變量實現有條件的指令變更(詳見 2637號問題 )。

我們給出的 解決方案 是創建一個基礎鏡像,兩個特定環境的鏡像以及其它一些包括重命名以及sed替換功能的Makefile自動化。除此之外,Docker中還有一些意想不到的“ 功能 ”有可能導致環境變量$HOME消失,進而產生無用的錯誤信息。太令人厭惡了。

Docker緩存/層

Docker有能力利用COW(即寫入時復制)文件系統實現 緩存 Dockerfile指令,這一點與LVM 快照機制 相似,而且直到最近都只支持AuFS,而后者還存在大量問題。之后, 0.7版本 引入了多種不同的COW實現方式以改進穩定性與性能,感興趣的朋友可以 點擊此處 了解更多細節信息。

然而,這套緩存系統不智能,它不能阻止單一指緩存(詳見 1996號問題 ),產生了一些意料之外的 副作用 。它的運行速度也極為緩慢,如果禁用緩存并避免使用層,其構建速度甚至能夠得到提升。而Docker Hub緩慢的上傳/下載速度則讓情況進一步惡化,這個問題我們將在下文作進一步評述。

這些問題均源自Docker整體所采用的糟糕的架構設計,這直接導致它即使是在完全不適用的情況下,依然會強制執行線性指令(詳見 2439號問題 )。作為構建緩慢的解決方案,可以使用支持異步執行的第三方工具,例如 Salt StackPuppet 甚至 bash ,它們完全能夠達成層的目的而使層變得沒用。

Docker Hub

Docker鼓勵用戶通過Docker Hub進行社會化合作。用戶可以在上面發布Dockerfile——包括公開與私有文件。其他用戶可以通過 FROM 指令而不是復制/粘貼來繼承并使用這些Dockerfile。該生態系統類似于AWS 市場 以及Vagrant Boxes 中的AMI,從理論上講還是非常有用的。

然而由于一些原因,Docker Hub的實現存在缺陷。Dockerfile不支持多FROM指令(詳見 3378號5714號 以及 5726號問題 ),這意味著只能繼承單個鏡像。此外,它沒有版本強制。舉例來說,dockerfile/ubuntu:14.04的作者可以替換該標簽的內容,這相當于 允許用戶使用軟件包管理器但又不沒有版本強制機制。而且正如下文所提到,Docker Hub在這方面存在著令人沮喪的速度緩慢的限制。

Docker Hub還擁有一套自動化構建系統,能夠檢測到庫中新提交內容并觸發容器構建。因為許多原因,這項功能也是完全沒用。由于幾乎不能定制,構建配置受到了極大 限制,甚至無法支持最基本的腳本執行前/后的鉤子。Docker Hub采用一套特殊的項目結構,一個項目下只能有一個Dockerfile,這破壞了我們先前提到的構建解決方案,而且構建速度極為緩慢。

我們的解決方案是使用 CircleCI ,它是一個優秀的托管CI平臺,能夠從Makefile觸發Docker構建并推送到Docker Hub。雖然這種方式無法解決速度慢的問題,但唯一的可選方案是使用我們自己的Docker Registry,其 復雜程度 都到了荒唐的地步。

安全性

Docker最初使用LXC作為默認執行環境,但現在,0.9版本默認使用libcontainer。這使得用戶可以 調整 命名空間功能、權限,并且可以在使用合適的exec-driver時使用自定義的LXC 配置文件

這需要一直在主機上運行一個root守護進程,而且Docker一直存在著 若干 安全漏洞,例如 CVE-2014-6407 以及 CVE-2014-6408 。坦率地講,這些問題起初就不應該存在。甚至Gartner公司也在其 追蹤報告 中給出了糟糕評價,并表達了對Docker的不成熟和安全性問題的 擔憂

按照設計,Docker對于命名空間 功能 給予充分信任,這就導致其攻擊面要比其它典型的虛擬機管理程序更寬。Xen擁有 129 項CVE,相比之下Linux則擁有 1279 項。在某些情況下上述問題并非不可接受,例如在Travis CI當中進行公開構建,但這對于私有、多用戶環境來說無疑是危險的。

容器與虛擬機并不是一回事

命名空間與cgroups功能 極為強大 ,允許一個進程及其子進程擁有一個共享內核資源——例如網絡堆棧以及進程表——的私有視圖。這種細粒度控制與隔離機制配合上chroot jailing與 grsec ,能夠提供非常出色的保護層。一些應用程序,如 uWSGI ,可以在沒有Docker的情況下直接利用這些特性的優點,而不支持命名空間的應用程序則可以利用 firejail 實現沙箱化處理。如果您有冒險精神,可以將這種支持直接添加到自己的容器化項目的 代碼 中,例如LXC以及Dokcer,從而在單一內核空間中利用這些特性的有點高效地運行多套發行版。 相較于 虛擬機管理程序,這種作法有時候會有降低內存使用率和減少啟動時間的好處,但其代價就是降低安全性、穩定性以及兼容性。舉個與 Linux Kernel Interface 相關的最糟糕的 極端案例 ,在內核及用戶空間中運行不兼容或者未經測試的glibc組合版本很可能引發意料之外的行為。

早在2008年LXC尚處于構思階段時,硬件輔助虛擬化也僅僅誕生了幾年時間,許多虛擬機管理程序都存在著性能以及穩定性問題。因此,虛擬化技術并沒有得 到廣泛應用,而面對成本以及物理基礎設施占用減少等優勢,上述問題是可以接受的。不過如今我們的虛擬機管理程序在性能表現方面幾乎與裸機設備不相上下,而 且有趣的是,在 某些情況 下速度更快。另外,托管的、按需分配的虛擬機速度越來越快,成本越來越低, DigitalOcean 在性能與成本方面都要遠遠勝過EC2,這也使應用程序與虛擬機之間進行一對一映射從經濟角度講成為可能。

[編輯意見]正如 Bryan Cantrill 提出的 觀點 ,虛擬化技術的性能將受到工作負載類型的顯著影響。例如,IO任務繁重的應用程序會導致性能 降低

在某些特定的應用場景中,容器化確實是恰當的解決方案,不過除非能夠明確說明為什么在你的應用場景中選擇此類處理方式,否則你可能應用使用虛擬機管理程序 代替。而且即使使用虛擬化技術方案,你仍然應該利用命名空間的優點,而在應用程序沒有對這些特性提供原生支持的情況下,像 firejail 這樣的工具可以提供幫助。

Docker并不是必須的

Docker增加了一個復雜的侵入層,使開發、故障排查以及調試工作的難度大幅上升,它帶來的問題往往多于它能夠解決的問題。它在部署上也沒有 任何優勢,因為你仍然需要利用快照實現響應式自動擴展。更糟糕的是,如果大家并沒有使用快照機制,那么生產環境的擴展就會依賴于Docker Hub的穩定性。

目前有不少項目都在濫用容器化技術,例如 baseimage-docker ,該鏡像旨在通過運行作為入口的init.d簡化檢查、調試和兼容,甚至還提供一個可選的SSH服務器,實際上是將容器當作虛擬機對待,雖然作者本人以 無甚說服力的言詞 反對這種觀點。

總結

如果開發流程合乎情理,那么你已經明白Docker不是必須的。Docker中號稱能夠帶來助益的全部功能要么完全無用,要么實現很差,而其最大的優勢直接使用命名空間就很容易實現。如果放在8年前,Docker是一個有趣的概念,但以現在的眼光來看,它幾乎是沒用的。

修正/改進

從表面上看,Docker還有很多事情要做。它的生態系統鼓勵開發人員傾向于“ 不可變部署(immutable deployment) ”這樣一種理念,新項目能夠更快更 輕松 的地完成,在這一點上其實用性確實得到了許多數人的肯定。然而需要注意的是,這篇文章的主旨在于探討Docker的日常使用和長遠使用,包括在本地及生產環境中。

盡管前面提到的大部分問題都清晰易懂,但文章并沒有提及Docker如何才能做得更好。有許多可選的方案可以替代Docker,每種方案中都有自己的優點和不足,而我將在接下來的文章中進行詳細闡述。

感興趣的讀者可以查看 a-komarkbnj 的進一步討論,前者討論了容器化的長遠影響,后者從技術上進行了反駁,你可能會覺得它們都非常有用。

我要對在百忙中抽出時間給出個人反饋意見的每位朋友表示由衷的感謝。看到文章受到大家的關注確實令人倍感振奮,而且在讀過多位工程技術大牛——其中包括許多年來都一直給我啟發的那些人——的回應后,我也頗有種誠惶誠恐之感。

查看英文原文: Lets review.. Docker (again)

</div>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!