前言
Labels(標籤)是 Kubernetes 中最核心的組織機制之一。幾乎所有的資源關聯——Service 對接 Pod、ReplicaSet 管理副本、NetworkPolicy 篩選目標——都是透過標籤選擇器來實現的。如果你覺得標籤只是個簡單的 key-value 對,那你可能忽略了它背後的設計哲學。這篇文章會從標籤的命名規範開始,深入探討各種選擇器的用法。
標籤的命名規範
標籤由鍵(Key)和值(Value)組成,兩者都有嚴格的格式要求。
鍵(Key)的格式
Key 由可選的「前綴」和「名稱」兩部分構成,格式為 prefix/name:
- 名稱:最多 63 個字元,只允許字母、數字、
-、_、.,且必須以字母或數字開頭和結尾 - 前綴(可選):必須是合法的 DNS 子域名,不超過 253 個字元
一個重要的規則:省略前綴的標籤被視為使用者的私有資料。K8s 系統元件和第三方工具自動添加的標籤必須帶有前綴。kubernetes.io/ 和 k8s.io/ 前綴保留給核心元件使用,例如 Node 上常見的 kubernetes.io/os、kubernetes.io/arch、kubernetes.io/hostname 等。
值(Value)的格式
不超過 63 個字元,可以為空字串,其餘規則與 Key 名稱部分相同。
常用標籤分類
在實務中,好的標籤設計能大幅提升運維效率。以下是常見的標籤分類:
| 類別 | Key | 常見值 |
|---|---|---|
| 版本 | release |
stable、canary、beta |
| 環境 | environment |
dev、qa、staging、prod |
| 應用 | app |
frontend、backend、api |
| 架構層級 | tier |
frontend、backend、cache、db |
| 分區/租戶 | partition |
customerA、customerB |
| 品質 | track |
daily、weekly |
我個人建議在團隊中制定統一的標籤規範文件,明確哪些標籤是必要的、命名風格如何統一,避免各團隊各自為政導致混亂。
標籤選擇器
Kubernetes 支援兩種選擇器語法:
基於等值關係(Equality-based)
使用 =、==(兩者等價)和 != 運算子:
# 選擇 app 為 demoapp 的資源
kubectl get pods -l app=demoapp
# 選擇 app 不是 demoapp 的資源(包含沒有 app 標籤的)
kubectl get pods -l app!=demoapp
基於集合關係(Set-based)
提供更靈活的篩選能力:
| 語法 | 含義 |
|---|---|
KEY in (VALUE1, VALUE2) |
Key 的值存在於指定列表中 |
KEY notin (VALUE1, VALUE2) |
Key 的值不在指定列表中 |
KEY |
存在此 Key 的標籤 |
!KEY |
不存在此 Key 的標籤 |
# 過濾所有包含 app 標籤的 Pod
kubectl get pods -l app --show-labels
# 過濾所有不含 app 標籤的 Pod(注意引號防止 shell 解析驚嘆號)
kubectl get pods -l '!app' --show-labels
# 過濾 app 為 demoapp 或 liveness 的 Pod
kubectl get pods -l 'app in (demoapp,liveness)' --show-labels
多條件組合
多個選擇器以逗號分隔,它們之間是 AND(且)的關係:
# 同時滿足 app=demoapp 且 track=daily
kubectl get pods -l 'app=demoapp,track=daily' --show-labels
注意:沒有內建的 OR 運算,要實現 OR 語義只能使用 in 運算子(僅限同一個 Key)。
標籤的增刪改操作
# 添加標籤
kubectl label pods my-pod release=alpha
# 修改已存在的標籤(需要 --overwrite)
kubectl label pods my-pod release=beta --overwrite
# 刪除標籤(Key 後加減號)
kubectl label pods my-pod release-
# 批次為所有 Pod 添加標籤
kubectl label pods --all environment=dev
# 標籤操作適用於所有資源類型
kubectl label nodes my-node disktype=ssd
標籤在控制器中的關鍵角色
標籤不只是用來分類和過濾,它是 K8s 資源關聯的核心機制:
- Service → Pod:Service 的
spec.selector透過標籤匹配找到對應的 Pod - ReplicaSet → Pod:控制器的
spec.selector必須與 Pod 模板的labels匹配 - NetworkPolicy:透過
podSelector和namespaceSelector篩選目標 - Node 調度:
nodeSelector和 Node Affinity 都基於 Node 標籤運作
這也是為什麼標籤設計如此重要:一旦標籤命名混亂,整個叢集的資源關聯都會出問題。
實務建議
- 使用推薦的標籤鍵:K8s 官方推薦了一組標準標籤如
app.kubernetes.io/name、app.kubernetes.io/version、app.kubernetes.io/component等,遵循這些標準可以與生態系統工具更好地整合。 - 避免在 selector 中使用過多標籤:selector 越精確越好,但太多標籤會增加維護成本。通常 2-3 個標籤就足以唯一識別一組 Pod。
- 謹慎手動修改受控 Pod 的標籤:如果你手動移除了某個 Pod 的標籤,使其不再被控制器的 selector 匹配,控制器會認為少了一個副本而建立新的 Pod。這可以用來「隔離」問題 Pod 進行除錯,但要確保你知道自己在做什麼。
- 善用
--show-labels:在排錯時養成加上--show-labels的習慣,能快速確認標籤是否正確匹配。
總結
標籤是 Kubernetes 中看似簡單卻影響深遠的設計。它不僅是分類工具,更是整個叢集資源關聯的基礎建設。花時間設計好標籤規範,比後期修改標籤體系要省事得多。掌握等值和集合兩種選擇器的用法,能讓你在日常運維中快速定位和篩選資源。

發佈留言