Categories
程式開發

Kubernetes 並不適合大多數團隊


如果你已經在使用 Docker 了,那麼下一步很自然的就是要應用 Kubernetes。

在開發同一應用程序時,5 個軟件工程師設計的解決方案、與 50 個軟件工程師、500 個軟件工程師設計的肯定不同。因此,如果你是在一個小團隊中,Kubernetes 可能不是一個好的選擇,它會帶來很多痛苦,但好處卻微乎其微。

為什麼這麼說呢?

Kubernetes 應用存在哪些問題?

Kubernetes 有大量的活動部件——概念、子系統、過程、機器、代碼,這就意味著會有大量的問題。

多機器

Kubernetes 是一個分佈式系統:有一台控制工作機器的主機器,工作被安排在不同的工作機器上。然後,每台機器在容器中運行工作。

如果你的工作只需要兩台機器或者虛擬機來完成,那麼使用 Kubernetes,你可能就需要擴展,需要 3 個、4 個或者更多的虛擬機。

多代碼

截至 2020 年 3 月初,Kubernetes 的代碼庫中已有超過 58 萬行 Go 代碼。這是實際的代碼行數,沒有計算註釋或空白行,也沒計算供應商的包。

2019 年的安全審查 這樣描述其代碼庫:

……Kubernetes 的代碼庫有很大的改進空間。該代碼庫龐大而復雜,大部分代碼只包含很少的文檔和大量的依賴關係,包括 Kubernetes 外部的系統。在代碼庫中有很多邏輯重新實現的情況,可以集中到支持庫中,從而降低複雜性,簡化補丁,並減少代碼庫中不同區域的文檔負擔。

坦率來講,Kubernetes 與其它大型項目沒有什麼不同,如果想要應用程序不奔潰且更好的運行,那麼研究代碼是必須要做的工作。

複雜性

Kubernetes 是一個複雜的系統,包含許多不同的服務、系統和部件。

在運行單個應用程序之前,你需要以下高度簡化的架構:

Kubernetes 並不適合大多數團隊 1

K8s 文檔中的概念文檔包含許多這樣的講解說明:

在 Kubernetes 中,EndpointSlice 包含對一組網絡端點的引用。在指定選擇器時,EndpointSlice 控制器自動為 Kubernetes 服務創建 EndpointSlice。這些 EndpointSlices 將包含任何與服務選擇器匹配的 Pod 引用。 EndpointSlice 通過唯一的服務和端口組合將網絡端點分組。

在默認情況下,EndpointSlice 控制器管理的每個 EndpointSlice 的端點不超過 100 個。在這個範圍內,EndpointSlice 應該與端點和服務進行 1:1 的映射,並且具有類似的性能。

僅僅這一段文字中就包含了很多的概念,例如 EndpointSlice、服務、選擇器、Pod 和端點。但在實際應用中,有時你根本都用不到這些功能。

默認情況下,發送到 ClusterIP 或 NodePort 服務的流量可能被路由到該服務的任何後端地址。從 Kubernetes 1.7 開始,就可以將“外部”流量路由到在接收流量的節點上運行的 Pods,但這不支持 ClusterIP 服務,而且,也不可能實現更複雜的拓撲結構(如分區路由)。服務拓撲特​​性解決了這個問題,它允許服務創建者根據源節點和目標節點的節點標籤定義流量路由策略。

安全審查是這樣評價 Kubernetes 的:

Kubernetes 是一個龐大的系統,操作非常複雜。評估團隊發現 Kubernetes 的配置和部署非常複雜,某些組件的默認設置令人困惑、缺少操作控制和隱式定義的安全控制。

另外,Kubernetes 的開發複雜性也很高,當你越多的使用 Kubernetes,就會越難進行平常的開發,需要了解各種概念之後才能運行代碼,如 Pod、部署、服務等。同樣測試時,也需要通過 VM 或嵌套的 Docker 容器啟動完整的 Kubernetes 系統。

由於應用程序很難在本地運行,開發也就更困難了,所以各種各樣的解決方案也就應運而生了,從過渡環境,到將本地進程代理到集群,再到將遠程進程代理到本地機器……

雖然解決方案很多,但是有些方案也不完善,所以我認為最好也是最簡單的解放方案是不使用 Kubernetes。

微服務

當系統允許運行多服務時,很容易就會編寫許多服務。其實,這並不是個好主意。

首先,分佈式應用程序很難編寫,服務越多,問題就會越多。

其次,分佈式應用程序很難調試,可能需要新的工具和日誌記錄來調試。

微服務其實是一種組織層面的擴展技術,當500 名開發人員在共同開發一個網站時,不同的開發團隊需要獨立工作,這時支付大規模分佈式系統的成本是有意義的,如果是一個5 人團隊,微服務是沒有意義的。

Kubernetes 是不是就沒用了呢?

上面講了這麼多 Kubernetes 應用時的問題,那是不是說明 Kubernetes 完全沒用呢?當然不是。

擴展性

如果你需要大規模的擴展,Kubernetes 可能會很有用。

你可以得到最多 416 個 vCPU 和 8TiB RAM 的雲 VM,雖然會很貴,但也很簡單。

你可以使用像 Heroku 這樣的服務來擴展許多簡單的 Web 應用程序。

不過,大多數應用程序不需要擴展太多,一些合理的優化就足夠了。

許多 Web 應用程序的擴展其瓶頸通常是數據庫,而不是 Web 工作進程。

可靠性

活動部件越多,就意味著出錯的機會越多。

Kubernetes 內置了很多特性(健康檢查、滾動部署),可以使得可靠性變得更簡單,例如,Nginx 可以對工作進程執行健康檢查,使用 docker-autoheal 或類似的東西自動重啟進程。

如果你關心的是停機時間,那麼第一個想法不應該是“如何將部署停機時間從1 秒減少到1 毫秒”,而應該是“如何確保數據庫模式更改不會妨礙我在事情搞砸時進行回滾”。

如果你只是想要一個可靠的 Web 工作進程,不存在單機故障點,那麼有很多方法可以做到這一點,不必使用 Kubernetes。

最佳實踐?

沒有所謂的最佳實踐,只有針對特定情況的最佳實踐。

我們不能僅僅因為某件事很流行,就認為它是正確的選擇。在某些情況下,Kubernetes 是一個非常好的主意,但在另一些情況下,這是一種毫無益處的時間陷阱。

在我看來,除非你的應用程序真的複雜到必須使用 Kubernetes,否則使用其它工具也可以很好的完成工作,例如單機 Docker Compose、類似 Heroku 的系統、用於計算管道的 Snakemake 等等。

原文鏈接:

https://pythonspeed.com/articles/dont-need-kubernetes