標籤和選擇器

標籤是附加到 Pod 等物件的鍵/值對。標籤旨在用於指定對使用者有意義且相關的物件的識別屬性,但並不直接向核心系統暗示語義。標籤可用於組織和選擇物件的子集。標籤可以在建立時附加到物件,並隨時新增和修改。每個物件都可以定義一組鍵/值標籤。對於給定物件,每個鍵必須是唯一的。

"metadata": {
  "labels": {
    "key1" : "value1",
    "key2" : "value2"
  }
}

標籤允許高效查詢和監視,非常適合在 UI 和 CLI 中使用。非識別資訊應使用註解記錄。

動機

標籤使使用者能夠以鬆散耦合的方式將其自身的組織結構對映到系統物件上,而無需客戶端儲存這些對映。

服務部署和批處理管道通常是多維實體(例如,多個分割槽或部署、多個釋出軌道、多個層、每個層多個微服務)。管理通常需要跨領域操作,這會打破嚴格分層表示的封裝,特別是那些由基礎設施而非使用者決定的僵硬層次結構。

標籤示例

  • "release" : "stable", "release" : "canary"
  • "environment" : "dev", "environment" : "qa", "environment" : "production"
  • "tier" : "frontend", "tier" : "backend", "tier" : "cache"
  • "partition" : "customerA", "partition" : "customerB"
  • "track" : "daily", "track" : "weekly"

這些是常用標籤的示例;你可以自由開發自己的約定。請記住,對於給定物件,標籤鍵必須是唯一的。

語法和字元集

標籤是鍵/值對。有效的標籤鍵包含兩部分:一個可選字首和一個名稱,兩者用斜槓(/)分隔。名稱部分是必需的,長度必須不超過 63 個字元,以字母數字字元([a-z0-9A-Z])開頭和結尾,中間可以包含短劃線(-)、下劃線(_)、點(.)和字母數字。字首是可選的。如果指定,字首必須是 DNS 子域名:一系列由點(.)分隔的 DNS 標籤,總長度不超過 253 個字元,後跟一個斜槓(/)。

如果省略字首,則標籤鍵被視為使用者私有。向終端使用者物件新增標籤的自動化系統元件(例如 kube-schedulerkube-controller-managerkube-apiserverkubectl 或其他第三方自動化)必須指定字首。

kubernetes.io/k8s.io/ 字首保留給 Kubernetes 核心元件。

有效的標籤值

  • 長度必須小於或等於 63 個字元(可以為空),
  • 除非為空,否則必須以字母數字字元([a-z0-9A-Z])開頭和結尾,
  • 可以包含短劃線(-)、下劃線(_)、點(.)和字母數字。

例如,這是一個具有兩個標籤 environment: productionapp: nginx 的 Pod 的清單

apiVersion: v1
kind: Pod
metadata:
  name: label-demo
  labels:
    environment: production
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

標籤選擇器

名稱和 UID 不同,標籤不提供唯一性。通常,我們預計許多物件會帶有相同的一個或多個標籤。

透過標籤選擇器,客戶端/使用者可以識別一組物件。標籤選擇器是 Kubernetes 中核心的分組原語。

API 目前支援兩種選擇器:基於相等性基於集合。標籤選擇器可以由多個用逗號分隔的要求組成。在有多個要求的情況下,所有要求都必須滿足,因此逗號分隔符充當邏輯&&)運算子。

空選擇器或未指定選擇器的語義取決於上下文,使用選擇器的 API 型別應記錄其有效性和含義。

基於相等性的要求

基於相等性基於不等性的要求允許透過標籤鍵和值進行過濾。匹配的物件必須滿足所有指定的標籤約束,儘管它們也可能具有額外的標籤。允許三種運算子:===!=。前兩個代表相等性(且是同義詞),而後者代表不等性。例如

environment = production
tier != frontend

前者選擇所有鍵等於environment且值等於production的資源。後者選擇所有鍵等於tier且值不同於frontend的資源,以及所有不帶tier鍵的標籤的資源。可以使用逗號運算子過濾production中不包括frontend的資源:environment=production,tier!=frontend

基於相等性的標籤要求的一個使用場景是 Pod 指定節點選擇條件。例如,下面的示例 Pod 選擇存在 accelerator 標籤並設定為 nvidia-tesla-p100 的節點。

apiVersion: v1
kind: Pod
metadata:
  name: cuda-test
spec:
  containers:
    - name: cuda-test
      image: "registry.k8s.io/cuda-vector-add:v0.1"
      resources:
        limits:
          nvidia.com/gpu: 1
  nodeSelector:
    accelerator: nvidia-tesla-p100

基於集合的要求

基於集合的標籤要求允許根據一組值過濾鍵。支援三種運算子:innotinexists(僅鍵識別符號)。例如

environment in (production, qa)
tier notin (frontend, backend)
partition
!partition
  • 第一個示例選擇所有鍵等於environment且值等於productionqa的資源。
  • 第二個示例選擇所有鍵等於 tier 且值不是 frontendbackend 的資源,以及所有不帶 tier 鍵的標籤的資源。
  • 第三個示例選擇所有包含鍵為 partition 的標籤的資源;不檢查值。
  • 第四個示例選擇所有不帶鍵為 partition 的標籤的資源;不檢查值。

同樣,逗號分隔符充當 AND 運算子。因此,可以使用 partition,environment notin (qa) 來過濾帶有 partition 鍵(無論值是什麼)且 environment 不同於 qa 的資源。基於集合的標籤選擇器是相等性的一種通用形式,因為 environment=production 等同於 environment in (production);同樣適用於 !=notin

基於集合的要求可以與基於相等性的要求混合使用。例如:partition in (customerA, customerB),environment!=qa

API

LIST 和 WATCH 過濾

對於列表監控操作,你可以指定標籤選擇器來過濾返回的物件集;你使用查詢引數指定過濾器。(要詳細瞭解 Kubernetes 中的監控,請閱讀高效的更改檢測)。兩種要求都允許(這裡顯示的是它們在 URL 查詢字串中出現的形式)

  • 基於相等性的要求:?labelSelector=environment%3Dproduction,tier%3Dfrontend
  • 基於集合的要求:?labelSelector=environment+in+%28production%2Cqa%29%2Ctier+in+%28frontend%29

這兩種標籤選擇器樣式都可以透過 REST 客戶端列出或監視資源。例如,使用 kubectl 針對 apiserver 並使用基於相等性的選擇器時,可以這樣寫:

kubectl get pods -l environment=production,tier=frontend

或者使用基於集合的要求

kubectl get pods -l 'environment in (production),tier in (frontend)'

如前所述,基於集合的需求更具表現力。例如,它們可以在值上實現 OR 運算子

kubectl get pods -l 'environment in (production, qa)'

或者透過 notin 運算子限制負向匹配

kubectl get pods -l 'environment,environment notin (frontend)'

API 物件中的集合引用

一些 Kubernetes 物件,例如 servicesreplicationcontrollers,也使用標籤選擇器來指定其他資源(例如 pod)的集合。

服務和 ReplicationController

service 所針對的 Pod 集合由標籤選擇器定義。類似地,replicationcontroller 應管理的 Pod 集合也由標籤選擇器定義。

兩個物件的標籤選擇器均使用對映在 jsonyaml 檔案中定義,並且僅支援基於相等性的要求選擇器

"selector": {
    "component" : "redis",
}

或者

selector:
  component: redis

此選擇器(分別為 jsonyaml 格式)等效於 component=rediscomponent in (redis)

支援基於集合要求的資源

更新的資源,例如 JobDeploymentReplicaSetDaemonSet,也支援基於集合的要求。

selector:
  matchLabels:
    component: redis
  matchExpressions:
    - { key: tier, operator: In, values: [cache] }
    - { key: environment, operator: NotIn, values: [dev] }

matchLabels{key,value} 對的對映。matchLabels 對映中的單個 {key,value} 等效於 matchExpressions 的一個元素,其中 key 欄位是“key”,operator 是“In”,並且 values 陣列僅包含“value”。matchExpressions 是 Pod 選擇器要求的列表。有效運算子包括 In、NotIn、Exists 和 DoesNotExist。在 In 和 NotIn 的情況下,values 集合必須非空。來自 matchLabelsmatchExpressions 的所有要求都透過 AND 組合在一起——它們必須全部滿足才能匹配。

選擇節點集

基於標籤進行選擇的一個用例是限制 Pod 可以排程到的節點集。有關更多資訊,請參閱節點選擇文件。

有效使用標籤

你可以為任何資源應用單個標籤,但這並非總是最佳實踐。在許多場景中,應使用多個標籤來區分資源集。

例如,不同的應用程式會為 app 標籤使用不同的值,但一個多層應用程式,例如留言簿示例,還需要區分每個層。前端可以帶有以下標籤

labels:
  app: guestbook
  tier: frontend

而 Redis 主節點和副本將具有不同的 tier 標籤,甚至可能有一個額外的 role 標籤

labels:
  app: guestbook
  tier: backend
  role: master

labels:
  app: guestbook
  tier: backend
  role: replica

這些標籤允許根據標籤指定的任何維度對資源進行切片和分析

kubectl apply -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml
kubectl get pods -Lapp -Ltier -Lrole
NAME                           READY  STATUS    RESTARTS   AGE   APP         TIER       ROLE
guestbook-fe-4nlpb             1/1    Running   0          1m    guestbook   frontend   <none>
guestbook-fe-ght6d             1/1    Running   0          1m    guestbook   frontend   <none>
guestbook-fe-jpy62             1/1    Running   0          1m    guestbook   frontend   <none>
guestbook-redis-master-5pg3b   1/1    Running   0          1m    guestbook   backend    master
guestbook-redis-replica-2q2yf  1/1    Running   0          1m    guestbook   backend    replica
guestbook-redis-replica-qgazl  1/1    Running   0          1m    guestbook   backend    replica
my-nginx-divi2                 1/1    Running   0          29m   nginx       <none>     <none>
my-nginx-o0ef1                 1/1    Running   0          29m   nginx       <none>     <none>
kubectl get pods -lapp=guestbook,role=replica
NAME                           READY  STATUS   RESTARTS  AGE
guestbook-redis-replica-2q2yf  1/1    Running  0         3m
guestbook-redis-replica-qgazl  1/1    Running  0         3m

更新標籤

有時,你可能希望在建立新資源之前重新標記現有的 Pod 和其他資源。這可以透過 kubectl label 完成。例如,如果你想將所有 NGINX Pod 標記為前端層,請執行

kubectl label pods -l app=nginx tier=fe
pod/my-nginx-2035384211-j5fhi labeled
pod/my-nginx-2035384211-u2c7e labeled
pod/my-nginx-2035384211-u3t6x labeled

這首先會過濾所有帶有 "app=nginx" 標籤的 Pod,然後用 "tier=fe" 標記它們。要檢視已標記的 Pod,請執行

kubectl get pods -l app=nginx -L tier
NAME                        READY     STATUS    RESTARTS   AGE       TIER
my-nginx-2035384211-j5fhi   1/1       Running   0          23m       fe
my-nginx-2035384211-u2c7e   1/1       Running   0          23m       fe
my-nginx-2035384211-u3t6x   1/1       Running   0          23m       fe

這將輸出所有 "app=nginx" Pod,並附帶一個額外的 Pod 層標籤列(用 -L--label-columns 指定)。

有關更多資訊,請參閱 kubectl label

下一步

最後修改於 2024 年 7 月 30 日晚上 11:13 PST:更正加速器標籤 (bbb4553bb0)