You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kubernetes中通过单个Deployment实现双版本金丝雀部署?

关于单个Deployment实现金丝雀部署(同时运行v1和v2各3个Pod)的问题

首先直接给结论:单个Deployment无法长期稳定地同时运行v1和v2各3个Pod,这和Deployment的设计初衷有关,下面详细解释并给出可行方案。

为什么你的两个Deployment只运行了最新版本?

你创建的两个Deployment的metadata.name都是process,而Kubernetes要求同一命名空间下的资源名称必须唯一。当你创建第二个Deployment时,它会覆盖第一个Deployment的配置——K8s会认为你是在更新已有的process Deployment,因此会逐步将第一个Deployment对应的ReplicaSet(管理v1 Pod)的副本数缩为0,只保留第二个Deployment对应的ReplicaSet(管理v2 Pod)的3个Pod,这就是为什么你只看到了最新版本的Pod。

能不能用单个Deployment实现同时运行v1和v2各3个Pod?

答案是不能长期稳定实现。Deployment的核心逻辑是通过ReplicaSet管理同一版本的Pod,它的滚动更新机制是逐步替换旧版本Pod为新版本,最终只会保留一个活跃的ReplicaSet(除非你通过revisionHistoryLimit保留旧ReplicaSet,但旧ReplicaSet的副本数会被缩为0)。

如果你想临时实现“v1和v2各3个Pod”的状态(比如做金丝雀验证),可以通过以下步骤操作,但这只是临时状态,无法长期维持:

  1. 先创建初始的v1 Deployment,设置replicas: 6
  2. 更新Deployment的镜像为v2,同时配置滚动更新参数:
    spec:
      strategy:
        rollingUpdate:
          maxSurge: 3       # 最多新增3个Pod
          maxUnavailable: 0 # 不允许旧版本Pod被删除
    
  3. 当K8s启动3个v2 Pod后,立即暂停滚动更新:
    kubectl rollout pause deployment process
    

此时你会看到v1和v2各3个Pod,但这个状态是临时的——如果你恢复滚动更新(kubectl rollout resume deployment process),K8s会继续将剩余的v1 Pod替换为v2 Pod,最终全部变为v2。

推荐的金丝雀部署方案(长期稳定运行两个版本)

如果你需要长期同时运行v1和v2的Pod,建议使用两个独立的Deployment,具体步骤如下:

1. 修改两个Deployment的名称

将两个Deployment的metadata.name改为不同的名称,比如process-v1和process-v2,各自保持replicas: 3:

deployment-process-v1.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: process-v1
  labels:
    app: process
    version: v1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: process
      version: v1
  template:
    metadata:
      labels:
        app: process
        version: v1
    spec:
      containers:
      - name: pull
        image: parma/k8s-php:red
        ports:
        - containerPort: 80

deployment-process-v2.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: process-v2
  labels:
    app: process
    version: v2
spec:
  replicas: 3
  selector:
    matchLabels:
      app: process
      version: v2
  template:
    metadata:
      labels:
        app: process
        version: v2
    spec:
      containers:
      - name: pull
        image: parma/k8s-php:green
        ports:
        - containerPort: 80

2. 创建Service统一入口

创建一个Service,通过app: process标签匹配两个版本的Pod:

apiVersion: v1
kind: Service
metadata:
  name: process-service
spec:
  selector:
    app: process
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

3. 实现流量分流(金丝雀核心)

如果需要将部分流量导向v2,其余导向v1,可以通过以下方式:

  • Ingress流量拆分:比如使用NGINX Ingress配置权重,将指定比例的流量导向v2,剩余导向v1
  • Service Mesh:使用Istio、Linkerd等工具,更精细地控制流量比例、灰度发布策略

这种方案的优势是两个Deployment完全独立,各自管理自己的ReplicaSet和Pod,你可以随时调整每个版本的副本数、更新版本,而不会互相影响,是生产环境中金丝雀部署的常用方式。

内容的提问来源于stack exchange,提问作者Paramanand Dhuri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:55:20