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) 决定了流量何时切入,这是实现“无感灰度”的关键。

实践要点: 灰度 Pod 的 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 上,实现“按比例”的负载均衡。

注意: 如果 Service 的 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 之间的流量流转与版本关系:

灰度发布核心对象关系图 用户请求 Ingress Service Deployment (stable) replicas: 8 Deployment (canary) replicas: 2 Pod (v1.0) Pod (v1.0) Pod (v1.0) Pod (v1.2) Pod (v1.2) 说明:Service 通过公共标签(app: myapp)同时路由到稳定和金丝雀 Pod,实现按副本比例的流量分发。

4. 灰度发布中的标签与选择器策略

标签(Labels)是连接所有对象的“粘合剂”。在灰度发布中,推荐采用 多维度标签体系:

  • app:标识应用名称,所有版本共享(如 app: myapp)。
  • version:标识版本号,用于区分稳定版和金丝雀版(如 version: stable 或 version: canary)。
  • track:标识发布轨道,用于更精细的流量控制(如 track: stable、track: canary、track: experimental)。
关键原则: Service 的 selector 应只包含 app 标签,不包含 version 或 track 标签。这样,Service 才能同时覆盖所有版本的 Pod,实现“无差别”的流量分发。版本间的流量比例,通过调整不同 Deployment 的 replicas 数量来实现。

5. 灰度批次中的容量基线留痕

容量基线留痕的核心在于:在灰度批次推进的每个阶段,记录下当前集群中 稳定版本 和 金丝雀版本 的 Pod 数量、资源使用量以及 Service 的端点状态。这些数据构成了“容量基线”。

下图展示了灰度批次推进过程中,容量基线的记录点:

灰度批次容量基线留痕时间线 基线 100% 稳定 批次 1 10% 金丝雀 批次 2 30% 金丝雀 全量 100% 新版本 每个批次节点记录以下容量基线数据: 稳定 Pod 数 / 金丝雀 Pod 数 / Service 端点数 / CPU & 内存使用率

通过在每个灰度批次节点执行 kubectl get pods -l app=myapp -o wide 和 kubectl describe svc myapp-svc,并将输出持久化到版本发布记录中,即可实现“容量基线留痕”。这为后续的容量评估、回滚决策和性能对比提供了不可篡改的审计依据。