Kubernetes 的層級名稱空間介紹

米開朗基楊發表於2020-08-18

原文連結:https://fuckcloudnative.io/posts/introducing-hierarchical-namespaces/

在單個 Kubernetes 叢集上安全託管大量使用者一直是一個老大難問題,其中最大的麻煩就是不同的組織以不同的方式使用 Kubernetes,很難找到一種租戶模式可以適配所有組織。相反,Kubernetes 只提供了建立不同租戶模式的基礎構件,例如 RBACNetworkPolicies,這些基礎構件實現得越好,安全構建多租戶叢集就越容易。

1. 名稱空間

其中最重要的基礎構件是名稱空間(namespace),它構成了幾乎所有 Kubernetes 控制平面安全和共享策略的骨幹。名稱空間有兩個關鍵屬性,使其成為策略執行的理想選擇:

  • 首先,名稱空間可以用來代表所有權。大多數 Kubernetes 物件資源必須在某一個名稱空間中,所以如果使用名稱空間來代表所有權,那麼名稱空間中的所有物件都隸屬於同一個所有者。
  • 其次,名稱空間的建立和使用需要授權。只有超級管理員才能建立名稱空間,其他使用者需要明確的許可權才能使用這些名稱空間(包括建立、檢視和修改名稱空間中的資源物件)。可以設定恰當的安全策略,防止非特權使用者建立某些資源物件。

2. 名稱空間的限制

然而在實際使用中,名稱空間還是不夠靈活,無法滿足一些常見的用例。假設一個團隊擁有好幾套微服務環境,每一套微服務環境都有自己的祕鑰和資源配額,理想情況下應該將不同的微服務環境放到不同的名稱空間中,以便相互隔離。但這樣會帶來兩個問題:

  • 首先,不同的名稱空間沒有共同的所有權概念,即使它們屬於同一個團隊。如果某個團隊控制了多個名稱空間,Kubernetes 不僅沒有任何關於這些名稱空間的共同所有者的記錄,而且針對名稱空間範圍內的策略也無法跨多個名稱空間生效。
  • 其次,如果團隊能夠自主運作,團隊協作效率會更高。但建立名稱空間是需要高階許可權的,所以開發團隊的任何成員都不可能有許可權建立名稱空間。這就意味著,每當某個團隊想要建立新的名稱空間時,就必須向叢集管理員提出申請,這種方式對小規模組織還可以接受,但隨著組織的發展壯大,勢必需要尋求更佳的方案。

3. 層級名稱空間介紹

層級名稱空間(hierarchical namespaces是 Kubernetes 多租戶工作組(Working Group for Multi-Tenancy,wg-multitenancy) 為了解決這些問題而提出的新概念。在最簡單的形式下,層級名稱空間就是一個常規的名稱空間,它標識了一個單一的、可選的父名稱空間;更復雜的形式下,父名稱空間還可以繼承出子空間。這樣就建立了跨名稱空間的所有權概念,而不是侷限於名稱空間內。

這種層級名稱空間的所有權可以在名稱空間的基礎上實現額外的兩種功能:

  • 策略繼承 : 如果一個名稱空間是另一個名稱空間的子空間,那麼許可權策略(例如 RBAC RoleBindings)將會從父空間直接複製到子空間
  • 繼承建立許可權 : 通常情況下,需要管理員許可權才能建立名稱空間。但層級名稱空間提供了一個新方案:子名稱空間(subnamespaces,只需要使用父名稱空間中的部分許可權即可操作子名稱空間。

有了這兩個功能後,叢集管理員就可以為團隊建立一個『根』名稱空間,以及所有必要的許可權策略,然後將建立子名稱空間的許可權賦予該團隊的成員。這樣團隊內的成員就可以在不違反叢集策略的情況下建立自己的子名稱空間。

4. 示例

層級名稱空間由 Kubernetes 的層級名稱空間控制器(Hierarchical Namespace Controller,HNCHNC 包含兩個元件:

  • 控制器 : 控制器執行在叢集中,用來管理子名稱空間,傳遞策略物件,確保層次結構的合理性,並管理擴充套件點。
  • kubectl 外掛 : 外掛名叫 kubectl-hns,使用者可以使用該外掛和控制器進行互動。

控制器和外掛的安裝請參考 release 頁面

下面舉一個簡單的例子,假設某團隊成員沒有建立名稱空間的許可權,但可以檢視名稱空間 team-a,也可以為其建立子名稱空間。使用 kubectl 外掛執行以下命令:

$ kubectl hns create svc1-team-a -n team-a

這個命令建立了一個子名稱空間 svc1-team-a。子名稱空間也是常規的名稱空間,所以名稱不能重複。

檢視名稱空間的層級結構:

$ kubectl hns tree team-a
# Output:
team-a
└── svc1-team-a

如果父名稱空間中有任何策略,都會被繼承到子名稱空間中。例如,假設 team-a 中有一個名為 sres 的 RBAC RoleBinding,那麼它也會出現在子名稱空間中:

$ kubectl describe rolebinding sres -n svc1-team-a
# Output:
Name:         sres
Labels:       hnc.x-k8s.io/inheritedFrom=team-a  # inserted by HNC
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  admin
Subjects: ...

HNC 還為層級名稱空間新增了相關標籤,其中包含了層級結構的相關資訊,你可以用來設定其他的策略。例如,可以建立以下 NetworkPolicy

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-team-a
  namespace: team-a
spec:
  ingress:
  - from:
    - namespaceSelector:
        matchExpressions:
          - key: 'team-a.tree.hnc.x-k8s.io/depth' # Label created by HNC
            operator: Exists

該策略會傳遞給 team-a 的所有子名稱空間,也會允許所有這些子名稱空間之間的 ingress 流量。 這些 "tree" 標籤只能由 HNC 建立,用來確保最新的層級結構。

關於 HNC 的更多資訊請參考使用者指南


Kubernetes 1.18.2 1.17.5 1.16.9 1.15.12離線安裝包釋出地址http://store.lameleg.com ,歡迎體驗。 使用了最新的sealos v3.3.6版本。 作了主機名解析配置優化,lvscare 掛載/lib/module解決開機啟動ipvs載入問題, 修復lvscare社群netlink與3.10核心不相容問題,sealos生成百年證書等特性。更多特性 https://github.com/fanux/sealos 。歡迎掃描下方的二維碼加入釘釘群 ,釘釘群已經整合sealos的機器人實時可以看到sealos的動態。

相關文章