昨天把第一個 Pod 跑起來了。今天來說說 Label 和 Selector,學會幫資源貼標籤 !
附加在 K8s 資源上的 key-value 標籤,可以貼在 Pod、Node、Service、Deployment 等任何資源上。
metadata:
labels:
app: todo-api
tier: backend
version: v1.0.0
用來篩選有特定 Label 的資源。例如 Service 用 Selector 決定要把流量送給哪些 Pod:
spec:
selector:
app: todo-api # 找所有有 app=todo-api 的 Pod
不需要寫死 Pod 的名稱或 IP——只要 Pod 有對應的 Label,Service 就會自動找到它,即使 Pod 死掉重建、IP 改變也沒問題。
selector:
app: todo-api # app 等於 todo-api
tier: backend # 同時 tier 等於 backend
多個條件是 AND 關係,Pod 必須同時符合所有條件才會被選到。
# 找 tier 是 backend 或 frontend 的 Pod
kubectl get pods -l 'tier in (backend, frontend)'
# 找有 app 這個 key 的 Pod(不管 value 是什麼)
kubectl get pods -l '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 │
└─────────────────┘ └─────────────────────┘
app: todo-api 的 Label,Service 就會自動把流量分給這三個,完全不需要手動設定。今天目標:幫 todo-api 加上 Label,實際用 Selector 篩選資源,理解 Service 之後是怎麼靠 Label 找到 Pod 的。
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"
kubectl apply -f todo-api-pod.yaml
# 看所有 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
不需要修改 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-
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 的服務跑在效能好的機器上。
kubectl delete pod todo-api
todo-api-pod.yaml 檔案刪除,後續不會再使用到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 裡最基礎的識別機制:
明天學 Deployment,真正把 Todo App 的前後端穩定地跑在 K8s 上,也會看到 Label 和 Selector 在 Deployment 裡怎麼運作。