Kubernetes 是一個(gè)強(qiáng)大的容器編排平臺,它提供了許多功能來管理和部署容器化應(yīng)用程序。其中一個(gè)重要的功能是使用名字空間來劃分集群。通過將不同的應(yīng)用程序或團(tuán)隊(duì)分配到不同的命名空間中,可以更好地管理資源、控制訪問權(quán)限和隔離環(huán)境。本文將介紹如何使用 Kubernetes 名字空間來劃分集群,并提供一些實(shí)用的建議和最佳實(shí)踐。
一、準(zhǔn)備
1、已擁有一個(gè)配置好的 Kubernetes 集群;
2、已對 Kubernetes 的 Pod、 Service 和 Deployment 有基本理解。
二、查看名字空間
列出集群中現(xiàn)有的名字空間:
kubectl get namespaces
NAME STATUS AGE default Active 11d kube-node-lease Active 11d kube-public Active 11d kube-system Active 11d
初始狀態(tài)下,Kubernetes 具有四個(gè)名字空間:
- default 無名字空間對象的默認(rèn)名字空間;
- kube-node-lease 此名字空間保存與每個(gè)節(jié)點(diǎn)關(guān)聯(lián)的租約(Lease)對象。 節(jié)點(diǎn)租約允許 kubelet 發(fā)送[心跳](/zh-cn/docs/concepts/architecture/nodes/#heartbeats), 以便控制平面可以檢測節(jié)點(diǎn)故障;
- kube-public 自動創(chuàng)建且被所有用戶可讀的名字空間(包括未經(jīng)身份認(rèn)證的)。 此名字空間通常在某些資源在整個(gè)集群中可見且可公開讀取時(shí)被集群使用。 此名字空間的公共方面只是一個(gè)約定,而不是一個(gè)必要條件;
- kube-system 由 Kubernetes 系統(tǒng)創(chuàng)建的對象的名字空間。
還可以通過下列命令獲取特定名字空間的摘要:
kubectl get namespaces <name>
或用下面的命令獲取詳細(xì)信息:
kubectl describe namespaces <name>
Name: default Labels: <none> Annotations: <none> Status: Active
No resource quota.
Resource Limits Type Resource Min Max Default ---- -------- --- --- --- Container cpu - - 100m
這些詳情同時(shí)顯示了資源配額(如果存在)以及資源限制區(qū)間。
資源配額跟蹤并聚合 Namespace 中資源的使用情況, 并允許集群運(yùn)營者定義 Namespace 可能消耗的 Hard 資源使用限制。限制區(qū)間定義了單個(gè)實(shí)體在一個(gè) Namespace 中可使用的最小/最大資源量約束。
名字空間可以處于下列兩個(gè)階段中的一個(gè):
- Active 名字空間正在被使用中;
- Terminating 名字空間正在被刪除,且不能被用于新對象。
三、創(chuàng)建名字空間
注意:避免使用前綴 kube- 創(chuàng)建名字空間,因?yàn)樗菫?Kubernetes 系統(tǒng)名字空間保留的。
新建一個(gè)名為 my-namespace.yaml 的 YAML 文件,并寫入下列內(nèi)容:
apiVersion: v1 kind: Namespace metadata: name: <insert-namespace-name-here>
然后運(yùn)行:
kubectl create -f ./my-namespace.yaml
或者,可以使用下面的命令創(chuàng)建名字空間:
kubectl create namespace <insert-namespace-name-here>
注意:名字空間的名稱必須是一個(gè)合法的 DNS 標(biāo)簽。
可選字段 finalizers 允許觀察者們在名字空間被刪除時(shí)清除資源。 記住如果指定了一個(gè)不存在的終結(jié)器,名字空間仍會被創(chuàng)建, 但如果用戶試圖刪除它,它將陷入 Terminating 狀態(tài)。
四、刪除名字空間
刪除名字空間使用命令:
kubectl delete namespaces <insert-some-namespace-name>
注意:這會刪除名字空間下的 所有內(nèi)容 !
刪除是異步的,所以有一段時(shí)間會看到名字空間處于 Terminating 狀態(tài)。
五、細(xì)分集群
默認(rèn)情況下,Kubernetes 集群會在配置集群時(shí)實(shí)例化一個(gè) default 名字空間,用以存放集群所使用的默認(rèn) Pod、Service 和 Deployment 集合。
假設(shè)有一個(gè)新的集群,可以通過執(zhí)行以下操作來內(nèi)省可用的名字空間:
kubectl get namespaces
NAME STATUS AGE default Active 13m
1、創(chuàng)建新的名字空間
在本練習(xí)中,我們將創(chuàng)建兩個(gè)額外的 Kubernetes 名字空間來保存我們的內(nèi)容。
在某組織使用共享的 Kubernetes 集群進(jìn)行開發(fā)和生產(chǎn)的場景中:
- 開發(fā)團(tuán)隊(duì)希望在集群中維護(hù)一個(gè)空間,以便他們可以查看用于構(gòu)建和運(yùn)行其應(yīng)用程序的 Pod、Service 和 Deployment 列表。在這個(gè)空間里,Kubernetes 資源被自由地加入或移除, 對誰能夠或不能修改資源的限制被放寬,以實(shí)現(xiàn)敏捷開發(fā);
- 運(yùn)維團(tuán)隊(duì)希望在集群中維護(hù)一個(gè)空間,以便他們可以強(qiáng)制實(shí)施一些嚴(yán)格的規(guī)程, 對誰可以或不可以操作運(yùn)行生產(chǎn)站點(diǎn)的 Pod、Service 和 Deployment 集合進(jìn)行控制。
該組織可以遵循的一種模式是將 Kubernetes 集群劃分為兩個(gè)名字空間:development 和 production。 讓我們創(chuàng)建兩個(gè)新的名字空間來保存我們的工作。
使用 kubectl 創(chuàng)建 development 名字空間。
kubectl create -f https://k8s.io/examples/admin/namespace-dev.json
讓我們使用 kubectl 創(chuàng)建 production 名字空間。
kubectl create -f https://k8s.io/examples/admin/namespace-prod.json
為了確保一切正常,列出集群中的所有名字空間。
kubectl get namespaces --show-labels
NAME STATUS AGE LABELS default Active 32m <none> development Active 29s name=development production Active 23s name=production
2、在每個(gè)名字空間中創(chuàng)建Pod
Kubernetes 名字空間為集群中的 Pod、Service 和 Deployment 提供了作用域。 與一個(gè)名字空間交互的用戶不會看到另一個(gè)名字空間中的內(nèi)容。 為了演示這一點(diǎn),讓我們在 development 名字空間中啟動一個(gè)簡單的 Deployment 和 Pod。
kubectl create deployment snowflake \ --image=registry.k8s.io/serve_hostname \ -n=development --replicas=2
我們創(chuàng)建了一個(gè)副本個(gè)數(shù)為 2 的 Deployment,運(yùn)行名為 snowflake 的 Pod,其中包含一個(gè)負(fù)責(zé)提供主機(jī)名的基本容器。
kubectl get deployment -n=development
NAME READY UP-TO-DATE AVAILABLE AGE snowflake 2/2 2 2 2m
kubectl get pods -l app=snowflake -n=development
NAME READY STATUS RESTARTS AGE snowflake-3968820950-9dgr8 1/1 Running 0 2m snowflake-3968820950-vgc4n 1/1 Running 0 2m
讓我們切換到 production 名字空間, 展示一下一個(gè)名字空間中的資源是如何對另一個(gè)名字空間隱藏的。 名字空間 production 應(yīng)該是空的,下面的命令應(yīng)該不會返回任何東西。
kubectl get deployment -n=production kubectl get pods -n=production
生產(chǎn)環(huán)境下一般以養(yǎng)牛的方式運(yùn)行負(fù)載,所以讓我們創(chuàng)建一些 Cattle(牛)Pod。
kubectl create deployment cattle --image=registry.k8s.io/serve_hostname -n=production kubectl scale deployment cattle --replicas=5 -n=production kubectl get deployment -n=production
NAME READY UP-TO-DATE AVAILABLE AGE cattle 5/5 5 5 10s
kubectl get pods -l app=cattle -n=production
NAME READY STATUS RESTARTS AGE cattle-2263376956-41xy6 1/1 Running 0 34s cattle-2263376956-kw466 1/1 Running 0 34s cattle-2263376956-n4v97 1/1 Running 0 34s cattle-2263376956-p5p3i 1/1 Running 0 34s cattle-2263376956-sxpth 1/1 Running 0 34s
此時(shí),應(yīng)該很清楚地展示了用戶在一個(gè)名字空間中創(chuàng)建的資源對另一個(gè)名字空間是隱藏的。隨著 Kubernetes 中的策略支持的發(fā)展,我們將擴(kuò)展此場景,以展示如何為每個(gè)名字空間提供不同的授權(quán)規(guī)則。
六、名字空間動機(jī)
單個(gè)集群應(yīng)該能滿足多個(gè)用戶及用戶組的需求(以下稱為 “用戶社區(qū)”)。Kubernetes 名字空間 幫助不同的項(xiàng)目、團(tuán)隊(duì)或客戶去共享 Kubernetes 集群。
名字空間通過以下方式實(shí)現(xiàn)這點(diǎn):
- 為名字設(shè)置作用域;
- 為集群中的部分資源關(guān)聯(lián)鑒權(quán)和策略的機(jī)制。
使用多個(gè)名字空間是可選的。每個(gè)用戶社區(qū)都希望能夠與其他社區(qū)隔離開展工作。 每個(gè)用戶社區(qū)都有自己的:
- 資源(Pod、服務(wù)、副本控制器等等)
- 策略(誰能或不能在他們的社區(qū)里執(zhí)行操作)
- 約束(該社區(qū)允許多少配額等等)
集群運(yùn)營者可以為每個(gè)唯一用戶社區(qū)創(chuàng)建名字空間。
名字空間為下列內(nèi)容提供唯一的作用域:
- 命名資源(避免基本的命名沖突)
- 將管理權(quán)限委派給可信用戶
- 限制社區(qū)資源消耗的能力
用例包括:
- 作為集群運(yùn)營者, 我希望能在單個(gè)集群上支持多個(gè)用戶社區(qū);
- 作為集群運(yùn)營者,我希望將集群分區(qū)的權(quán)限委派給這些社區(qū)中的受信任用戶;
- 作為集群運(yùn)營者,我希望能限定每個(gè)用戶社區(qū)可使用的資源量,以限制對使用同一集群的其他用戶社區(qū)的影響;
- 作為集群用戶,我希望與我的用戶社區(qū)相關(guān)的資源進(jìn)行交互,而與其他用戶社區(qū)在該集群上執(zhí)行的操作無關(guān)。
七、名字空間和DNS
當(dāng)創(chuàng)建服務(wù)時(shí),Kubernetes 會創(chuàng)建相應(yīng)的 DNS 條目。 此條目的格式為 <服務(wù)名稱>.<名字空間名稱>.svc.cluster.local。 這意味著如果容器使用 <服務(wù)名稱>,它將解析為名字空間本地的服務(wù)。 這對于在多個(gè)名字空間(如開發(fā)、暫存和生產(chǎn))中使用相同的配置非常有用。 如果要跨名字空間訪問,則需要使用完全限定的域名(FQDN)。