
作者 | 易立 阿裡雲資深技術專家
導讀:Kubernetes 已經成為企業新一代雲 IT 架構的重要基礎設施,但是在企業部署和運維 Kubernetes 叢集的過程中,依然充滿了複雜性和困擾。
阿裡雲容器服務自從 2015 年上線後,目前托管着上萬的 K8s 叢集來支撐全球各地的客戶。我們對客戶在規劃叢集過程中經常會遇見的問題,進行一些分析解答。試圖緩解大家的“選擇恐懼症”。
如何選擇 Worker 節點執行個體規格?
裸金屬還是虛拟機?
在 Dimanti 2019 年的容器調查報告中,對專有雲使用者選擇裸金屬伺服器來運作容器的主要原因進行了分析。
- 選擇裸金屬伺服器的最主要原因(超過 55%)是:傳統虛拟化技術 I/O 損耗較大;對于 I/O 密集型應用,裸金屬相比傳統虛拟機有更好的性能表現;
- 此外近 36% 的客戶認為:裸金屬伺服器可以降低成本。大多數企業在初始階段采用将容器運作在虛拟機的方案,但是當大規模生産部署的時候,客戶希望直接運作在裸金屬伺服器上來減少虛拟化技術的 license 成本(這也常被戲稱為“VMWare 稅”);
- 還有近 30% 的客戶因為在實體機上部署有更少的額外資源開銷(如虛拟化管理、虛拟機作業系統等);還有近 24% 的客戶選擇的原因是:可以有更高的部署密度,進而降低基礎設施成本;
- 超過 28% 的客戶認為,在實體機上可以更加靈活地選擇網絡、存儲等裝置和軟體應用生态。
在公共雲上,我們應該如何選擇呢?2017 年 10 月,阿裡雲“神龍架構”橫空出世。彈性裸金屬伺服器(ECS Bare Metal Instance)是一款同時兼具虛拟機彈性和實體機性能及特性的新型計算類産品,實作超強超穩的計算能力,無任何虛拟化開銷。阿裡雲 2019 年 8 月重磅釋出了彈性計算第六代企業級執行個體,基于神龍架構對虛拟化能力進行了全面更新。
- 基于阿裡自研神龍晶片和全新的輕量化 Hypervisor - 極大減少虛拟化性能開銷。基于阿裡雲智能神龍晶片和全新的輕量化 VMM,将大量傳統虛拟化功能解除安裝到專用硬體上,大大降低了虛拟化的性能開銷,同時使用者幾乎可以獲得所有的主控端 CPU 和記憶體資源,提高整機和大規格執行個體的各項能力,尤其是 I/O 性能有了大幅度提升;
- 使用最新第二代英特爾至強可擴充處理器 - E2E 性能提升。使用最新一代 Intel Cascade Lake CPU, 突發主頻提升至 3.2GHz, 各場景 E2E 性能大幅提升,并在深度學習的多種場景有數倍的提升;
- 給企業級場景帶來穩定和可預期的表現 - 全球最高水準 SLA。針對軟硬體優化以及更加實施更細緻的 QoS 手段,給企業級客戶的負載提供更穩定可預期的性能。
一般而言建議:
- 對性能極其敏感的應用,如高性能計算,裸金屬執行個體是較好的選擇;
- 如果需要 Intel SGX,或者安全沙箱等技術,裸金屬執行個體是不二選擇;
- 六代虛拟機執行個體基于神龍架構,I/O 性能有了顯著提升,同時有更加豐富的規格配置,可以針對自身應用需求靈活選擇,降低資源成本;
- 虛拟機執行個體支援熱遷移,可以有效降低運維成本。
阿裡雲 ACK K8s 叢集支援多個節點伸縮組(AutoScalingGroup),不同彈性伸縮組支援不同的執行個體規格。在工作實踐,我們會為 K8s 叢集劃分靜态資源池和彈性資源池。通常而言,固定資源池可以根據需要選擇裸金屬或者虛拟機執行個體。彈性資源池建議根據應用負載使用合适規格的虛拟機執行個體來優化成本、避免浪費,提升彈性供給保障。此外由于裸金屬執行個體一般 CPU 核數非常多,大規格執行個體在使用中的挑戰請參見下文。
較少的大規格執行個體還是較多的小規格執行個體?
一個引申的問題是,如何選擇執行個體規格?我們清單對比一下:
預設情況下,kubelet 使用 CFS 配額 來執行 pod 的 CPU 限制。當節點上運作了很多 CPU 密集的應用時,工作負載可能會遷移到不同的 CPU 核,工作負載的會受到 CPU 緩存親和性以及排程延遲的影響。當使用大規格執行個體類型時,節點的 CPU 數量較多,現有的 Java,Golang 等應用在多 CPU 共享的場景,性能會出現明顯下降。所有對于大規格執行個體,需要對 CPU 管理政策進行配置,利用 CPU set 進行資源配置設定。
此外一個重要的考慮因素就是 NUMA 支援。在 NUMA 開啟的裸金屬執行個體或者大規格執行個體上,如果處理不當,記憶體通路吞吐可能會比優化方式降低了 30%。Topology 管理器可以開啟 NUMA 感覺 。但是目前 K8s 對 NUMA 的支援比較簡單,還無法充分發揮 NUMA 的性能。
https://kubernetes.io/docs/tasks/administer-cluster/topology-manager/阿裡雲容器服務提供了 CGroup Controller 可以更加靈活地對 NUMA 架構進行排程和重排程。
如何容器運作時?
Docker 容器還是安全沙箱?
在 Sysdig 釋出的 2019 容器使用報告中,我們可以看到 Docker 容器占據市場規模最大的容器運作時 (79%),containerd 是 Docker 貢獻給 CNCF 社群的開源容器運作時,現在也占據了一席之地,并且得到了廠商的廣泛支援;cri-o 是紅帽公司推出的支援 OCI 規範的面向 K8s 的輕量容器運作時,目前還處在初級階段。
很多同學都關心 containerd 與 Docker 的關系,以及是否 containerd 可以取代 Docker?Docker Engine 底層的容器生命周期管理也是基于 containerd 實作。但是 Docker Engine 包含了更多的開發者工具鍊,比如鏡像建構。也包含了 Docker 自己的日志、存儲、網絡、Swarm 編排等能力。此外,絕大多數容器生态廠商,如安全、監控、日志、開發等對 Docker Engine 的支援比較完善,對 containerd 的支援也在逐漸補齊。
是以在 Kubernetes 運作時環境,對安全和效率和定制化更加關注的使用者可以選擇 containerd 作為容器運作時環境。對于大多數開發者,繼續使用 Docker Engine 作為容器運作時也是一個不錯的選擇。
此外,傳統的 Docker RunC 容器與主控端 Linux 共享核心,通過 CGroup 和 namespace 實作資源隔離。但是由于作業系統核心的攻擊面比較大,一旦惡意容器利用核心漏洞,可以影響整個主控端上所有的容器。
越來越多企業客戶關注容器的安全性,為了提升安全隔離,阿裡雲和螞蟻金服團隊合作,引入安全沙箱容器技術。19 年 9 月份我們釋出了基于輕量虛拟化技術的 RunV 安全沙箱。相比于 RunC 容器,每個 RunV 容器具有獨立核心,即使容器所屬核心被攻破,也不會影響其他容器,非常适合運作來自第三方不可信應用或者在多租戶場景下進行更好的安全隔離。
阿裡雲安全沙箱容器有大量性能優化,可以達到 90% 的原生 RunC 性能:
- 利用 Terway CNI 網絡插件,網絡性能無損;
- 利用 DeviceMapper 建構了⾼速、穩定的容器 Graph Driver;
- 優化 FlexVolume 和 CSI Plugin,把 mount bind 的動作下沉到沙箱容器内,進而避開了 9pfs 帶來的性能損耗。
而且,ACK 為安全沙箱容器和和 RunC 容器提供了完全一緻的使用者體驗,包括日志、監控、彈性等。同時,ACK 可以在一台神龍裸金屬執行個體上同時混布 RunC 和 RunV 容器,使用者可以根據自己的業務特性自主選擇。
同時,我們也要看到安全沙箱容器還有一些局限性,現有很多日志、監控、安全等工具對獨立核心的安全沙箱支援不好,需要作為 sidecar 部署在安全沙箱内部。
對于使用者而言,如果需要多租戶隔離的場景,可以采用安全沙箱配合 network policy 來完成,當然也可以讓不同租戶的應用運作在不同的虛拟機或者彈性容器執行個體上,利用虛拟化技術來進行隔離。
注意:安全沙箱目前隻能運作在裸金屬執行個體上,當容器應用需要資源較少時成本比較高。可以參考下文的 Serverless K8s 有關内容。
如何規劃容器叢集?
一個大叢集還是一組小叢集?
在生産實踐中,大家經常問到的一個問題是我們公司應該選擇一個還是多個 Kubernetes 叢集。
Rob Hirschfeld 在 Twitter 上做了一個調查:
- 一個大一統的平台,支援多種應用負載、環境和多租戶隔離;
- 或者,一組以應用為中心的小叢集,支援不同應用和環境的生命周期管理。
大多數的使用者選擇是後者,典型的場景是:
- 開發、測試環境使用不同的叢集
- 不同的部門使用不同的叢集進行隔離
- 不同的應用使用不同的叢集
- 不同版本的 K8s 叢集
在使用者回報中,采用以多個小叢集的主要原因在于爆炸半徑比較小,可以有效提升系統的可用性。同時通過叢集也可以比較好地進行資源隔離。管理、運維複雜性的增加是采用多個小叢集的一個不足之處,但是在公共雲上利用托管的 K8s 服務(比如阿裡雲的 ACK)建立和管理 K8s 叢集生命周期非常簡單,可以有效解決這個問題。
我們可以比較一下這兩種選擇:
源自 Google Borg 的理念,Kubernetes 的願景是成為 Data Center Operating System,而且 Kubernetes 也提供了 RBAC、namespace 等管理能力,支援多使用者共享一個叢集,并實作資源限制。但是這些更多是 “軟多租” 能力,不能實作不同租戶之間的強隔離。在多租最佳實踐中,我們可以有如下的一些建議:
- 資料平面:可以通過 PSP (PodSecurityPolicy) 或者安全沙箱容器,提升容器的隔離性;利用 Network Policy 提升應用之間網絡隔離性;可以通過将 nodes 和 namespace 綁定在一起,來提升 namespace 之間資源的隔離;
- 控制平面:Kubernetes 的控制平面包括 master 元件 API Server, Scheduler, etcd 等,系統 addon 如 CoreDNS, Ingress Controller 等,以及使用者的擴充,如 3 方的 CRD (Customer Resource Definition) controller。這些元件大多不具備良好的租戶之間的安全、資源和故障隔離能力。一個錯誤的 CRD contoller 實作有可能打挂一個叢集的 API Server。
關于 Kubernetes 多租戶實踐的具體資訊可以參考下文。目前而言,Kubernetes 對硬隔離的支援存在很多局限性,同時社群也在積極探索一些方向,如阿裡容器團隊的 Virtual Cluster Proposal 可以提升隔離的支援,但是這些技術還未成熟。
https://www.infoq.cn/article/NyjadtOXDemzPWyRCtdm?spm=a2c6h.12873639.0.0.28373df9R7x2DP https://github.com/kubernetes-sigs/multi-tenancy/tree/master/incubator/virtualcluster?spm=a2c6h.12873639.0.0.28373df9R7x2DP另一個需要考慮的方案是 Kubernetes 自身的可擴充性,我們知道一個 Kubernetes 叢集的規模在保障穩定性的前提下受限于多個次元,一般而言 Kubernetes 叢集小于 5000 節點。當然,運作在阿裡雲上還受限于雲産品的 quota 限制。阿裡經濟體在 Kubernetes 規模化上有豐富的經驗,但是對于絕大多數客戶而言,是無法解決超大叢集的運維和定制化複雜性的。
對于公共雲客戶我們一般建議,針對業務場景建議選擇合适的叢集規模:
- 對于跨地域(region)場景,采用多叢集政策,K8s 叢集不應跨地域。我們可以利用 CEN 将不同地域的 VPC 打通;
- 對于強隔離場景,采用多叢集政策,不同安全域的應用部署在不同的叢集上;
- 對于應用隔離場景,比如 SaaS 化應用,可以采用單叢集方式支援多租,并加強安全隔離;
- 對于多個大規模應用,可以采用多叢集政策,比如,線上應用、AI 訓練、實時計算等可以運作在不同的 K8s 叢集之上,一方面可以控制叢集規模,一方面可以針對應用負載選擇合适的節點規格和排程政策。
由于有 VPC 中節點、網絡資源的限制,我們可以甚至将不同的 K8s 叢集分别部署在不同的 VPC,利用 CEN 實作網絡打通,這部分需要對網絡進行前期規劃。
- 如果需要對多個叢集的應用進行統一管理,有如下幾個考慮;
- 利用 Kubefed 建構叢集聯邦,ACK 對叢集聯邦的支援可以參考。
利用統一的配置管理中心,比如 GitOps 方式來管理和運維應用。
https://github.com/fluxcd/flux?spm=a2c6h.12873639.0.0.28373df9R7x2DP另外利用托管服務網格服務 ASM,可以利用 Istio 服務網格輕松實作對多個 K8s 叢集的應用的統一路由管理。
如何選擇 K8s 或者 Serverless K8s 叢集?
在所有的調查中,K8s 的複雜性和缺乏相應的技能是阻礙 K8s 企業所采用的主要問題,在 IDC 中運維一個 Kubernetes 生産叢集還是非常具有挑戰的任務。阿裡雲的 Kubernetes 服務 ACK 簡化了 K8s 叢集的生命周期管理,托管了叢集的 master 節點被,但是使用者依然要維護 worker 節點,比如進行更新安全更新檔等,并根據自己的使用情況進行容量規劃。
針對 K8s 的運維複雜性挑戰,阿裡雲推出了 Serverless Kubernetes 容器服務 ASK。
完全相容現有 K8s 容器應用,但是所有容器基礎設施被阿裡雲托管,使用者可以專注于自己的應用。它具備幾個特點:
- 首先它按照容器應用實際消耗的資源付費,而不是按照預留的節點資源付費;
- 對使用者而言沒有節點的概念,零維護;
- 所有資源按需建立,無需任何容量規劃。
在 ASK 中,應用運作在彈性容器執行個體 - ECI (Elastic Container Instance)中,ECI 基于輕量虛拟機提供的沙箱環境實作應用安全隔離,并且完全相容 Kubernetes Pod 語義。在 ASK 中我們通過對 Kubernetes 做減法,将複雜性下沉到基礎設施,極大降低了運維管理負擔,提升使用者體驗,讓 Kubernetes 更簡單,讓開發者更加專注于應用自身。除了無需管理節點和 Master 外,我們将 DNS, Ingress 等能力通過阿裡雲産品的原生能力來實作,提供了極簡但功能完備的 Kubernetes 應用運作環境。
Serverless Kubernetes 極大降低了管理複雜性,而且其自身設計非常适合突發類應用負載,如 CI/CD,批量計算等等。比如一個典型的線上教育客戶,根據教學需要按需部署教學應用,課程結束自動釋放資源,整體計算成本隻有使用包月節點的 1/3。
在編排排程層,我們借助了 CNCF 社群的 Virtual-Kubelet,并對其進行了深度擴充。Virtual-Kubelet 提供了一個抽象的控制器模型來模拟一個虛拟 Kubernetes 節點。當一個 Pod 被排程到虛拟節點上,控制器會利用 ECI 服務來建立一個 ECI 執行個體來運作 Pod。
我們還可以将虛拟節點加入 ACK K8s 叢集,允許使用者靈活控制應用部署在普通節點上,還是虛拟節點上。
值得注意的是 ASK/ECI 是 nodeless 形态的 pod,在 K8s 中有很多能力和 node 相關,比如 NodePort 等概念不支援,此外類似日志、監控元件經常以 DaemonSet 的方式在 K8s 節點上部署,在 ASK/ECI 中需要将其轉化為 Sidecar。
使用者該如何選擇 ACK 和 ASK 呢?ACK 主要面向的是基礎設施運維團隊,具備和 K8s 高度的相容性和靈活性控制性。而 ASK 則是面向業務技術團隊或者開發者,使用者完全不需具備 K8s 的管理運維能力,即可管理和部署 K8s 應用。而 ACK on ECI,則同時支援使用者負載運作在 ECS 執行個體或者 ECI 執行個體上,可以允許使用者進行靈活控制。
ACK on ECI/ASK 則可以将彈性的負載通過 ECI 的方式運作,有幾個非常典型的場景:
- 應對突發流量:ECI 基于面向容器的輕量安全沙箱,可以實作 30s 500Pod 的彈性伸縮能力,可以輕松應對突發的業務流量,在面對不确定的業務流量時,可以簡化彈性配置;
- 批量資料處理:我們可以實作 Serverless Spark/Presto 這樣的計算任務, 按需為計算任務配置設定計算資源;
- 安全隔離:有些業務應用需要運作 3 方不可信應用,比如一個 AI 算法模型,ECI 本身利用安全沙箱進行隔離,我們可以利用 ECI 隔離運作相關應用。
ACK on ECI 還可以和 Knative 這樣的 Serverless 應用架構配合,開發領域相關的 Serverless 應用。
總結
合理規劃 K8s 叢集可以有效規避後續運維實踐中的穩定性問題,降低使用成本。期待與大家一起交流阿裡雲上使用 Kubernetes 的實踐經驗。
關于作者
易立,阿裡雲資深技術專家,阿裡雲容器服務的研發負責人。之前曾在 IBM 中國開發中心工作,擔任資深技術專員;作為架構師和主要開發人員負責或參與了一系列在雲計算、區塊鍊、Web 2.0,SOA 領域的産品研發和創新。阿裡雲容器平台團隊求賢若渴!社招技術專家 / 進階技術專家,base 杭州 / 北京 / 深圳。歡迎發履歷到 [email protected]
“ 阿裡巴巴雲原生 關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的技術圈。”