標籤和選擇器
標籤是附加到 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-scheduler
、kube-controller-manager
、kube-apiserver
、kubectl
或其他第三方自動化)必須指定字首。
kubernetes.io/
和 k8s.io/
字首保留給 Kubernetes 核心元件。
有效的標籤值
- 長度必須小於或等於 63 個字元(可以為空),
- 除非為空,否則必須以字母數字字元(
[a-z0-9A-Z]
)開頭和結尾, - 可以包含短劃線(
-
)、下劃線(_
)、點(.
)和字母數字。
例如,這是一個具有兩個標籤 environment: production
和 app: 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 型別應記錄其有效性和含義。
注意
對於某些 API 型別(例如 ReplicaSets),兩個例項的標籤選擇器在同一名稱空間內不得重疊,否則控制器可能將其視為衝突指令,並無法確定應存在多少個副本。注意
對於基於相等性條件和基於集合條件,都沒有邏輯 OR(||
)運算子。請確保你的過濾語句結構得當。基於相等性的要求
基於相等性或基於不等性的要求允許透過標籤鍵和值進行過濾。匹配的物件必須滿足所有指定的標籤約束,儘管它們也可能具有額外的標籤。允許三種運算子:=
、==
、!=
。前兩個代表相等性(且是同義詞),而後者代表不等性。例如
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
基於集合的要求
基於集合的標籤要求允許根據一組值過濾鍵。支援三種運算子:in
、notin
和 exists
(僅鍵識別符號)。例如
environment in (production, qa)
tier notin (frontend, backend)
partition
!partition
- 第一個示例選擇所有鍵等於
environment
且值等於production
或qa
的資源。 - 第二個示例選擇所有鍵等於
tier
且值不是frontend
和backend
的資源,以及所有不帶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 物件,例如 services
和 replicationcontrollers
,也使用標籤選擇器來指定其他資源(例如 pod)的集合。
服務和 ReplicationController
service
所針對的 Pod 集合由標籤選擇器定義。類似地,replicationcontroller
應管理的 Pod 集合也由標籤選擇器定義。
兩個物件的標籤選擇器均使用對映在 json
或 yaml
檔案中定義,並且僅支援基於相等性的要求選擇器
"selector": {
"component" : "redis",
}
或者
selector:
component: redis
此選擇器(分別為 json
或 yaml
格式)等效於 component=redis
或 component in (redis)
。
支援基於集合要求的資源
更新的資源,例如 Job
、Deployment
、ReplicaSet
和 DaemonSet
,也支援基於集合的要求。
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 集合必須非空。來自 matchLabels
和 matchExpressions
的所有要求都透過 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。
下一步
- 瞭解如何為節點新增標籤
- 查詢知名標籤、註解和汙點
- 請參閱推薦標籤
- 使用名稱空間標籤強制執行 Pod 安全標準
- 閱讀關於為 Pod 標籤編寫控制器的部落格