iT邦幫忙

2026 iThome 鐵人賽

DAY 5
0

昨天把第一個 Pod 跑起來了。今天來說說 Label 和 Selector,學會幫資源貼標籤 !


Label 是什麼

附加在 K8s 資源上的 key-value 標籤,可以貼在 Pod、Node、Service、Deployment 等任何資源上。

metadata:
  labels:
    app: todo-api
    tier: backend
    version: v1.0.0
  • key/value 都是字串,一個資源可以有多個 Label
  • Label 本身不影響資源行為,只是標記——真正讓它發揮作用的是 Selector

Selector 是什麼

用來篩選有特定 Label 的資源。例如 Service 用 Selector 決定要把流量送給哪些 Pod:

spec:
  selector:
    app: todo-api  # 找所有有 app=todo-api 的 Pod

不需要寫死 Pod 的名稱或 IP——只要 Pod 有對應的 Label,Service 就會自動找到它,即使 Pod 死掉重建、IP 改變也沒問題。

Selector 支援兩種寫法:

  • 等值條件(最常用)
selector:
  app: todo-api   # app 等於 todo-api
  tier: backend   # 同時 tier 等於 backend

多個條件是 AND 關係,Pod 必須同時符合所有條件才會被選到。

  • 集合條件(kubectl 指令常用)
# 找 tier 是 backend 或 frontend 的 Pod
kubectl get pods -l 'tier in (backend, frontend)'

# 找有 app 這個 key 的 Pod(不管 value 是什麼)
kubectl get pods -l 'app'

Label 和 Selector 在 Todo App 裡的角色

來看 Todo App 的前後端,Label 實際上是怎麼用的:

todo-api Pod              todo-frontend Pod
┌────────────────────┐    ┌────────────────────┐
│ labels:            │    │ labels:            │
│   app: todo-api    │    │   app: todo-       │
│   tier: backend    │    │     frontend       │
│                    │    │   tier: frontend   │
└────────────────────┘    └────────────────────┘
          ▲                         ▲
          │                         │
┌─────────────────┐      ┌─────────────────────┐
│ Service         │      │ Service             │
│ selector:       │      │ selector:           │
│   app: todo-api │      │   app: todo-        │
│                 │      │     frontend        │
└─────────────────┘      └─────────────────────┘
  • 每個 Service 透過 Selector 精準找到對應的 Pod,不會互相干擾。
    之後 todo-api 擴充成 3 個副本,只要這 3 個 Pod 都有 app: todo-api 的 Label,Service 就會自動把流量分給這三個,完全不需要手動設定。

實際操作

今天目標:幫 todo-api 加上 Label,實際用 Selector 篩選資源,理解 Service 之後是怎麼靠 Label 找到 Pod 的。

Step 1: 把 Label 加進 todo-api

  1. 昨天的 Todo-App/k8s/todo-api-pod.yaml 還沒有 Label,今天加上去:
apiVersion: v1
kind: Pod
metadata:
  name: todo-api
  labels:
    app: todo-api
    tier: backend
    version: v1.0.0
spec:
  containers:
    - name: api
      image: yourname/todo-app-api:v1.0.0
      ports:
        - containerPort: 8000
      env:
        - name: DATABASE_URL
          value: "mysql+pymysql://user:password@mysql-service:3306/tododb"
  1. 套用:
kubectl apply -f todo-api-pod.yaml

Step 2: 把用 Label 篩選資源

# 看所有 Pod 的 Label
kubectl get pods --show-labels

# 篩選有 app=todo-api 的 Pod
kubectl get pods -l app=todo-api

# 篩選有 tier=backend 的 Pod
kubectl get pods -l tier=backend

# 多個條件同時篩選
kubectl get pods -l app=todo-api,tier=backend

Step 3: 把動態新增和修改 Label

不需要修改 YAML,可以直接用指令操作:

# 新增 Label
kubectl label pod todo-api env=staging

# 修改 Label(要加 --overwrite)
kubectl label pod todo-api env=production --overwrite

# 刪除 Label(key 後面加減號)
kubectl label pod todo-api env-

Step 4: 把用 Label 篩選 Node

Label 不只能貼在 Pod 上,Node 也可以貼:

# 看 Node 的 Label
kubectl get nodes --show-labels

# 幫 Node 加 Label
kubectl label node minikube disk=ssd

這個在生產環境很常用——把有 SSD 的 Node 貼上 disk=ssd,再用 nodeSelector 指定某些 Pod 只跑在這些 Node 上,可以確保需要高 I/O 的服務跑在效能好的機器上。

Step 5: 把清理 Pod

kubectl delete pod todo-api
  • 一併手動將 todo-api-pod.yaml 檔案刪除,後續不會再使用到

延伸筆記:Label 和 Annotation 的差異

K8s 還有另一個跟 Label 很像的東西叫 Annotation,兩者都是 key-value,但用途完全不同。

Label:用來識別和篩選資源,value 有長度限制(63 字元以內)。Selector 只能用 Label 來篩選,不能用 Annotation。

Annotation:用來存放描述性的附加資訊,value 沒有長度限制,可以放任意字串甚至 JSON。但它不能被 Selector 篩選。

metadata:
  labels:
    app: todo-api          # 給機器看,用來篩選
    version: v1.0.0
  annotations:
    description: "Todo App FastAPI backend"      # 給人看,用來記錄資訊
    last-deployed-by: "github-actions"

簡單記法:Label 給機器看、Annotation 給人看


小結

今天學了 K8s 裡最基礎的識別機制:

  • Label:貼在資源上的 key-value 標籤,本身不影響行為
  • Selector:用 Label 篩選資源,讓元件之間可以動態連結
  • Service 用 Selector 找 Pod:不需要寫死 IP 或名稱,Pod 重建也不影響
  • Label 可以動態新增、修改、刪除,不需要重新部署資源

明天學 Deployment,真正把 Todo App 的前後端穩定地跑在 K8s 上,也會看到 Label 和 Selector 在 Deployment 裡怎麼運作。


上一篇
Day 04|第一個 Pod YAML + 宣告式思維
下一篇
Day 06|Deployment
系列文
從零學 K8s|30 天核心概念 × 實作,新手也能真正掌握 Kubernetes6
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言