iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 9
0

這一章節承接第 8 天的文章,此篇文章要分享的是標籤標籤選擇器的應用。

在一個 Kubernetes 環境下,當 POD 數量越來越多,分類和管理將會變得重要,因為這樣才能提升管理的效率,而在 K8s 中有一個 Label 的字段,它可用來定義資源而外的訊息像是測試環境、開發環境、前端等,往後在藉由標籤選擇器進行過濾完成想要的目標和任務。

標籤

標籤可以依附在每個 K8s 資源對象之上,一個對象可有不止一個標籤,而同一個標籤可被新增到多個資源上。如上述所講,它可以靈活的進行資源對象的分類進行管理,標籤可用版本、環境、分層架構等方式進行貼標籤動作。下圖為 "Kubernetes in action" 書中圖片

相較於 annotationsannotations 無法用來挑選資源對象,僅提供"原數據",類似註解

管理標籤

K8s 中標籤字段定義在 metadata 上,以下面為範例,定義兩個標籤分別是 apptier,值分別是 myappbackend

# pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-label-demo
  namespace: default
  labels:
    app: myapp
    tier: backend
spec:
  containers:
  - name: myapp
    image: nginx:1.18

如果上面的 yaml 檔部署完成後,可用 --show-labels 的選項,讓列出 POD 資源時帶有定義的標籤。

$ kubectl get pod --show-labels
NAME             READY   STATUS    RESTARTS   AGE     LABELS
pod-label-demo   1/1     Running   0          10s     app=myapp,tier=backend

假設標籤給很多時,使用 -L key1,key2...,可指定要看的標籤訊息。

$ kubectl get pod -L tier
NAME             READY   STATUS    RESTARTS   AGE     TIER
envar-demo       1/1     Running   0          3d20h
pod-demo         2/2     Running   93         3d21h   frontend
pod-label-demo   1/1     Running   0          2m48s   backend # this
pod-ports-demo   2/2     Running   92         3d20h   frontend
$ kubectl get pods -L tier --show-labels
NAME             READY   STATUS    RESTARTS   AGE     TIER       LABELS
envar-demo       1/1     Running   0          3d20h              purpose=demonstrate-envars
pod-demo         2/2     Running   93         3d21h   frontend   app=myapp,tier=frontend
pod-label-demo   1/1     Running   0          4m43s   backend    app=myapp,tier=backend
pod-ports-demo   2/2     Running   92         3d20h   frontend   app=myapp,tier=frontend

在 K8s 操作中,也提供用 kubectl label 方式打標籤

$ kubectl label pods pod-demo release=canary
pod/pod-demo labeled
$ kubectl get pod -l release --show-labels
NAME       READY   STATUS    RESTARTS   AGE     LABELS
pod-demo   2/2     Running   93         3d21h   app=myapp,release=canary,tier=frontend

# 當要更正已存在標籤則要使用 --overwrite

$ kubectl label pods pod-demo release=stable --overwrite
pod/pod-demo labeled
$ kubectl get pod -l release --show-labels
NAME       READY   STATUS    RESTARTS   AGE     LABELS
pod-demo   2/2     Running   93         3d21h   app=myapp,release=stable,tier=frontend

標籤選擇器

如果客戶端想針對某個特定標籤下執行特定動作(刪除、查看),這需要使用標籤選擇器。使用標籤選擇器須注意以下

  1. 同時指定的多個選則器之間的邏輯關係為 "AND" 操作
  2. 使用空值的標籤選擇器表示每個資源對象都被選擇
  3. 空的標籤選擇器無法選擇任何資源

進行標籤選擇時可使用以下方式

  • 等值關係
    • =
    • ==
    • !=
# 此範例為選擇 release 標籤且值為 stable
$ kubectl get pods -l release=stable --show-labels
NAME       READY   STATUS    RESTARTS   AGE     LABELS
pod-demo   2/2     Running   93         3d21h   app=myapp,release=stable,tier=frontend
# 此範例為選擇 app 標籤且值為 myapp 和  tier 標籤且值為 backend
$ kubectl get pods -l app=myapp,tier==backend --show-labels
NAME             READY   STATUS    RESTARTS   AGE   LABELS
pod-label-demo   1/1     Running   0          13m   app=myapp,tier=backend
# 此範例為選擇 app 標籤且值為 myapp 和  tier 標籤且值不為 backend
$ kubectl get pods -l app=myapp,tier!=backend -L tier --show-labels
NAME             READY   STATUS    RESTARTS   AGE     TIER       LABELS
pod-demo         2/2     Running   93         3d21h   frontend   app=myapp,release=stable,tier=frontend
pod-ports-demo   2/2     Running   92         3d20h   frontend   app=myapp,tier=frontend
  • 集合關係
    • key in
    • key notin
    • key
    • !key
$ kubectl get pods -l "tier in (backend)" -L tier --show-labels
NAME             READY   STATUS    RESTARTS   AGE   TIER      LABELS
pod-label-demo   1/1     Running   0          18m   backend   app=myapp,tier=backend

K8s 資源中必須以標籤選擇器方式關連到相關的 POD 資源,像是 ServiceDeploymentReplicaSet 等資源。這些資源會透過在 spec 中定義 selector 字段,並使用 matchLabels 指定標籤選擇器,或者有些資源可用 matchExpressions 帶有表達式方式去做篩選機制。

  • matchLabels
    • 給定鍵值來指定標籤選擇器
  • matchExpressions

POD 選擇節點

指定讓 POD 在某個節點上運行,假設只有某節點有 SSDGPU 等資源時, 讓scheduler 用標籤和標籤選擇器讓 POD 選擇匹配的節點。正常的來說 POD 部署會藉由 scheduler 挑選節點上資源允許的節點部署。

PODspec 中的 nodeSelector 可用來選擇想要的節點,前提下節點需設置好標籤。

使用 kubectl label node 將節點打標籤。在預設上節點上是有標籤可透過 kubectl get node --show-labels 觀察。

$ kubectl label node gke-cluster-1-default-pool-7dc8b11b-z2gx disk=ssd device=gpu
node/gke-cluster-1-default-pool-7dc8b11b-z2gx labeled
$ kubectl get node -L disk,device 
NAME                                       STATUS   ROLES    AGE    VERSION          DISK   DEVICE
gke-cluster-1-default-pool-7dc8b11b-cxs1   Ready    <none>   7d2h   v1.15.12-gke.2
gke-cluster-1-default-pool-7dc8b11b-r7rg   Ready    <none>   7d2h   v1.15.12-gke.2
gke-cluster-1-default-pool-7dc8b11b-z2gx   Ready    <none>   7d2h   v1.15.12-gke.2   ssd    gpu
apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeselector-demo
  namespace: default
  labels:
    app: myapp
    tier: backend
    node: ssd
spec:
  containers:
  - name: myapp
    image: nginx:1.18
  nodeSelector:
    disk: ssd

部署完上面 yaml

$ kubectl describe pod pod-nodeselector-demo 
....
Events:
  Type    Reason     Age   From                                               Message
  ----    ------     ----  ----                                               -------
  Normal  Scheduled  6s    default-scheduler                                  Successfully assigned default/pod-nodeselector-demo to gke-cluster-1-default-pool-7dc8b11b-z2gx
  Normal  Pulled     5s    kubelet, gke-cluster-1-default-pool-7dc8b11b-z2gx  Container image "nginx:1.18" already present on machine
  Normal  Created    5s    kubelet, gke-cluster-1-default-pool-7dc8b11b-z2gx  Created container myapp
  Normal  Started    5s    kubelet, gke-cluster-1-default-pool-7dc8b11b-z2gx  Started container myapp

對於這種綁定還有一種類型叫 nodeName,它直接指定目標節點。

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodename-demo
  namespace: default
  labels:
    app: myapp
    tier: backend
    node: ssd
spec:
  containers:
  - name: myapp
    image: nginx:1.18
  nodeName: "gke-cluster-1-default-pool-7dc8b11b-r7rg"

部署完後用下面進行部署節點位置觀察。

$ kubectl get pod -o wide
NAME                    READY   STATUS    RESTARTS   AGE     IP          NODE                                       NOMINATED NODE   READINESS GATES
...
pod-nodename-demo       1/1     Running   0          43s     10.4.2.9    gke-cluster-1-default-pool-7dc8b11b-r7rg   <none>           <none>
pod-nodeselector-demo   1/1     Running   0          5m8s    10.4.0.11   
...

資源註釋

與標籤類似,但它的描述內容不受字元大小限制,它可用來添加一些而外訊息。可使用 kubectl describe pods 去查看 POD 資源的 Annotations

yaml 中則是在 metadata 中使用 annotations 去定義,否則也可使用 kubectl annotate pods 方式。

參考資源

  • Kubernetes in action

上一篇
POD 資源管理第一部份
下一篇
POD 生命週期
系列文
我真的覺得認為 K8s 到底在火什麼30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言