上一節講到了label標簽,label標簽屬於metadata元數據對象的一個屬性,這節講下另外兩個屬性 annotations 和 namespace 以及 label 在 node 節點的使用。
Annotations 是注解的意思,也使用key/value 鍵值對進行定義,Annotations 的作用類似代碼的注釋功能,可以為資源添加說明,可以是鏡像的相關信息,日志記錄,負責人信息等等。
不同於 Labels 用於標志和選擇對象,Annotations 用來記錄一些附加信息可以用來輔助應用部署、安全策略以及調度策略等。比如 deployment 使用 annotations 來記錄 rolling update 的狀態。
編輯deployment 資源配置文件,添加 Annotations 注釋 imageregistry: "https://index.docker.io/v1/":
[root@ylserver10686071 ~]# cat deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app003
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
annotations:
imageregistry: "https://index.docker.io/v1/"
labels:
app: web
spec:
containers:
- name: tomcat
image: tomcat:8.0
創建deployment,查看 pod annotations 信息,可以看到添加的 imageregistry ,另外2個 key/value 則為自動寫入信息,記錄 pod的IP地址:
[root@ylserver10686071 ~]# kubectl describe pod app003|grep -5 Annotations
Priority: 0
Node: ylserver10686072/10.68.60.72
Start Time: Sun, 18 Jul 2021 21:47:18 +0800
Labels: app=web
pod-template-hash=569979b4c7
Annotations: cni.projectcalico.org/podIP: 10.233.67.26/32
cni.projectcalico.org/podIPs: 10.233.67.26/32
imageregistry: https://index.docker.io/v1/
Status: Running
IP: 10.233.67.26
IPs:
[root@ylserver10686071 ~]#
在metadata元數據對象里還有一個很重要的屬性,就是namespace 命名空間,namespace 是 k8s 支持多個虛擬集群,底層依賴於同一個物理集群,當多團隊或多項目的場景可以用到命名空間,命名空間也可以進行資源配額。
查看系統已經創建的namespace,其中default為默認namespace,資源不指定namespace時,默認使用該namespace,kube-system則為系統創建對象所使用的namespace:
[root@ylserver10686071 ~]# kubectl get namespace NAME STATUS AGE default Active 6d8h ingress-nginx Active 6d7h kube-node-lease Active 6d8h kube-public Active 6d8h kube-system Active 6d8h [root@ylserver10686071 ~]#
創建一個名為 prod 的namespace:
[root@ylserver10686071 ~]# kubectl create namespace prod namespace/prod created [root@ylserver10686071 ~]#
創建 deployment 資源,namespace 為 prod:
[root@ylserver10686071 ~]# cat deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app004
namespace: prod
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
annotations:
imageregistry: "https://index.docker.io/v1/"
labels:
app: web
spec:
containers:
- name: tomcat
image: tomcat:8.0
應用配置文件並查看,參數 -n 指定命名空間:
[root@ylserver10686071 ~]# kubectl apply -f deployment.yml
deployment.apps/app004 created
[root@ylserver10686071 ~]# kubectl get deployments -n prod
NAME READY UP-TO-DATE AVAILABLE AGE
app004 1/1 1 1 15s
查看屬於namespace 管理類型的資源(這里只截取前面幾個):
[root@ylserver10686071 ~]# kubectl api-resources --namespaced=true NAME SHORTNAMES APIGROUP NAMESPACED KIND bindings true Binding configmaps cm true ConfigMap endpoints ep true Endpoints events ev true Event limitranges limits true LimitRange persistentvolumeclaims pvc true PersistentVolumeClaim pods po true Pod
查看不屬於namespace 管理類型的資源(這里只截取前面幾個):
[root@ylserver10686071 ~]# kubectl api-resources --namespaced=false NAME SHORTNAMES APIGROUP NAMESPACED KIND componentstatuses cs false ComponentStatus namespaces ns false Namespace nodes no false Node persistentvolumes pv false PersistentVolume
metadata元數據對象的一些屬性也可以注釋到pod 的env對象的屬性中,最終在Container的環境變量中可以直接調用,編寫deployment 資源配置文件:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app005
namespace: prod
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
annotations:
imageregistry: "https://index.docker.io/v1/"
labels:
app: web
spec:
containers:
- name: tomcat
image: tomcat:8.0
env:
- name: "NODENAME"
valueFrom:
fieldRef:
fieldPath: metadata.name
創建deployment資源,並進入 pod的 tomcat 容器中:
[root@ylserver10686071 ~]# kubectl apply -f deployment.yml
deployment.apps/app005 created
[root@ylserver10686071 ~]# kubectl exec -it app005-569979b4c7-gfrr2 -c tomcat -n prod -- env|grep -2 NODENAME
HOSTNAME=app005-569979b4c7-gfrr2
TERM=xterm
NODENAME=app005-569979b4c7-gfrr2
KUBERNETES_PORT_443_TCP=tcp://10.233.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
[root@ylserver10686071 ~]#
允許注入pod env的對象有: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.podIP", "status.podIPs"
label標簽還可以應用到 node 節點上,node 節點就是宿主機,查看之前創建的pod 在哪個node上創建:
[root@ylserver10686071 ~]# kubectl get pods -n prod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES app004-569979b4c7-h4zxx 1/1 Running 0 10m 10.233.67.28 ylserver10686072 <none> <none> app005-569979b4c7-gfrr2 1/1 Running 0 3m51s 10.233.75.61 ylserver10686071 <none> <none> [root@ylserver10686071 ~]#
如果pod在創建的時候沒有指定某個node,則會根據k8s 內置的調度算法在某個node上啟動,我們也可以給某個node 做 label標記,然后使用標簽選擇器指定該label,從而達到pod在指定的node上啟動。
查看集群所有node節點:
[root@ylserver10686071 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION ylserver10686071 Ready master 6d8h v1.19.10 ylserver10686072 Ready master 6d8h v1.19.10 ylserver10686073 Ready master 6d8h v1.19.10 [root@ylserver10686071 ~]#
給node節點 ylserver10686073 打上標簽 disk=ssd :
[root@ylserver10686071 ~]# kubectl label node ylserver10686073 disk=ssd node/ylserver10686073 labeled [root@ylserver10686071 ~]#
查看 node 節點 ylserver10686073 所有label,可以看到已經打上 disk=ssd 標簽:
[root@ylserver10686071 ~]# kubectl get node ylserver10686073 --show-labels
NAME STATUS ROLES AGE VERSION LABELS
ylserver10686073 Ready master 6d8h v1.19.10 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disk=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=ylserver10686073,kubernetes.io/os=linux,node-role.kubernetes.io/master=
[root@ylserver10686071 ~]#
編輯deployment配置文件,指定在label 包含 disk=ssd 的node上啟動:
[root@ylserver10686071 ~]# cat deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app006
namespace: prod
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
annotations:
imageregistry: "https://index.docker.io/v1/"
labels:
app: web
spec:
nodeSelector:
"disk": 'ssd'
containers:
- name: tomcat
image: tomcat:8.0
env:
- name: "NODENAME"
valueFrom:
fieldRef:
fieldPath: metadata.name
創建deployment app006,並查看 pod:
[root@ylserver10686071 ~]# kubectl apply -f deployment.yml deployment.apps/app006 created [root@ylserver10686071 ~]# kubectl get pods -n prod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES app004-569979b4c7-h4zxx 1/1 Running 0 28m 10.233.67.28 ylserver10686072 <none> <none> app005-569979b4c7-gfrr2 1/1 Running 0 22m 10.233.75.61 ylserver10686071 <none> <none> app006-748746dccf-pjj9d 1/1 Running 0 3m43s 10.233.72.37 ylserver10686073 <none> <none> [root@ylserver10686071 ~]#
node label也可以刪除,只需要在key后面加 - ,刪除disk=ssd 標簽如下:
[root@ylserver10686071 ~]# kubectl label node ylserver10686073 disk- node/ylserver10686073 labeled [root@ylserver10686071 ~]# kubectl get node ylserver10686073|grep disk [root@ylserver10686071 ~]#
刪除node label,已經創建的pod 不會受到影響:
[root@ylserver10686071 ~]# kubectl get pods -n prod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES app004-569979b4c7-h4zxx 1/1 Running 0 30m 10.233.67.28 ylserver10686072 <none> <none> app005-569979b4c7-gfrr2 1/1 Running 0 24m 10.233.75.61 ylserver10686071 <none> <none> app006-748746dccf-pjj9d 1/1 Running 0 5m51s 10.233.72.37 ylserver10686073 <none> <none> [root@ylserver10686071 ~]#
總結一下:
- metadata元數據對象屬性中 Annotations 和 Label 都用 key/value 鍵值對 定義,Annotations 為用戶添加的額外注解,Label為上層控制器對下層控制器的匹配定位;
- metadata元數據的一些對象屬性以及spec、status的一些對象屬性可以注入到pod 的env環境變量中;
- Label標簽也可以應用到node節點上,pod可以根據node節點包含的label 選擇在哪些node上啟動。
