本文同步刊登於個人技術部落格,有興趣關注更多 Kubernetes、DevOps 相關資源的讀者,請務必追蹤從零開始的軟體工程師之旅,喜歡的話幫我按讚分享、歡迎留言、或是許願想要看的文章。
如果有技術問題也可透過粉絲專頁 討論,技術方面諮詢免錢、需要動手做另計 XD。
Borg, Omega and Kubernetes
這是原文完整版本。好讀版請見 Borg Omega and Kubernetes 前世今生摘要
完整英文原文請見 Borg, Omega, and Kubernetes - Lessons learned from three containermanagement systems over a decade
容器作為管理單位 (Container as the unit of management)
圍繞容器建構管理 API,而非圍繞機器,使得資料中心的「Primary key」從機器變成應用。帶來許多好處:
- 應用工程師與維運團隊 (operation team) 不需再煩惱機器與作業系統的細節
- 架構團隊 (infrastructure team) 獲得更多升版或是調度硬體的彈性,實際對應用與開發團隊的影響非常小
- 管理系統收集應用的監測數據 (例如 CPU 與 Memory 使用 metrics),而非機器的監測數據,直接提升應用的監測與自我檢查 (introspection),特別是擴展 (scale-up)、機器錯誤、或是維護時,造成應用移到其他位置時,監測依然可用。
Generic API
容器提供許多切入點給泛用 API (generic API),泛用 API 使資訊在管理系統與應用之間流動,但其實兩者互相不清楚對方的實作細節。
- 在 Borg 中有一系列的 API 連結到所有容器,例如 /healthz 端點回報應用的健康程度給協調管理者 (orchestrator),當發現不健康的應用,自動終止並重啟應用。
- 這個自動修復功能是可靠的分散式系統的基礎。(Kubernetes 也提供類似功能,透過 HTTP 端點或是 exec command 來檢查容器內部的應用)
容器提供、或是提供給容器的資訊,可以透過許多使用者介面呈現。
- Borg 提供可以動態更新的文字狀態訊息,
- Kubernetes 提供 key-value 的 annotation 存放在給個物件的 metadata,這些都能溝通應用。annotation 可以是容器自行設定、或是由管理系統設定 (例如滾動更新版本時標註新版本)。
容器管理系統可以取得容器內部訊息,例如資源使用狀況、容器的 metadata,並傳播給日誌 (logging) 或是監控 (monitoring),例如
- 使用者名稱、
- 監控任務名稱、
- 用戶身分。甚至
- 進一步在節點維護時,提早提供安全終止 (graceful-termination) 的警示。
容器有其他方式可以提供應用導向的監測,例如
- Linux Kernel cgroups 會提供應用的資源使用率,
- 這些資訊可以擴展,並將客製化的 metrics 構過 HTTP API 送出。
- 基於這些資料,進一步開發出泛用工具如自動擴展 (auto-scaler) 與 cAdvisor,他們不需要知道應用的規格就可以記錄 metrics。
- 由於容器本身是應用,因次不需要在實體或虛擬機器、與多個應用之間,做信號多工轉發或多路分配 (multiplex / demultiplex signals)。這樣更簡單、更堅固、並且可以產生精度更高的 metrics 與日誌,並提供更精細的控制操作。
- 你可以對比使用 ssh 登入機器,並且使用 top 指令監測。雖然工程師可以 ssh 登入容器,但很少需要這樣做。
應用導向變遷在管理架構上產生更多回響,監測只是其中一個。
- Google 的附載均衡器 (load balancer) 不再根據機器做附載均衡,而是根據應用實體 (application instances)。
- 日誌會根據應用打上標籤 (key) 而不是機器,因此可以跨機器的收集所有相同應用的日誌,而不會影響其他的應用日誌或是影像作業系統。
- 我們可以檢測應用失效,更容易的描述錯誤原因,不需要先拆解處理機器的各層信號。
- 由於容器實體的身分資訊,從基礎上都是由容器管理系統控制,工程師可以明確的指定應用的執行身分,使得應用更容易建構、管理、除錯。
最後,雖然上述都針對容器與應用在一對一的狀況下,但實務上我們需要套裝的容器群 (nested containers),這群容器一起排程到相同機器上,最外層的容器提供資源,內層的容器提供部屬的隔離。
- Borg 中,最外層容器叫做資源分配 (resource allocation or alloc),
- 在 Kubernetes 上稱做 Pod。
- Borg 允許最上層的應用直接跑在外層的 alloc 上,但這點產生了一些不便,所以這點在 Kubernetes 做了調整,
- Kubernetes 的應用永遠跑在最外層 Pod 的內部,就算只有單一一個容器。
一個常見的使用情境,是一個 Pod 內部跑一個複雜的應用,
- 大部分的應用都是一個一個子容器 (child containers),
- 其他的子容器則執行輔助工具,例如 log rotation 或是將日誌移轉到分散式檔案系統。
- 對比把上述功能都打包到 binary 執行檔中,拆分更容易讓不同團隊各自開發負責的功能,
- 拆分還提供更好的耐用程度 (就算主要應用終止,子容器仍能成功將日誌移轉出去),
- 更容易組裝應用 (composability) (由於每個服務都是獨立運作在各自的容器中,因此可以直接增加新的支援服務),
- 提供更精細的資源隔離 (所有容器資源隔離,所以日誌服務不會搶占主要應用的資源,反之亦然)。
明日待續:容器管理應用,協調管理只是開始,而不是終點 (Orchestration is the beginning, not the end)