也許你不需要 Kubernetes
原文由 Matthias Endler 于 發布,訂閱此部落格
來源:插圖由 freepik 製作,Nomad 標誌由 HashiCorp 提供。
Kubernetes 是容器編排領域中難以忽視的巨頭。
它支撐著全球許多最大規模的部署,但也伴隨著不小的代價。
對於規模較小的團隊來說,維護它既耗時,學習曲線又陡峭。對於我們這個在 trivago 的四人小團隊想達成的目標而言,它帶來的額外負擔太大了。因此我們開始尋找替代方案——然後愛上了 Nomad。
願望清單
我們團隊負責維運許多用於監控與效能分析的典型服務:用 Go 撰寫的 metrics API 端點、Prometheus exporter、像 Logstash 或 Gollum 這類的日誌解析器,以及像 InfluxDB 或 Elasticsearch 這樣的資料庫。這些服務各自跑在獨立的容器中。我們需要一套簡單的系統來讓這些任務持續運作。
我們一開始列出了對容器編排的需求:
- 在多台機器上運行一系列服務。
- 提供運行中服務的總覽。
- 讓服務之間能夠互相溝通。
- 當服務掛掉時能自動重新啟動。
- 能由小團隊維運管理。
除此之外,以下幾點是有會更好,但並非絕對必要的:
- 能依機器的能力加上標籤(例如,為 I/O 密集的服務標記配備高速磁碟的機器。)
- 能夠在不依賴任何編排工具的情況下獨立運行這些服務(例如在開發環境中)。
- 有一個共用的地方可以分享設定與機敏資訊。
- 提供用於 metrics 與日誌收集的端點。
為什麼 Kubernetes 不適合我們
在用 Kubernetes 打造原型時,我們發現自己開始為了維運服務而疊加一層又一層愈來愈複雜的邏輯。而我們也開始在無形中依賴這些邏輯。
舉例來說,Kubernetes 允許使用 ConfigMaps 來嵌入服務設定。特別是在合併多個設定檔或在同一個 Pod 中加入更多服務時,情況很快就會變得相當混亂。Kubernetes——或者說 helm——允許動態注入外部設定,以確保關注點分離。但這可能導致你的專案與 Kubernetes 之間產生緊密、隱晦的耦合。Helm 和 ConfigMaps 都是選用功能,你不一定要用它們。你大可直接把設定檔複製到 Docker 映像檔裡就好。然而,走上那條路、建立不必要的抽象層的誘惑很大,之後很可能會反過來咬你一口。
除此之外,Kubernetes 的生態系仍在快速演進中。要跟上最佳實踐與最新工具,需要花費相當多的時間與精力。Kubectl、minikube、kubeadm、helm、tiller、kops、oc——清單長到念不完。雖然要入門 Kubernetes 並不需要用到所有工具,但很難判斷哪些才是必要的,所以你至少得對它們有所認識。也正因如此,它的學習曲線相當陡峭。
什麼時候該用 Kubernetes
在 trivago 內部,確實有許多團隊使用 Kubernetes,而且用得很滿意。不過這些叢集是由 Google 或 Amazon 代管的,他們才有能力這樣做。
Kubernetes 帶來了許多令人驚豔的功能,讓大規模的容器編排變得更容易管理:
- 細緻的 權限管理
- 自訂控制器能讓你把邏輯放進叢集中。它們其實就是與 Kubernetes API 溝通的程式。
- 自動擴縮!Kubernetes 能根據需求自動擴展或縮減你的服務。它利用服務的 metrics 來做到這一點,無需人工介入。
問題在於,你是否真的需要所有這些功能。你不能指望這些抽象層自己就能正常運作;你必須搞懂底層到底發生了什麼事。
特別是像我們這樣的團隊,大多數服務都跑在地端(因為與 trivago 的核心基礎架構緊密相連),我們並不想花成本去自建、維運一個 Kubernetes 叢集;我們只想專心把服務交付出去。

不附電池
Nomad 是能讓你完成 80% 任務的那 20% 服務編排功能。它所做的就只是管理部署。它負責處理你的 rollout,並在出錯時重新啟動容器——大概就是這樣。
Nomad 的核心精神就是它做得更少:它不包含細緻的權限管理或進階網路政策,而這是刻意為之的。那些功能要就作為企業版服務提供,要就由第三方提供——或者根本沒有。
我認為 Nomad 在易用性與表達能力之間取得了絕佳的平衡。它很適合用來運行小型、彼此大致獨立的服務。如果你需要更多的控制,就得自己打造,或改用別的方案。Nomad 就只是個編排工具。
Nomad 最棒的地方在於它很容易被替換。幾乎沒有廠商鎖定的問題,因為它提供的功能可以輕易整合到任何其他管理服務的系統中。它只是在叢集中的每台機器上跑一個再普通不過的單一執行檔;就是這樣!
Nomad 鬆散耦合的生態系
Nomad 真正的強大之處在於它的生態系。它與其他——完全選用的——產品整合得非常好,像是 Consul(一個 key-value store)或 Vault(用於處理機敏資訊)。在你的 Nomad 檔案中,你可以加入用來從這些服務抓取資料的區段:
template {
data = <<EOH
LOG_LEVEL="{{key \"service/geo-api/log-verbosity\"}}"
API_KEY="{{with secret \"secret/geo-api-key\"}}{{.Data.value}}{{end}}"
EOH
destination = "secrets/file.env"
env = true
}這段設定會從 Consul 讀取 service/geo-api/log-verbosity 這個 key,並在你的任務中將它暴露為 LOG_LEVEL 環境變數。同時,它也會從 Vault 讀取 secret/geo-api-key 並暴露為 API_KEY。簡單,卻很強大!
正因為如此簡單,Nomad 也能透過 API 輕易地與其他服務擴充整合。舉例來說,可以為任務加上標籤來做服務探索。在 trivago,我們會為所有會暴露 metrics 的服務貼上 trv-metrics 標籤。這樣 Prometheus 就能透過 Consul 找到這些服務,並定期抓取 /metrics 端點以取得新資料。日誌也可以用同樣的方式,透過整合 Loki 等工具來處理。
還有許多其他擴充性的例子:
- 使用 webhook 與 Consul watches 來觸發 Jenkins 任務,在服務設定變更時重新部署你的 Nomad 任務。
- 使用 Ceph 為 Nomad 加上分散式檔案系統。
- 使用 fabio 來做負載平衡。
這一切讓我們得以在不需要太多前期投入的情況下,有機地擴展我們的基礎架構。
先提醒一下
沒有任何系統是完美的。我會建議你現在先別在正式環境中使用任何花俏的新功能。當然,還是會有 bug 和 缺失的功能——但 Kubernetes 也一樣有這些問題。
與 Kubernetes 相比,Nomad 背後的動能要小得多。到目前為止,Kubernetes 已累積了約 75,000 次 commit 與 2,000 名貢獻者,而 Nomad 則約有 14,000 次 commit 與 300 名貢獻者。Nomad 要跟上 Kubernetes 的開發速度會很困難,但或許它根本不需要!它的範疇要窄得多,而較小的社群也可能意味著,相較於 Kubernetes,你的 pull request 更容易被接受。
總結
結論就是:不要只因為大家都在用就跟著用 Kubernetes。仔細評估你的需求,看看哪個工具才真正符合需要。
如果你打算在大規模基礎架構上部署大量同質性的服務,Kubernetes 可能是正確的選擇。只是要留意額外的複雜度與維運成本。這些成本中有一些可以透過使用像是 Google Kubernetes Engine 或 Amazon EKS 這類代管式 Kubernetes 環境來避免。
如果你只是在尋找一個可靠、易於維護且可擴充的編排工具,何不試試 Nomad?你可能會驚訝它能帶你走多遠。
如果把 Kubernetes 比作汽車,那 Nomad 就是速克達。有時你會偏好其中一種,有時則是另一種。兩者都有其存在的價值。
隨機一篇部落格
留言
登入後參與討論