標籤與選擇器
標籤 (Labels) 是附加到物件 (objects)的鍵/值對。標籤旨在用於指定對使用者有意義且相關的物件識別屬性,但並不直接暗示核心系統的語意。標籤可用於組織和選擇物件的子集。標籤可以在建立物件時附加,並隨後隨時新增和修改。每個物件都可以定義一組鍵/值標籤。對於給定的物件,每個鍵都必須是唯一的。
"metadata": {
"labels": {
"key1" : "value1",
"key2" : "value2"
}
}
標籤允許高效的查詢和監看,非常適合在 UI 和 CLI 中使用。非識別資訊應使用註解 (annotations)記錄。
動機
標籤使使用者能夠以鬆散耦合的方式將自己的組織結構對應到系統物件,而無需用戶端儲存這些對應關係。
服務部署和批次處理管線通常是多維實體(例如,多個分割區或部署、多個發布軌跡、多個層級、每個層級多個微服務)。管理通常需要跨領域操作,這打破了嚴格階層表示的封裝,尤其是由基礎架構而不是使用者決定的剛性階層。
標籤範例
"release" : "stable"
,"release" : "canary"
"environment" : "dev"
,"environment" : "qa"
,"environment" : "production"
"tier" : "frontend"
,"tier" : "backend"
,"tier" : "cache"
"partition" : "customerA"
,"partition" : "customerB"
"track" : "daily"
,"track" : "weekly"
這些是常用標籤的範例;您可以自由開發自己的慣例。請記住,對於給定的物件,標籤鍵必須是唯一的。
語法和字元集
標籤 (Labels) 是鍵/值對。有效的標籤鍵有兩個部分:一個可選的前綴和名稱,以斜線 (/
) 分隔。名稱部分是必需的,且長度必須為 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 的 Manifest
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不同,標籤不提供唯一性。一般來說,我們預期許多物件會帶有相同的標籤。
透過標籤選擇器 (label selector),用戶端/使用者可以識別一組物件。標籤選擇器是 Kubernetes 中的核心分組基本元素。
API 目前支援兩種選擇器類型:基於等式 (equality-based) 和基於集合 (set-based)。標籤選擇器可以由多個以逗號分隔的需求 (requirements) 組成。在多個需求的情況下,所有需求都必須滿足,因此逗號分隔符號充當邏輯 AND (&&
) 運算子。
空或未指定選擇器的語意取決於上下文,並且使用選擇器的 API 類型應記錄它們的有效性和含義。
注意
對於某些 API 類型(例如 ReplicaSets),同一命名空間中兩個實例的標籤選擇器不得重疊,否則控制器可能會將其視為衝突的指令,並無法確定應存在多少副本。注意
對於基於等式和基於集合的條件,都沒有邏輯 OR (||
) 運算子。請確保您的篩選陳述式結構正確。基於等式 (Equality-based) 需求
基於等式或基於不等式的需求允許依標籤鍵和值進行篩選。匹配的物件必須滿足所有指定的標籤約束,儘管它們也可能具有額外的標籤。 允許三種運算子 =
、==
、!=
。前兩個表示等式(且為同義詞),而後者表示不等式。 例如:
environment = production
tier != frontend
前者選取鍵等於 environment
且值等於 production
的所有資源。 後者選取鍵等於 tier
且值與 frontend
不同的所有資源,以及所有沒有 tier
鍵標籤的資源。 可以使用逗號運算子篩選 production
中排除 frontend
的資源:environment=production,tier!=frontend
基於等式的標籤需求的一個使用情境是 Pods 指定節點選取標準。 例如,下面的範例 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 篩選
對於 list 和 watch 操作,您可以指定標籤選取器來篩選傳回的物件集合;您可以使用查詢參數指定篩選器。(若要詳細了解 Kubernetes 中的監看 (watches),請閱讀有效率的變更偵測)。兩種需求都是允許的(在此以它們在 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
,也使用標籤選取器來指定其他資源的集合,例如 pods。
Service 和 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 的情況下,值集合必須為非空。 來自 matchLabels
和 matchExpressions
的所有需求都以 AND 邏輯組合在一起——它們都必須滿足才能匹配。
選取節點集合
標籤選取的一個用例是約束 pod 可以排程的節點集合。 請參閱關於節點選取的文件以取得更多資訊。
有效率地使用標籤
您可以將單個標籤應用於任何資源,但這並不總是最佳實務。 在許多情況下,應使用多個標籤來區分彼此的資源集合。
例如,不同的應用程式將對 app
標籤使用不同的值,但多層應用程式(例如 guestbook 範例)還需要區分每個層級。 前端可以攜帶以下標籤
labels:
app: guestbook
tier: frontend
而 Redis master 和 replica 將具有不同的 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 標籤編寫控制器 的部落格文章