我為什麼不用 Docker?

2021.12.02

實際上令我比較詫異的是越來越多的人選擇使用甚至是在生產環境透過 Docker 部署環境並配置服務, 就我個人而言是從來不在任何測試或生產伺服器使用 Docker 的. 在這里便開門見山地簡單記述些許不使用 Docker 的考量.

運行效率低

這一點是毋庸置疑的. 在 Docker 的邏輯模式下會透過主機內核調度盡可能多的系統資源, 而在較低配置的設備上如果不對容器可以調用的資源加以限制, 則會使得作業系統為確保重要系統功能的穩定運行而關閉其他進程, 由於 Docker 在作業系統中的守護進程優先級並不高, 被關閉的錯誤進程自然也可能會包括 Docker 本身. 加之其與作業系統之間的附加層, 盡管容器本身並不包含完整的虛擬作業系統, 但也會在一定程度上影響運行效率. 特別是雲上業務的發展下, 在伺服器上建立虛擬化再創建容器的套娃行為實在愈發多見又不應該. 關於這一點也有一些數據可以說明, 以 MongoDB 的延時測試為例:

  • Containerized MongoDB 1,000 Sequential Insert Time: ~775ms
  • Containerized MongoDB 1,000 Concurrent Insert Time: ~429ms
  • Native MongoDB macOS 1,000 Sequential Insert Time: ~422ms
  • Native MongoDB macOS 1,000 Concurrent Insert Time: ~311ms

測試 數據來源 也已經由 Web Arvchive 存檔, 圖表可供查閱.

安全隱患較多

有個非常可笑的觀點是認為 Docker 將各類服務分解, 透過容器化的隔離提高了安全性. 這種觀點首先 忽略了在作業系統中運行 Docker 守護進程時所有的 Docker 進程都在主機上繼承這一權限 的事實, 不論是 root 權限運行亦或透過創建非特權用戶身份運行, 其隔離性之低都將安全性完全置於 Docker 本身的實現上, 而大多數的 Docker 又都來自於網路上的現成模板, 絕對提高了安全隱患, 這一點類似於沙盒逃逸的概念而又比其更顯而易見. 另一方面, 持有這種觀點的人還忽略了 Docker 的這種所謂隔離都可能會導致其為獲得最大效率而出現資源濫用帶來的系統隱患, 特別是默認配置下沒有命名空間進一步損害了 Docker 資源調度之間的安全性.

數據安全性堪憂

這主要是由於 Docker 的數據遷移性較差, 目前為止 Docker 的數據主要創建並存儲於容器層, 不僅不同進程之間難以互相調度和檢索數據, 特別是遷移也無法輕松完成. 而對 Docker 數據備份的相關方案也都又重又難用. 不僅如此, 在容器被關閉後其數據也一並丟失, 這一點更是對數據安全性而言是毀滅性的.

其他方面的缺陷

向後兼容性較差

在這種支離破碎的生態系統下, 對於 Docker 版本疊代帶來的問題似乎已經是坊間遍野的事了, 如果能夠對 Docker 版本疊代帶來的前後兼容性問題處理得當自然是好, 但如果不能那形形色色資源依賴各不相同的容器便是維護人員的噩夢了.

容器間互動性較差

且不論多個伺服器之間的眾多容器互動了, 即便是在單個伺服器上的容器之間建立和維護數據交換也是大費心思精力的事情. 即便有 Docker Compose 之類的工具, 但這類補丁式的實現著實笨重又不好用, 將 Docker 生態系統和服務體系本身的支離破碎更大程度上表現了出來.

資源占用過多

在上文的運行效率低部分中雖然已經提到了 Docker 的資源濫用問題, 但這里還是要從另一個角度來審視 Docker 的資源使用. 往往用戶透過 Docker 部署和實現自己的某個服務, 而這一服務如果直接按找標準的規範來配置在作業系統的守護進程中, 沒有了 Docker 附加層不僅會更加輕便高效, 還能減去 Docker 服務耗費的無效資源. 同樣是運行這一套服務, 為何要花費一筆完全沒有必要的開銷呢?

小結

盡管從客觀公正地角度很想要順帶說明 Docker 的所謂優勢, 比如一些場景下對用戶更加友好和一鍵式, 但這一點完全只是將部署服務的知識成本推後了, 當不可避免地需要升級或維護, 你依然需要理解相關服務的運作和配套體系為自己的省事買單. 諸如此類, 我也實在不想贅述 Docker 所謂的便利性或什麼優勢了, 盡管這樣看起來可能並不夠客觀, 但本文本身也並不意在對 Docker 作定性或評價, 完全是單方面地講述自己規避使用 Docker 的考量. 正如此, 我在目前並沒有在任何環境下使用 Docker 容器, 在可見的將來也會如此.