deployment關聯到pod
spec.selector.matchLabels.deployment: hello
作用:
這是選擇器(Selector),用於告訴Deployment:
- 識別哪些Pod屬於這個Deployment管理
- 它會匹配集羣中已有的Pod標籤
- 一個Deployment只能管理與自己selector匹配的Pod
關鍵點:
- 用於查找和選擇現有的Pod
- 決定Deployment的管理範圍
- 一旦設置後不能修改(除非刪除整個Deployment重新創建)
spec.template.metadata.labels.deployment: hello
作用:
這是模板標籤(Template Labels),用於:
- 定義新創建Pod的標籤
- 當Deployment創建新Pod副本時,會給每個Pod打上這個標籤
- 確保新Pod能夠被上面的selector選中
關鍵點:
- 用於給新Pod打標籤
- 決定新Pod的身份標識
- 可以修改(觸發滾動更新)
兩者關係圖示
Deployment
├── selector.matchLabels: deployment=hello ← 查找標準("我要管理哪些Pod?")
│
└── template
└── metadata.labels: deployment=hello ← 創建標準("我創建的Pod長這樣")
│
└── Pod1 (deployment=hello) ← 被selector匹配到
└── Pod2 (deployment=hello) ← 被selector匹配到
為什麼需要兩者匹配?
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-deployment
spec:
replicas: 3
selector:
matchLabels:
deployment: hello # ← 查找標籤為deployment=hello的Pod
template:
metadata:
labels:
deployment: hello # ← 創建Pod時給它打上deployment=hello標籤
spec:
containers:
- name: nginx
image: nginx:1.14.2
如果不匹配會發生什麼?
假設:
- selector匹配
deployment: hello - 但template標籤是
app: hello
結果:
- Deployment創建Pod時打上
app: hello標籤 - Deployment的selector查找
deployment: hello的Pod - 找不到自己創建的Pod
- 會無限創建新Pod(因為永遠達不到期望的副本數)
- 出現錯誤:"selector does not match template labels"
實際應用場景
1. 版本管理
selector:
matchLabels:
app: myapp # 匹配所有myapp的Pod,無論版本
template:
metadata:
labels:
app: myapp
version: v1.2.3 # 創建特定版本的Pod
2. 多Deployment共享Pod
# Deployment A
selector:
matchLabels:
app: myapp
tier: frontend
# Deployment B(也可以管理同樣的Pod)
selector:
matchLabels:
app: myapp
managed-by: deployment-b
3. 金絲雀發佈
# 主Deployment
selector:
matchLabels:
app: myapp
track: stable
# 金絲雀Deployment
selector:
matchLabels:
app: myapp
track: canary
最佳實踐
- 始終保持一致:selector的標籤必須包含在template的標籤中
- 使用複合標籤:不要只用一個標籤,通常用2-3個標籤組合
- 避免修改selector:修改會導致Deployment無法管理現有Pod
- 使用有意義的標籤:
labels:
app: shopping-cart
component: payment
environment: production
version: v2.1.0
總結對比
| 特性 | selector.matchLabels | template.metadata.labels |
|---|---|---|
| 作用 | 選擇管理哪些Pod | 定義新Pod的標籤 |
| 方向 | 從Pod到Deployment | 從Deployment到Pod |
| 可修改 | 不可修改(創建後) | 可修改(觸發更新) |
| 匹配關係 | 必須⊆ template的標籤 | 必須⊇ selector的標籤 |
簡單記憶:selector是"我要找誰",template是"我造的人長什麼樣"。Deployment用selector找到自己該管的人,然後用template製造新人。
service路由到pod
完全正確!你的理解非常準確。
Service Selector 的作用
apiVersion: v1
kind: Service
metadata:
name: hello-service
spec:
selector:
deployment: hello # ← 這是選擇Pod的標籤,不是選擇Deployment!
ports:
- port: 80
targetPort: 8080
Service的selector直接關聯到Pod,而不是Deployment,這是Kubernetes服務發現的核心機制。
詳細解釋
工作原理圖示
┌─────────────┐ 管理 ┌─────────────┐ 標籤匹配 ┌─────────────┐
│ Deployment │──────────▶│ Pod │◀────────────│ Service │
│ │ 創建Pod │ (deployment:hello) │ 流量轉發 │ │
└─────────────┘ └─────────────┘ └─────────────┘
│ ▲ │
│ 設置Pod標籤 │ 通過標籤選擇Pod
└──────────────────────────┘ │
流量
▼
客户端請求
關鍵區別
| 對象 | 選擇目標 | 選擇依據 | 作用 |
|---|---|---|---|
| Deployment Selector | Pod | matchLabels | 管理Pod的生命週期(創建、更新、刪除) |
| Service Selector | Pod | selector | 將流量路由到匹配的Pod |
完整示例
# 1. Deployment創建Pod並打標籤
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-deployment
spec:
selector:
matchLabels:
app: hello-app # 管理標籤匹配的Pod
template:
metadata:
labels:
app: hello-app # Service會匹配這個
version: v1 # Service也會匹配這個(如果selector包含)
environment: prod # 額外標籤,Service不關心
spec:
containers:
- name: nginx
image: nginx:1.14.2
---
# 2. Service通過標籤選擇Pod
apiVersion: v1
kind: Service
metadata:
name: hello-service
spec:
selector:
app: hello-app # 選擇具有app=hello-app標籤的Pod
# version: v1 # 也可以同時匹配多個標籤
ports:
- port: 80
targetPort: 80
實際應用中的常見模式
模式1:一對一關聯
# Deployment
template.metadata.labels:
app: frontend
component: web
# Service
selector:
app: frontend
component: web
# 精確匹配特定應用的特定組件
模式2:一對多關聯
# 多個Deployment創建相同標籤的Pod
# Deployment A
template.metadata.labels:
app: backend
tier: api
# Deployment B(另一個版本的API)
template.metadata.labels:
app: backend
tier: api
# 單個Service負載均衡到所有匹配的Pod
# Service
selector:
app: backend
tier: api
# 流量會同時分發到兩個Deployment創建的Pod
模式3:流量分片
# 金絲雀部署場景
# 穩定版Deployment
template.metadata.labels:
app: shopping-cart
track: stable
# 金絲雀Deployment
template.metadata.labels:
app: shopping-cart
track: canary
# Service A(穩定流量)
selector:
app: shopping-cart
track: stable
# Service B(測試流量)
selector:
app: shopping-cart
track: canary
重要特性
1. 動態發現
# 當新Pod啓動並匹配Service的selector時
# Service會自動將其添加到端點列表
kubectl get endpoints hello-service
# 輸出示例:
# NAME ENDPOINTS AGE
# hello-service 10.244.1.5:80,10.244.2.3:80,10.244.2.4:80 10m
# ↑
# Service自動發現的所有匹配Pod的IP
2. 標籤變化的影響
# 如果Pod的標籤變化,不再匹配Service的selector
# Service會自動將其從端點列表中移除
原始Pod標籤: app=frontend, version=v1
Service selector: app=frontend, version=v1
# 如果Pod標籤變為: app=frontend, version=v2
# Pod將不再接收來自該Service的流量
3. 無selector的Service
# Service也可以沒有selector,手動指定端點
apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
ports:
- port: 80
# 沒有selector,需要手動創建Endpoints對象
驗證方法
# 1. 查看Pod標籤
kubectl get pods --show-labels
# 2. 查看Service的selector
kubectl describe service hello-service | grep Selector
# 3. 查看Service關聯的端點
kubectl get endpoints hello-service
# 4. 測試連接
kubectl run test-$RANDOM --rm -i --image=busybox --restart=Never -- \
wget -qO- hello-service
常見誤區澄清
-
❌ Service選擇Deployment
- ✅ Service只選擇Pod,與Deployment無關
-
❌ 修改Deployment會影響Service
- ✅ 只有Pod的標籤變化才會影響Service
-
❌ Service和Deployment必須同名
- ✅ 它們可以任意命名,只需標籤匹配
-
❌ 一個Service只能關聯一個Deployment
- ✅ 一個Service可以關聯多個Deployment創建的Pod
總結
- Service selector → Pod標籤:Service直接選擇Pod,不關心Pod由誰創建
- 標籤匹配機制:Service的selector必須完全匹配Pod的標籤(所有key-value都對上)
- 動態更新:Pod標籤變化時,Service的端點列表自動更新
- 多對多關係:多個Service可以選擇同一組Pod,一個Pod可以被多個Service選擇
記住這個簡單規則:Service通過標籤找Pod,不關心Deployment的存在。