本書談的是分散式系統——由許多不同元件、跑在許多不同機器上組成的應用程式。但第一部卻專門討論存在於單一節點上的模式,理由很直接:容器是本書所有模式的基礎建構區塊,而共同部署在單一機器上的容器群組,正是分散式系統模式的原子元素

動機:為什麼要把單機應用拆成多個容器#

把分散式應用拆到不同機器的理由很明顯,但為什麼單一機器上的元件也要拆成不同容器?關鍵在於容器化的三個目標——容器的邊界(boundary)分別提供:

  • 資源隔離(resource isolation):明確界定「這個應用需要兩核心、8 GB 記憶體」。
  • 團隊所有權(team ownership):明確界定「這個映像檔由這個團隊擁有」。
  • 關注點分離(separation of concerns):明確界定「這個映像檔只做這一件事」。

資源隔離的例子#

  • 假設應用有兩個元件:面向使用者的應用伺服器,與背景設定檔載入器。使用者請求延遲是最高優先,背景載入器則是盡力而為(best-effort)——高流量時稍微延遲也無妨,且不應影響使用者體驗。
  • 拆成不同容器後,可以為兩者設定不同的資源需求與優先級:讓背景載入器在使用者服務負載輕時「機會性地」利用空閒 CPU;當記憶體洩漏等因素造成資源競爭時,也保證背景載入器會先於使用者服務被終止。

團隊擴展與模組重用#

  • 理想團隊規模約六到八人;要用這種小團隊組成建構大系統,就需要小而聚焦、可各自擁有的元件。
  • 元件若切分得當,還能成為跨團隊重用的模組。例如把「本地檔案系統與 Git 原始碼儲存庫同步」做成獨立容器,就能在 PHP、HTML、JavaScript、Python 等各種 Web 服務環境中重用;反之若把 Python 執行環境與 Git 同步綁死在同一個容器裡,這種模組化重用(以及擁有該模組的小團隊)就不可能存在。

關注點分離#

  • 即使應用很小、所有容器都屬於同一團隊,關注點分離也能確保應用容易被理解,並能輕鬆地測試、更新與部署。

小結#

接下來各章的單節點模式,與多節點分散式模式不同——它們假設模式內所有容器之間存在緊密依賴

  • 所有容器可以被可靠地共同排程(coscheduled)到同一台機器上。
  • 所有容器可以選擇性地共享磁碟區(volume)或部分檔案系統,以及網路命名空間(network namespace)、共享記憶體等關鍵容器資源。

這種緊密的群組在 Kubernetes 中稱為 Pod,但概念普遍適用於各種容器編排器,只是原生支援程度不一。