本文主要介紹如何同時保證租戶之間公平地分配共用叢集資源,以最大程度的避免惡意租戶對其他租戶的攻擊。
背景資訊
隔離的安全程度分為軟隔離(Soft Multi-tenancy)和硬隔離(Hard Multi-tenancy)。
軟隔離更多面向企業內部的多租需求,該形態下預設不存在惡意租戶,隔離是為了內部團隊間的業務保護和對可能的安全攻擊進行防護。
硬隔離更多面向對外提供服務的服務供應商,由於該業務形態下無法保證不同租戶中業務使用者的安全背景,預設租戶之間以及租戶與K8s系統之間是存在互相攻擊的可能,因此也需要更嚴格的隔離作為安全保障。
軟多租
您可以使用原生Kubernetes
特性來實現軟多租,例如namespace
、roles
、role bindings
以及network polices
,在租戶之間實現邏輯分離。例如,RBAC
可以防止租戶訪問或操縱彼此的資源。qoutas
和limit ranges
控制每個租戶可以消耗的叢集資源量,而network polices
可以防止部署到不同命名空間的應用程式相互連信。
這些控制措施不能阻止來自不同租戶的Pod
共用一個節點。您可以使用nodeselector
、anti-affinity
規則、taints
和tolerations
來強制將不同租戶的Pod調度到不同的節點上,這通常稱為獨立租戶節點。在租戶數量很多的情境下,這樣做會變得相當複雜且成本過高。
使用Namespaces
實現的軟多租不允許您向租戶提供命名空間的過濾列表,因為命名空間是全域範圍的資來源物件。如果租戶能夠查看指定命名空間,則可以查看叢集內的所有命名空間。
使用軟多租,租戶保留預設情況下為叢集內啟動並執行所有服務查詢CoreDNS
的能力。攻擊者可以在叢集中的任何Pod
中運行dig SRV
..svc.cluster.local
來利用此特性。如果您需要限制對叢集內啟動並執行服務的DNS記錄的訪問,請使用CoreDNS
的防火牆或策略外掛程式。具體操作,請參見kubernetes-metadata-multi-tenancy-policy。
企業內部環境
第一種是在企業環境中,該情境下叢集的所有使用者均來自企業內部,這也是當前很多K8s叢集客戶的使用模式,因為服務使用者身份的可控性,相對來說這種業務形態的安全風險是相對可控的。每個租戶通常會與一個行政部門(例如部門或團隊)保持一致。
在類似這種情境中,叢集管理員通常負責建立命名空間和管理原則。還可以實現託管管理模型,在該模型中,某些個人被賦予對命名空間的監管權,允許他們對非策略相關的對象(如
deployments
、services
、pod
、jobs
等)執行CRUD
操作。Docker提供的隔離機制在此情境中是可以接受的,或者需要增加額外的控制,例如Pod安全性原則 (PSP)。如果需要更嚴格的隔離,還需要限制不同命名空間中服務之間的通訊。
Kubernetes即服務(KaaS)
軟多租戶可用於您希望提供Kubernetes即服務 (KaaS) 的情境之中。使用KaaS,您的應用程式與提供一組PaaS服務的控制器和CRD集合一起託管在共用叢集中。租戶直接與Kubernetes API伺服器互動,並被允許對非策略對象執行CRUD操作。還有自助功能,例如允許租戶建立和管理他們自己的命名空間。在類似此種環境中,租戶被假定正在運行不可信代碼。
要在此類環境中隔離租戶,您可能需要實施嚴格的Network Policies以及Pod Sandboxing。具體操作,請參見安全容器。
軟體即服務 (SaaS)
在此環境中,每個租戶都與在叢集中啟動並執行應用程式的特定執行個體相關聯。每個執行個體通常都有自己的資料,並使用通常獨立於
Kubernetes RBAC
的單獨的存取控制。與其他情境不同,SaaS環境中的租戶不直接與
Kubernetes API
互動。而是SaaS應用程式負責與Kubernetes API
互動以建立每個租戶所需要的對象。
Kubernetes原生配置
Kubernetes在架構上是面向單租戶的容器編排管理平台,即控制平面的單個執行個體在叢集內的所有租戶之間共用。您可以使用各種Kubernetes對象來實現多租戶隔離的目的。例如,可以使用命名空間和角色型存取控制 (RBAC
),以在邏輯上將租戶彼此隔離。同樣,Quotas
和Limit Ranges
可用於控制每個租戶可以消耗的叢集資源量。然而,叢集是唯一提供強大安全邊界的結構。這是因為設法獲得對叢集內主機的訪問權的攻擊者可以檢索所有安裝在該主機上的Secrets
、ConfigMaps
和Volumes
。還可以類比Kubelet
,這將允許操縱節點的屬性或在叢集內橫向移動。下面的Kubernetes原生配置可以協助您降低使用像Kubernetes這樣的單租戶平台的風險,在一定程度上實現上述情境中租戶之間的隔離。
命名空間
Namespaces是實現軟多租的基礎。Namespaces允許您將叢集分為不同的邏輯層。Quotas、Network Policies、Service Accounts和其他資來源物件都需要在Namespaces範圍內實現多租。
AuthN&AuthZ&Admission
ACK叢集的授權分為RAM授權和RBAC授權兩個步驟,其中RAM授權作用於叢集管理介面的存取控制,包括對叢集的CRUD許可權(如叢集可見度、擴縮容、添加節點等操作),而RBAC授權用於叢集內部Kubernetes資源模型的存取控制,可以做到指定資源在命名空間粒度的細化授權。ACK授權管理為租戶內使用者提供了不同層級的預置角色模板,同時支援綁定多個使用者自訂的叢集角色,此外支援對批量使用者的授權。具體操作,請參見授權概述。
網路原則
預設情況下,Kubernetes叢集中的所有Pod都允許相互連信。使用Network Policies更改此預設設定。
Network Policies使用標籤或IP位址範圍限制Pod之間的通訊。在需要租戶之間嚴格網路隔離的多租戶環境中,需要添加兩條規則:
拒絕Pod之間通訊的預設規則。
允許所有Pod查詢DNS伺服器以進行名稱解析。
資源配額&限制範圍
Quotas用於定義叢集中託管的工作負載的限制。使用Quotas,您可以指定Pod可以消耗的最大CPU和記憶體量,也可以限制可以在叢集或命名空間中分配的資源數量。Limit ranges允許您聲明每個限制的最小值、最大值和預設值。
在共用叢集中過度使用資源通常是有益的,因為可以讓您最大限度地利用資源。但是,對叢集的無限制訪問會導致資源匱乏,從而導致效能下降和應用程式可用性損失。如果一個Pod的請求設定得太低,實際資源使用率超過了節點的容量,節點就會開始遇到CPU或記憶體壓力。發生這種情況時,Pod可能會重啟或從節點中驅逐。
為了防止這種情況發生,您應該在多租戶環境中對命名空間實施Quotas,以強制租戶在叢集上調度Pod時指定請求和限制。這樣做還可以限制Pod可以消耗的資源量來緩解潛在的拒絕服務風險。
在KaaS情境中,您可以使用Quotas來分配叢集資源以與租戶需要的保持一致。
Pod優先順序和搶佔
當您想為不同的客戶提供不同的服務品質 (QoS) 時,Pod優先順序和搶佔會很有用。例如,使用Pod優先順序,您可以將客戶A的Pod配置為以高於客戶B的優先順序運行。當可用容量不足時,Kubelet會從客戶B驅逐低優先順序的Pod以容納客戶A的高優先順序Pod。在SaaS環境中,通過這種方式為願意獲得更高品質服務從而支付更高價格的客戶提供服務方便。
緩解措施
作為多租環境的安全性系統管理員,您主要關心的是防止攻擊者獲得對底層主機的存取權限。應考慮採取以下控制措施來降低這種風險:
安全沙箱
相比於原有Docker運行時,安全沙箱為您提供的一種新的容器運行時選項,可以讓您的應用運行在一個輕量虛擬機器沙箱環境中,擁有獨立的核心,具備更好的安全隔離能力。
安全沙箱特別適合於不可信應用隔離、故障隔離、效能隔離、多使用者間負載隔離等情境。在提升安全性的同時,對效能影響非常小,並且具備與Docker容器一樣的使用者體驗,例如日誌、監控、彈性等。更多資訊,請參見安全沙箱概述。
Open Policy Agent (OPA) & Gatekeeper
OPA(Open Policy Agent)是一種功能強大的策略引擎,支援解耦式的Policy Decisions服務並且在K8s叢集中已經有了廣泛應用。當現有RBAC在命名空間粒度的隔離不能夠滿足公司專屬應用程式複雜的安全需求時,可以通過OPA提供object模型層級的細粒度存取原則控制。Gatekeeper是一個Kubernetes准入控制器,可以在應用部署時刻執行指定的已實施OPA策略。更多資訊,請參考Gatekeeper。
同時OPA支援七層的NetworkPolicy策略定義及基於Labels/Annotation的跨命名空間存取控制,可以作為K8s原生NetworkPolicy的有效增強。
Kyverno
Kyverno是一個面向Kubernetes而生的策略引擎,可以為Kubernetes資源產生驗證、改變和組建組態的策略。Kyverno支援Kustomize Overlays風格的策略校正和Mutate修改,並且可以基於靈活的觸發器跨命名空間複製資源。更多資訊,請參見Kyverno。
您可以使用Kyverno來隔離命名空間、實現Pod安全和其他最佳實務,並產生預設配置(例如網路原則)。具體操作,請參見策略倉庫。
硬多租
硬多租可以通過為每個租戶配置單獨的叢集來實現。雖然這在租戶之間提供了非常強的隔離,但有如下幾個缺點:
當您擁有很多租戶時,成本會很高。您不僅需要為每個叢集支付控制平面成本,而且無法在叢集之間共用計算資源。這樣會導致片段化,其中一部分叢集未被充分利用,其他叢集則被過度利用。
您可能需要購買或構建特殊工具來管理這些叢集。隨著時間的推移,管理成百上千個叢集可能會變得過於繁重。
和建立命名空間相比,為每個租戶建立叢集會很慢。在高度監管的行業或需要強隔離的SaaS環境中,需要採用硬多租方法。
未來方向
Kubernetes社區已經認識到軟多租目前的缺點以及硬多租的挑戰。多租戶特別興趣小組 (SIG) 正嘗試通過幾個孵化專案來解決這些問題:
Virtual Cluster提案描述了一種機制,用於為叢集中的每個租戶(也稱為“Kubernetes on Kubernetes”)建立控制平面服務的單獨執行個體,包括API Server、Controller Manage和Scheduler。更多資訊,請參見Virtual Cluster。
HNC提案 (KEP) 描述了一種通過策略對象繼承以及租用戶系統管理員建立子命名空間的能力在命名空間之間建立父子關係的方法。更多資訊,請參見HNC。
Multi-Tenancy Benchmarks提案提供了使用命名空間進行隔離和分段共用叢集的指南,以及命令列工具Kubectl-mtb用於驗證是否符合的指南。更多資訊,請參見Multi-Tenancy Benchmarks。