
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手段,給企業級客戶的負載提供更穩定可預期的性能。
ECS執行個體類型 | 第六代裸金屬執行個體 | 六代虛拟機執行個體 |
---|---|---|
CPU | 目前包含80/104兩種規格 | 2~104 |
CPU與記憶體配比 | 1:1.8 ~ 1:7.4 | 1:2 ~ 1:8 |
虛拟化資源開銷 | 沒有 | 極小 |
GPU支援 | 是 (部分型号) | |
支援Intel SGX | 否 | |
支援安全沙箱容器(如KataContainer, 阿裡雲安全沙箱容器等) | 是 | |
支援License綁定硬體 | 是 (DDH支援) | |
支援熱遷移 | 否 (支援當機遷移) |
一般而言建議:
- 對性能極其敏感的應用,如高性能計算,裸金屬執行個體是較好的選擇。
- 如果需要Intel SGX,或者安全沙箱等技術,裸金屬執行個體是不二選擇。
- 六代虛拟機執行個體基于神龍架構,I/O性能有了顯著提升,同時有更加豐富的規格配置,可以針對自身應用需求靈活選擇,降低資源成本。
- 虛拟機執行個體支援熱遷移,可以有效降低運維成本。
阿裡雲ACK K8s叢集支援多個節點伸縮組(AutoScalingGroup),不同彈性伸縮組支援不同的執行個體規格。在工作實踐,我們會為K8s叢集劃分靜态資源池和彈性資源池。通常而言,固定資源池可以根據需要選擇裸金屬或者虛拟機執行個體。彈性資源池建議根據應用負載使用合适規格的虛拟機執行個體來優化成本、避免浪費,提升彈性供給保障。
此外由于裸金屬執行個體一般CPU核數非常多,大規格執行個體在使用中的挑戰請參見下文。
較少的大規格執行個體還是較多的小規格執行個體?
一個引申的問題是,如何選擇執行個體規格?我們清單對比一下
較少的大規格執行個體 | 較多的小規格執行個體 | 備注 | |
---|---|---|---|
節點管理開銷 | 較低 | 較高 | |
作業系統額外開銷 | |||
節點部署密度 | |||
節點排程複雜性(如NUMA) | 部署密度增加之後,需要更加合理的資源排程來保障應用SLA | ||
節點穩定性 | 随着部署密度增加,節點自身的穩定性也會随之下降 | ||
節點失效爆炸半徑 | 較大 | 較小 | 一個大規格執行個體失效,會影響更多的應用容器。也需要預留更多的資源進行當機遷移。 |
Master元件壓力 | Worker節點數量是影響Master節點容量規劃和穩定性的因素之一。K8s 1.13版本引入的NodeLease功能讓節點數量對master元件的壓力降低很多。 |
預設情況下,kubelet 使用
CFS 配額來執行 pod 的 CPU 限制。當節點上運作了很多 CPU 密集的應用時,工作負載可能會遷移到不同的 CPU 核,工作負載的會受到 CPU 緩存親和性以及排程延遲的影響。當使用大規格執行個體類型時,節點的CPU數量較多,現有的Java,Golang等應用在多CPU共享的場景,性能會出現明顯下降。所有對于大規格執行個體,需要對CPU管理政策進行配置,利用CPU set進行資源配置設定。
此外一個重要的考慮因素就是NUMA支援。在NUMA開啟的裸金屬執行個體或者大規格執行個體上,如果處理不當,記憶體通路吞吐可能會比優化方式降低了30%。Topology管理器可以開啟NUMA感覺
https://kubernetes.io/docs/tasks/administer-cluster/topology-manager/。但是目前K8s對NUMA的支援比較簡單,還無法充分發揮NUMA的性能。
阿裡雲容器服務提供了 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叢集生命周期非常簡單,可以有效解決這個問題。
我們可以比較一下這兩種選擇
單一大叢集 | 多個應用為中心叢集 | |
---|---|---|
爆炸半徑 | 大 | 小 |
硬多租(安全、資源強隔離) | 複雜 | 簡單 |
混合排程多種類型資源 (GPU等 ) | ||
叢集管理複雜性 | 較高(自建)/較低(采用托管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可以提升隔離的支援,但是這些技術還未成熟。
另一個需要考慮的方案是Kubernetes自身的可擴充性,我們知道一個Kubernetes叢集的規模在保障穩定性的前提下受限于
多個次元,一般而言Kubernetes叢集小于5000節點。當然,運作在阿裡雲上還受限于雲産品的quota限制。阿裡經濟體在Kubernetes規模化上有豐富的經驗,但是對于絕大多數客戶而言,是無法解決超大叢集的運維和定制化複雜性的。
對于公共雲客戶我們一般建議,針對業務場景建議選擇合适的叢集規模
- 對于跨地域(region)場景,采用多叢集政策,K8s叢集不應跨地域。我們可以利用CEN将不同地域的VPC打通。
- 對于強隔離場景,采用多叢集政策,不同安全域的應用部署在不同的叢集上。
- 對于應用隔離場景,比如SaaS化應用,可以采用單叢集方式支援多租,并加強安全隔離。
- 對于多個大規模應用,可以采用多叢集政策,比如,線上應用、AI訓練、實時計算等可以運作在不同的K8s叢集之上,一方面可以控制叢集規模,一方面可以針對應用負載選擇合适的節點規格和排程政策。
-
- 由于有VPC中節點、網絡資源的限制,我們可以甚至将不同的K8s叢集分别部署在不同的VPC,利用CEN實作網絡打通,這部分需要對網絡進行前期規劃。
如果需要對多個叢集的應用進行統一管理,有如下幾個考慮
- 利用 Kubefed 建構叢集聯邦,ACK對叢集聯邦的支援可以參考 https://help.aliyun.com/document_detail/121653.html
- 利用統一的配置管理中心,比如GitOps方式來管理和運維應用 https://github.com/fluxcd/flux
另外利用托管
服務網格服務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的實踐經驗。