时间:2025-12-29 10:13
人气:
作者:admin
这是选择器(Selector),用于告诉Deployment:
这是模板标签(Template Labels),用于:
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
假设:
deployment: helloapp: hello结果:
app: hello 标签deployment: hello 的Podselector:
matchLabels:
app: myapp # 匹配所有myapp的Pod,无论版本
template:
metadata:
labels:
app: myapp
version: v1.2.3 # 创建特定版本的Pod
# Deployment A
selector:
matchLabels:
app: myapp
tier: frontend
# Deployment B(也可以管理同样的Pod)
selector:
matchLabels:
app: myapp
managed-by: deployment-b
# 主Deployment
selector:
matchLabels:
app: myapp
track: stable
# 金丝雀Deployment
selector:
matchLabels:
app: myapp
track: canary
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制造新人。
完全正确!你的理解非常准确。
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
# Deployment
template.metadata.labels:
app: frontend
component: web
# Service
selector:
app: frontend
component: web
# 精确匹配特定应用的特定组件
# 多个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
# 金丝雀部署场景
# 稳定版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
# 当新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
# 如果Pod的标签变化,不再匹配Service的selector
# Service会自动将其从端点列表中移除
原始Pod标签: app=frontend, version=v1
Service selector: app=frontend, version=v1
# 如果Pod标签变为: app=frontend, version=v2
# Pod将不再接收来自该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
❌ 修改Deployment会影响Service
❌ Service和Deployment必须同名
❌ 一个Service只能关联一个Deployment
记住这个简单规则:Service通过标签找Pod,不关心Deployment的存在。
作者:仓储大叔,张占岭,
荣誉:微软MVP
QQ:853066980
支付宝扫一扫,为大叔打赏!

Ubuntu离线环境部署Kubernetes v1.31.3(ARM64)