昨天在 Deployment 的 YAML 中已經看過 selector 與 labels。今天把視角拉遠一點:Kubernetes 裡不同資源如何透過這些欄位找到彼此,以及設定不吻合時可以從哪裡檢查。
Deployment 要知道哪些 Pod 是自己的 replica,ReplicaSet 要知道哪些 Pod 數量需要維持,後續的 Service 也要知道 request 應該送往哪些 Pod,都會靠 Labels 與 Selectors 串起來。
Label 是加在 Kubernetes object metadata.labels 裡的一組 key-value 值。例如:
metadata:
labels:
app.kubernetes.io/name: catalog-api
app.kubernetes.io/component: backend
app.kubernetes.io/version: v1
它可以描述這個資源屬於哪個應用、擔任什麼角色、目前是哪個版本,或屬於哪個環境。Pod、Deployment、Service、Namespace 等 Kubernetes object 都可以有 Label。
Selector 是一組選取條件。下面的寫法會選出帶有 app.kubernetes.io/name=catalog-api Label 的物件;實際選取哪一種物件,則由使用 selector 的資源與欄位決定:
selector:
matchLabels:
app.kubernetes.io/name: catalog-api
例如 Deployment、Service 或 NetworkPolicy 會在各自定義的範圍內使用 selector。Namespace 本身也能被另一個資源的 namespaceSelector 選取。

| 資源 | Selector 的用途 | 是否直接擁有 Pod? |
|---|---|---|
| Deployment | 宣告目標 Pod 的 Label 條件與 Pod template,讓 Deployment Controller 建立、更新、擴縮 child ReplicaSet。 | 否;Deployment 直接擁有 ReplicaSet。 |
| ReplicaSet | 依 selector 識別或取得 Pod,並依 replicas/Pod template 建立或刪除 Pod。 | 是;Pod 的 ownerReferences 指向 ReplicaSet。 |
| Service | 由 Control Plane 依 Service selector 找出候選 Pod,更新 EndpointSlice。 | 否;Service 不建立、不刪除 Pod。 |
這個差別非常重要。Service selector 選到 Pod,並不代表 Service 在管理 Pod 的生命週期;Service 只提供穩定入口,把流量導向符合條件且可用的後端。
以下是最常見的寫法:
apiVersion: apps/v1
kind: Deployment
metadata:
name: catalog-api
spec:
selector:
matchLabels:
app.kubernetes.io/name: catalog-api
template:
metadata:
labels:
app.kubernetes.io/name: catalog-api
app.kubernetes.io/component: backend
spec:
containers:
- name: api
image: example.registry/catalog-api:1.0
Deployment 的 selector 只要求 Pod template 至少帶有相同的 app.kubernetes.io/name。Pod 可以額外帶 component、version 等 Label,但 selector 想找的條件一定要被 template 滿足,否則 Controller 無法正確管理自己建立的 Pod。
不同 Controller 的 selector 不應重疊,否則它們可能同時把同一批 Pod 視為管理對象,造成副本數維持或刪除行為難以預期。Deployment 的 selector 在建立後也不能直接修改,因此一開始就應使用穩定的應用識別 Label,避免把會隨版本變動的 Label 放進 selector。官方文件
matchLabels 與 matchExpressionsmatchLabels 與 matchExpressions 這種 LabelSelector 寫法,適用於 Deployment、ReplicaSet、NetworkPolicy 等資源。
Service 的 .spec.selector 則是較簡單的 key-value map,例如 app: catalog-api,不能改寫成 matchExpressions。
matchLabels 適合最直覺的「key 等於 value」條件。若需要更複雜的條件,Selector 還能使用 matchExpressions:
selector:
matchExpressions:
- key: app.kubernetes.io/component
operator: In
values: [backend, worker]
- key: environment
operator: In
values: [production, staging]
這裡有兩個條件:component 必須是 backend 或 worker,而 environment 必須是 production 或 staging。不同條件之間是 AND;同一個 In 條件的 values 則表示符合其中任一值。
Set-based selector 還能使用 NotIn、Exists、DoesNotExist。
要特別注意到,NotIn 也會選到沒有該 Label key 的物件。
一般 selector 沒有直接表示任意條件 OR 的運算子,若需要「值是 A 或 B」,可用 In 表達。
三者很容易混在一起:
metadata.name: catalog-api。app.kubernetes.io/name=catalog-api。因此不要用 Pod 名稱來代表一群可替換的 Pod,也不要把需要被 Service 或 Controller 選取的條件只放在 Annotation。
例如,Tanzu Package 的 PackageInstall 可以透過 Annotation 告訴 kapp-controller,要把哪個 Secret 裡的 ytt overlay 納入套件模板:
apiVersion: packaging.carvel.dev/v1alpha1
kind: PackageInstall
metadata:
name: example-package
annotations:
ext.packaging.carvel.dev/ytt-paths-from-secret-name.0: logging-volume-overlay
這個 Annotation 是 kapp-controller 定義並讀取的擴充設定,並用 ytt overlay 為套件管理的日誌 DaemonSet 加入 SMB Volume。
而只建立 overlay Secret 還不夠,PackageInstall 必須有引用該 Secret 的 Annotation,套件 reconcile 時才會把 overlay 納入模板,直接修改套件產生的 DaemonSet,也可能在後續 reconcile 時被還原。
專案也遇過某個負載平衡器專用的 Annotation 經過平台轉譯後沒有被送到真正處理 VIP 的元件,因此設定流程沒有報錯,預期效果仍未出現。這提醒我們:Annotation 要有作用,必須有特定工具或 Controller 支援並讀取它;沒有錯誤訊息不代表設定已生效。
在這次實際部署的經驗中,叢集網路資源使用 Namespace 的內建 Label kubernetes.io/metadata.name,搭配 matchExpressions 的 In 條件選取多個 Namespace。以下示意:
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values: [orders, payments]
這裡選的是 Namespace,被選 Namespace 的加入或移除會影響此 selector 的匹配結果。Kubernetes 會在 Namespace 上設定這個內建名稱 Label。
如果 Service 沒有把流量導到預期的 Pod,可以先檢查 Pod 是否帶有 Service selector 要求的 Label,再看 EndpointSlice 是否列出後端:
kubectl get pods -n demo -l app=catalog-api --show-labels
kubectl get endpointslices -n demo -l kubernetes.io/service-name=catalog-api-service
第一個指令確認 selector 能不能找到 Pod,第二個確認 EndpointSlice 裡是否有這個 Service 的後端。
若找不到 Pod,先比對 Service 的 .spec.selector 與 Pod template 的 .metadata.labels;若 Pod 找得到但沒有可用後端,再檢查 Pod 的 Ready 狀態與 EndpointSlice 的 endpoint conditions。
Deployment、ReplicaSet 與 Service 都會使用 Labels 與 Selectors,但目的不同:前兩者用來管理 Pod 副本,Service 用來挑選流量後端。
Labels 與 Selectors 也能用在 Namespace 與網路資源上;Annotation 則讓特定工具為資源附加設定或描述資訊。下一篇會以 Service 為主題,進一步追蹤 selector 如何形成穩定的服務後端。