文章目錄
- 第1章 k8s中的資源(resources)介紹
- 1.1 k8s中資源(resouces)的分類
- 1.2 k8s中資源(resources)的級別
- 1.3 k8s中資源(resources)的API規范
- 1.4 k8s中資源(resources)的manifests
- 第2章 k8s中的標準資源之namespaces的實踐
- 2.1 基本介紹
- 2.2 編寫相關ns資源對象的manifests
- 2.3 應用相關ns資源對象的manifests
- 2.4 列出相關ns資源對象
- 2.5 ns資源對象的name
- 2.6 ns資源對象的labels
- 2.7 列出ns資源對象中已有非namespace級別的資源對象
- 2.8 ns資源對象的刪除
- 第3章 基于ns資源對象實踐理解Label的管理
第1章 k8s中的資源(resources)介紹
1.1 k8s中資源(resouces)的分類
我們用 kubectl api-resources 可看到其 kubernetes 中的所有資源(當然kubectl所用的kubeconfig所承載的帳戶得具備超級權限)。
root@master01:~# kubectl api-resources | head -4 # 只取了前4行
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings v1 true Binding
componentstatuses cs v1 false ComponentStatus
configmaps cm v1 true ConfigMap
這些資源可分為標準資源(安裝好kubernetes后就有)、非標準資源(擴展kubernetes后才有),我們可用 kubectl get crd 看到有哪些非標準資源,其結果 NAME 字段對應值以點號"."分隔的第一列就是其資源的name。
root@master01:~# kubectl get crd | head -4 # 只取了前4行
NAME CREATED AT
analysisruns.argoproj.io 2025-04-23T02:32:30Z
analysistemplates.argoproj.io 2025-04-23T02:32:30Z
applications.argoproj.io 2025-04-19T17:46:46Z
root@master01:~#
root@master01:~# kubectl api-resources | grep -w applications
applications app,apps argoproj.io/v1alpha1 true Application
1.2 k8s中資源(resources)的級別
不管是標準資源、非標準資源,它們要么是namespace級別、非namespace級別(也稱cluster級別)。可從 kubectl api-resources 結果的 NAMESPACE字段中看到,也可用 kubectl api-resources --namespaced=true/false 列出所有namespace級別或非namespace級別的資源
## kubectl工具看某個資源屬于什么級別
root@master01:~# kubectl api-resources | grep -w Namespace
namespaces ns v1 false Namespace # <== false表示 非namespace級別
root@master01:~#
root@master01:~# kubectl api-resources | grep -w Pod
pods po v1 true Pod # <== true表示 namespace級別## kuectl工具列出所有namespace級別或所有非namespace級別的資源
kubectl api-resources --namespaced=true
kubectl api-resources --namespaced=false
注意:namespace級別的資源其實例化出來的對象得放在已存在的ns資源對象(由Kind為Namespace的資源namespaces實例化出來的)中。
1.3 k8s中資源(resources)的API規范
我們可用以下方法獲取標準資源、非標準資源類的某資源其API規范中有哪些一級字段。
## 參考
root@master01:~# kubectl api-resources | head -1
NAME SHORTNAMES APIVERSION NAMESPACED KIND## 規范的
# <== 格式
kubectl explain --api-version='<APIVERSION>' <KIND># <== 例如
kubectl explain --api-version='v1' Pod## 簡化的
# <== 格式
kubectl explain <KIND># <== 例如
kubectl explain Pod
標準資源、非標準資源其API規范一定會有apiVersion、kind、metadata這三個一級字段,在編寫其對象的manifests是得寫上。
大多數資源其API規范中有spec這個一級字段,用于定義期望狀態,在編寫其對象的manifests時得寫上。
標準資源、非標準資源的API規范一定會有status這個一級字段,在編寫其對象的manifests時不用寫。當對象創建后其status是由其spec轉換而來(期望狀態轉換成實際狀態)。
我們也可以查看某資源其API規范中一級字段下有哪些二級字段,二級字段有哪些三級字段。如下所示。
## 規范的
kubectl explain --api-version='<APIVERSION>' <KIND> # 可看到有哪些一級字段
kubectl explain --api-version='<APIVERSION>' <KIND>.某一級字段 # 可看到有哪些二級字段
kubectl explain --api-version='<APIVERSION>' <KIND>.某一級字段.某二級字段 # 可看到有哪些三級字段 ## 簡化的
kubectl explain <KIND> # 可看到有哪些一級字段
kubectl explain <KIND>.某一級字段 # 可看到有哪些二級字段
kubectl explain <KIND>.某一級字段.某二級字段 # 可看到有哪些三級字段
前面提到
namespace級別的資源其實例化出來的對象得放在某ns資源對象(由Kind為Namespace的資源namespaces實例化出來)中。
那么所以
namespace級別的資源其API規范中metadata字段下的namespace字段,在編寫manifests時得指定。
非namespace級別的資源其API規范中metadata字段下的namespace字段,在編寫manifests時不用指定,指定也沒用的。
# namespace級別的資源其API規范中metadata字段下的namespace字段,在編寫manifests時得指定。
root@master01:~# kubectl explain Pod.metadata.namespace # 在編寫manifests時得指定# 非namespace級別的資源其API規范中metadata一級字段下的namespace字段,在編寫manifests時不用指定,指定也沒用的。
root@master01:~# kubectl explain Namespace.metadata.namespace # 在編寫manifests時不用指定
1.4 k8s中資源(resources)的manifests
資源實例化出對象
可以使用kubectl工具在命令行直接創建(默認只支持使用相應的標準資源),但這種方式不推薦(若要在線修改呢、若被刪除了且在沒備份的情況下你如何快速恢復呢)。
也可以根據其API規范編寫manifests,其manifests可以放在一個文件中,這個文件中可以存在多個不同類型的資源對象的manifests,得用三個橫杠(—)獨占一行進行分隔,這個文件中的內容其格式要么是json/yaml,其文件的擴展名也得是json/yaml,推薦內容格式為yaml,文件擴展名為yaml,易于人類可讀。最后可用kubectl apply -f /path/xxx.yaml -f /path/yyy.yaml 或 cd /path/ && kubectl apply -f . 或 kubectl apply -f /path/ 進行應用(不存在就創建,存在就更新其差異的,有些字段是不可在線更新的)
在版書時可用 “資源的類型/所實例化出對象的name”來表示一個對象,如下所示
Namespace/a
Namespace/b
前面提到
標準資源、非標準資源都有namespace級別、非namespace級別(也稱cluster級別),均有一級字段之metadata字段,而metadata字段下的name字段是必須指定的。
那么所以
非namespace級別的某資源所實例化出來的對象不允許重名,不同資源間所實例化出來的對象是允許重名的。如下所示:
Namespace/a# # 若存在# kubectl工具命令行再創建Namespace/a,不允許,直接報錯。# kubectl工具apply -f Namespace/a <其manifests所在的文件>,其實是# 更新(有些字段是不允許更新的,例如metadata.name,有些字段更新后的影響你得心中有數)#
PersistentVolume/a # # 若存在# kubectl工具命令行再創建PersistentVolume/a,不允許,直接報錯。# kubectl工具apply -f PersistentVolume/a <其manifests所在的文件>,其實是# 更新(有些字段是不允許更新的,例如metadata.name,有些字段更新后的影響你得心中有數)#
namespace級別的某資源所實例化出來的對象不能在所指定 ns 中與現有某資源對象重名,可與非指定ns中現有某資源對象重名。
Namespace/a 對象中Deployment/a # 若存在# kubectl工具命令行再創建Deployment/a,不允許,直接報錯。# kubectl工具apply -f Deployment/a <其manifests所在的文件>,其實是# 更新(有些字段是不允許更新的,例如metadata.name,有些字段更新后的影響你得心中有數)# Service/a# 若存在# kubectl工具命令行再創建Service/a,不允許,直接報錯。# kubectl工具apply -f Service/a <其manifests所在的文件>,其實是# 更新(有些字段是不允許更新的,例如metadata.name,有些字段更新后的影響你得心中有數)# Namespace/b 對象中Deployment/a## 若存在,跟 Namespace/a 中的 Deployment/a 沒有任何關系# kubectl工具命令行再創建Deployment/a,不允許,直接報錯。# kubectl工具apply -f Deployment/a <其manifests所在的文件>,其實是# 更新(有些字段是不允許更新的,例如metadata.name,有些字段更新后的影響你得心中有數)# Service/a## 若存在,跟 Namespace/a 中的 Service/a 沒有任何關系# kubectl工具命令行再創建Service/a,不允許,直接報錯。# kubectl工具apply -f Service/a <其manifests所在的文件>,其實是# 更新(有些字段是不允許更新的,例如metadata.name,有些字段更新后的影響你得心中有數)#
第2章 k8s中的標準資源之namespaces的實踐
2.1 基本介紹
namespaces資源(簡寫ns)是kubernetes中的標準資源,屬于非namespace級別,其實例化出來的對象用于邏輯存放namespace級別資源所實例化出來的對象。
當ns資源對象被刪除后,其里面所包含的非namespace級別資源所實例化出來的對象也會被刪除。得小心哦。
2.2 編寫相關ns資源對象的manifests
我們應該讓各ns資源對象的manifests獨占一個文件。因為在刪除資源對象時可以使用kubectl delete -f <文件> 來刪除,當ns資源對象被刪除后,其里面所包含的非namespace級別資源所實例化出來的對象也會被刪除。
ns/dev-wyc對象的manifests,手動編寫
cat >./ns_dev-wyc.yaml<<'EOF'
apiVersion: v1
kind: Namespace
metadata:name: dev-wyclabels:env: dev proj: wyc
EOF
ns/test-wyc對象的manifests,手動編寫
cat >./ns_test-wyc.yaml<<'EOF'
apiVersion: v1
kind: Namespace
metadata:name: test-wyclabels:env: testproj: wyc
EOF
ns/prod-wyc對象的manifests,手動編寫
cat >./ns_prod-wyc.yaml<<'EOF'
apiVersion: v1
kind: Namespace
metadata:name: prod-wyclabels:env: prodproj: wyc
EOF
ns/uat-wyc對象的manifests,kubectl工具快速生成
kubectl create namespace uat-wyc --dry-run=client -o yaml >./ns_uat-wyc.yaml
ls -l ./ns_uat-wyc.yaml## 命令行快速生成ns資源對象的manifests,并保存于一個文件中。# 命令行無法指定ns/uat-wyc對象的相應label(不是必須的,可命令行添加,也可編輯文件后并保存)。# PS:我這里沒有修改,主要是與后面的步驟有關聯#
2.3 應用相關ns資源對象的manifests
應用ns_dev-wyc.yaml這個manifests
# -->檢查語法
kubectl apply -f ./ns_dev-wyc.yaml --dry-run=client
# -->應用manifests
kubectl apply -f ./ns_dev-wyc.yaml
# -->列出manifests中的相關資源對象
kubectl get -f ./ns_dev-wyc.yaml
# -->列出ns/dev-wyc對象
kubectl get ns/dev-wyc
# -->列出所有的ns資源對象,并根據labels過濾,且顯示所有labels
kubectl get ns -l kubernetes.io/metadata.name=dev-wyc --show-labels
應用ns_test-wyc.yaml這個manifests
kubectl apply -f ./ns_test-wyc.yaml --dry-run=client
kubectl apply -f ./ns_test-wyc.yaml
kubectl get -f ./ns_test-wyc.yaml
kubectl get ns/test-wyc
kubectl get ns -l kubernetes.io/metadata.name=test-wyc --show-labels
應用ns_prod-wyc.yaml這個manifests
kubectl apply -f ./ns_prod-wyc.yaml --dry-run=client
kubectl apply -f ./ns_prod-wyc.yaml
kubectl get -f ./ns_prod-wyc.yaml
kubectl get ns/prod-wyc
kubectl get ns -l kubernetes.io/metadata.name=prod-wyc --show-labels
應用ns_uat-wyc.yaml這個manifests
kubectl apply -f ./ns_uat-wyc.yaml --dry-run=client
kubectl apply -f ./ns_uat-wyc.yaml
kubectl get -f ./ns_uat-wyc.yaml
kubectl get ns/uat-wyc
kubectl get ns -l kubernetes.io/metadata.name=uat-wyc --show-labels
# --> 命令行給其打上相應的標簽。規范的是修改其manifests,再應用manifests,這里只是引出命令行如何給某資源對象打Label
kubectl label Namespace uat-wyc env=uat proj=wyc
# --> 再通過相應標簽進行查看
kubectl get ns -l kubernetes.io/metadata.name=uat-wyc --show-labels
2.4 列出相關ns資源對象
列出所有的ns資源對象
## 格式
kubectl get <某資源的kind>## 示例
kubectl get Namespace
列出已存在的一個或多個ns資源對象
## 格式1
kubectl get <某資源的kind> <對象name> [對象name]## 格式2
kubectl get <某資源的kind>/<對象name> [某資源的kind]/[對象的name]## 格式1示例
kubectl get Namespace dev-wyc test-wyc uat-wyc prod-wyc## 格式2示例
kubectl get Namespace/dev-wyc Namespace/test-wyc Namespace/uat-wyc Namespace/prod-wyc
通過標簽列出wyc項目相關的ns資源對象
# 列出wyc項目相關的所有ns資源對象
kubectl get ns -l proj=wyc# 列出dev環境之wyc項目所用的ns資源對象
kubectl get ns -l env=dev,proj=wyc # 指定多個標簽進行過濾,當有多個時,用逗號分隔,且是與(and)關系# 列出test環境之wyc項目所用的ns資源對象
...................................# 列出uat環境之wyc項目所用的ns資源對象
...................................# 列出prod環境之wyc項目所用的ns資源對象
...................................
2.5 ns資源對象的name
非namespace級別的某資源所實例化出來的對象不能重名,不同資源間所實例化出來的對象是可以重名的。
namespace級別的某資源所實例化出來的對象不能在所指定 ns 中與現有某資源對象重名,可與非指定ns中現有某資源對象重名。
kubernetes中所有資源對象的name規范均遵循一定的規范:
https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/names/#names
ns資源對象的name規范得遵循 RFC 1123。
2.6 ns資源對象的labels
kubernetes中的各資源對象均有 labels 這一屬性,屬于元數據(metadata)的一部分,支持在線更新,我們不能隨便在線更新。
各ns資源對象具備默認的標簽之 app.kubernetes.io/instance=<ns資源對象的name> ,我們可以給ns資源對象額外的添加 labels。
有些場景下,ns資源對象可能需要打上特定的標簽,例如:Istio部署到kubernetes平臺上,其業務所用標簽就得打上 Istio 所規定的標簽。
2.7 列出ns資源對象中已有非namespace級別的資源對象
首先,kubectl -n <ns資源對象> get all 看不全 <ns資源對象> 中包含的所有已有非namespace資源所實例化出來的對象,即使kubernetes中的標準資源。
## 查看 ns/uat-wyc 對象中所包含的所有資源對象,(不嚴謹)
root@master01:~# kubectl -n uat-wyc get all
No resources found in uat-wyc namespace.
root@master01:~# ## 可用以下命令查看某 ns資源對象 中所包含的所有資源對象 (嚴謹)
# <== 列出namespace級別所有resources,并取其KIND字段的值
kubectl api-resources --verbs=list --namespaced=true | awk -F " " '{print $NF}' | sed 1d# <== 列出某ns資源對象中所包含namespace級別資源的相關資源對象
kubectl api-resources --verbs=list --namespaced=true | awk -F " " '{print $NF}' | sed 1d | \xargs -n 1 kubectl -n <ns資源對象> get --show-kind --ignore-not-found# <== 再進一步處理
kubectl api-resources --verbs=list --namespaced=true | awk -F " " '{print $NF}' | sed 1d | \xargs -n 1 kubectl -n <ns資源對象> get --show-kind --ignore-not-found | \sed '/^NAME/'d# <== 再進一步處理
kubectl api-resources --verbs=list --namespaced=true | awk -F " " '{print $NF}' | sed 1d | \xargs -n 1 kubectl -n <ns資源對象> get --show-kind --ignore-not-found | \sed '/^NAME/'d | \awk -F " " '{print $1}'