K8s 核心概念回顾:Pod、Deployment、Service、Ingress、Namespace 在灰度发布中的作用
在深入构建灰度发布流水线之前,必须重新审视 Kubernetes 的五大核心抽象。这些对象不仅是集群的“积木”,更是实现流量控制、版本隔离和容量基线留痕的底层机制。理解它们在灰度场景中的角色,是后续设计发布策略的基础。
1. 核心对象与灰度职责矩阵
下表从“灰度发布”视角,重新定义了每个 K8s 对象的核心职责与关键属性:
| 对象 | 灰度发布中的核心职责 | 关键属性 / 行为 |
|---|---|---|
| Pod | 承载业务进程的最小单元,灰度版本的“细胞”。 | 标签(labels)、就绪探针(readinessProbe)、资源请求/限制 |
| Deployment | 管理 Pod 副本的声明式更新与回滚,灰度版本的“编排器”。 | replicas、strategy(RollingUpdate / Recreate)、revisionHistoryLimit |
| Service | 提供稳定的虚拟 IP 和 DNS 名称,实现灰度流量的“负载均衡器”。 | selector(标签选择器)、type(ClusterIP / NodePort / LoadBalancer) |
| Ingress | 七层流量入口,基于域名/路径的“灰度路由网关”。 | annotations(nginx.ingress.kubernetes.io/canary)、rules、tls |
| Namespace | 逻辑隔离边界,用于“环境级”或“租户级”的灰度隔离。 | 资源配额(ResourceQuota)、网络策略(NetworkPolicy) |
2. 各对象在灰度批次中的深度解析
2.1 Pod:灰度版本的“原子单元”
Pod 是调度的最小单位。在灰度发布中,新版本的 Pod 通过 标签(labels) 与旧版本区分。例如,为金丝雀 Pod 添加 version: canary 标签。Pod 的 就绪探针(readinessProbe) 决定了流量何时切入,这是实现“无感灰度”的关键。
readinessProbe 应设置合理的 initialDelaySeconds 和 periodSeconds,避免因启动慢导致 Service 频繁摘除/挂载后端,造成流量抖动。
2.2 Deployment:灰度版本的“版本控制器”
Deployment 通过 ReplicaSet 管理 Pod 版本。在灰度场景中,通常维护两个 Deployment:app-stable(稳定版本)和 app-canary(灰度版本)。通过调整两者的 replicas 比例,即可控制灰度批次的大小。其 RollingUpdate 策略 中的 maxSurge 和 maxUnavailable 参数,直接决定了灰度扩容和缩容的速率。
# 金丝雀 Deployment 示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-canary
labels:
app: myapp
version: canary
spec:
replicas: 2 # 灰度批次大小
selector:
matchLabels:
app: myapp
version: canary
template:
metadata:
labels:
app: myapp
version: canary
spec:
containers:
- name: myapp
image: myapp:1.2.0-canary
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
2.3 Service:灰度流量的“稳定锚点”
Service 通过 标签选择器(selector) 将流量路由到后端 Pod。在灰度发布中,Service 的 selector 通常只匹配公共标签(如 app: myapp),而不匹配版本标签。这样,Service 会同时将流量分发到稳定版本和金丝雀版本的 Pod 上,实现“按比例”的负载均衡。
selector 包含了版本标签(如 version: stable),则灰度 Pod 将无法接收流量。灰度发布要求 Service 的 selector 必须“包容”所有版本。
2.4 Ingress:灰度路由的“七层网关”
Ingress 是灰度发布中最灵活的路由层。通过 Nginx Ingress Controller 的 canary 注解,可以实现基于 Header、Cookie 或 权重 的精细化流量分发。例如,只将携带 X-Canary: true 请求头的用户流量路由到金丝雀版本。
# 基于权重的金丝雀 Ingress 示例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-canary-ingress
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10" # 10% 流量
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-canary-svc
port:
number: 80
2.5 Namespace:灰度环境的“隔离边界”
Namespace 用于逻辑隔离。在大型灰度发布中,可以为每个灰度批次创建独立的 Namespace(如 prod-canary-v1),配合 NetworkPolicy 限制灰度 Pod 只能访问特定的数据库或缓存实例,防止灰度流量污染生产数据。
3. 灰度发布中的对象关系图
下图展示了灰度发布时,Ingress、Service、Deployment 和 Pod 之间的流量流转与版本关系:
4. 灰度发布中的标签与选择器策略
标签(Labels)是连接所有对象的“粘合剂”。在灰度发布中,推荐采用 多维度标签体系:
- app:标识应用名称,所有版本共享(如
app: myapp)。 - version:标识版本号,用于区分稳定版和金丝雀版(如
version: stable或version: canary)。 - track:标识发布轨道,用于更精细的流量控制(如
track: stable、track: canary、track: experimental)。
selector 应只包含 app 标签,不包含 version 或 track 标签。这样,Service 才能同时覆盖所有版本的 Pod,实现“无差别”的流量分发。版本间的流量比例,通过调整不同 Deployment 的 replicas 数量来实现。
5. 灰度批次中的容量基线留痕
容量基线留痕的核心在于:在灰度批次推进的每个阶段,记录下当前集群中 稳定版本 和 金丝雀版本 的 Pod 数量、资源使用量以及 Service 的端点状态。这些数据构成了“容量基线”。
下图展示了灰度批次推进过程中,容量基线的记录点:
通过在每个灰度批次节点执行 kubectl get pods -l app=myapp -o wide 和 kubectl describe svc myapp-svc,并将输出持久化到版本发布记录中,即可实现“容量基线留痕”。这为后续的容量评估、回滚决策和性能对比提供了不可篡改的审计依据。