Kubernetes 的層級命名空間介紹
- 2020 年 8 月 18 日
- 筆記
- Kubernetes
原文鏈接://fuckcloudnative.io/posts/introducing-hierarchical-namespaces/
在單個 Kubernetes
集群上安全託管大量用戶一直是一個老大難問題,其中最大的麻煩就是不同的組織以不同的方式使用 Kubernetes
,很難找到一種租戶模式可以適配所有組織。相反,Kubernetes 只提供了創建不同租戶模式的基礎構件,例如 RBAC
和 NetworkPolicies
,這些基礎構件實現得越好,安全構建多租戶集群就越容易。
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,HNC)。HNC
包含兩個組件:
- 控制器 : 控制器運行在集群中,用來管理子命名空間,傳遞策略對象,確保層次結構的合理性,並管理擴展點。
- 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離線安裝包發布地址//store.lameleg.com ,歡迎體驗。 使用了最新的sealos v3.3.6版本。 作了主機名解析配置優化,lvscare 掛載/lib/module解決開機啟動ipvs載入問題, 修復lvscare社區netlink與3.10內核不兼容問題,sealos生成百年證書等特性。更多特性 //github.com/fanux/sealos 。歡迎掃描下方的二維碼加入釘釘群 ,釘釘群已經集成sealos的機器人實時可以看到sealos的動態。