K8S灰度发布与蓝绿部署实战指南-CSDN博客

张开发
2026/5/12 14:06:19 15 分钟阅读

分享文章

K8S灰度发布与蓝绿部署实战指南-CSDN博客
Kubernetes灰度发布与蓝绿部署实战指南从原理到生产落地导读在生产环境中应用升级发布是最常见的运维操作之一也是最容易引发故障的环节。一次不当的发布可能导致线上服务大面积中断甚至造成严重的业务损失。本文将深入讲解Kubernetes中两种最主流的发布策略——灰度发布金丝雀发布和蓝绿部署从设计思路、YAML编写、逐步实操到生产环境选型建议带你从入门到精通。一、为什么需要发布策略在企业级生产环境中直接将旧版本一刀切替换为新版本是极其危险的做法。假设你的应用每天有100万次请求新版本存在一个隐藏的Bug导致5%的请求失败那么直接发布后瞬间就会有5万次失败请求——这对用户体验和业务声誉的打击是巨大的。因此业界发展出了多种渐进式发布策略核心目标只有一个在不影响用户体验的前提下安全、可控地将新版本推向全量。1.1 三种主流发布策略对比策略原理优点缺点适用场景灰度发布金丝雀新旧版本按比例共存逐步调大新版本、缩小旧版本风险可控资源利用率高回滚简单流量分配粒度受副本数限制常规功能迭代、Bug修复蓝绿部署同时运行两套完整环境通过切换Service流量实现发布切换瞬间完成回滚即时需要双倍资源成本较高重大版本升级、大促保障A/B测试基于用户特征精确路由到不同版本精细化控制可量化对比实现复杂需要额外的流量网关支持功能实验、用户行为分析二、灰度发布实战2.1 设计思路灰度发布也叫金丝雀发布的核心思想是让新旧版本短期共存通过逐步调整副本数让新版本逐渐蚕食旧版本的流量。发布流程: 1. 旧版本 Deployment 部署 3 个副本承载全部流量 2. 新版本 Deployment 部署 0 个副本待命 3. Service 同时匹配新旧版本的 Pod通过共享标签 appsxiuxian 4. 逐步调整旧 3→2→1→0新 0→1→2→3 5. 验证无误后删除旧版本 Deployment关键点Service 的selector使用的是新旧版本共享的公共标签如apps: xiuxian而不是版本标签。这样才能让流量同时分配到新旧版本的 Pod。2.2 环境准备首先部署旧版本v1# 01-deploy-apps-v1.yamlapiVersion:apps/v1kind:Deploymentmetadata:name:deploy-xiuxian-oldspec:replicas:3selector:matchLabels:apps:xiuxianversion:v1template:metadata:labels:apps:xiuxianspec:containers:-name:c1image:registry.cn-hangzhou.aliyuncs.com/eci_open/nginx:latest创建 Service注意 selector 只使用公共标签# 02-svc-xiuxian.yamlapiVersion:v1kind:Servicemetadata:name:svc-xiuxianspec:type:ClusterIPselector:apps:xiuxian# 关键只用公共标签不区分版本ports:-port:80部署并验证# 部署旧版本kubectl apply-f01-deploy-apps-v1.yaml kubectl apply-f02-svc-xiuxian.yaml# 确认Pod运行正常kubectl get pods-owide NAME READY STATUS RESTARTS AGE IP NODE deploy-xiuxian-old-568cf47956-fpx841/1 Running04s10.100.2.231 worker233 deploy-xiuxian-old-568cf47956-qlww51/1 Running04s10.100.2.230 worker233 deploy-xiuxian-old-568cf47956-tgqnx1/1 Running04s10.100.1.145 worker232# 确认Service已关联kubectl get svc svc-xiuxian-owide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)AGE SELECTOR svc-xiuxian ClusterIP10.200.64.17none80/TCP 4m34sappsxiuxian此时访问 Service IP所有请求都由 v1 版本处理。2.3 开始灰度部署新版本# 03-deploy-apps-v2.yamlapiVersion:apps/v1kind:Deploymentmetadata:name:deploy-xiuxian-newspec:replicas:1# 先只启动1个新版本Podselector:matchLabels:apps:xiuxianversion:v2template:metadata:labels:apps:xiuxianspec:containers:-name:c1image:registry.cn-hangzhou.aliyuncs.com/acs/nginx:1.21kubectl apply-f03-deploy-apps-v2.yaml此时集群中有 3个旧版本Pod 1个新版本PodService 会将流量轮询分配到这4个Pod新版本自然承担了约25%的流量。2.4 逐步灰度调整副本比例这就是灰度发布最核心的操作——通过kubectl scale命令逐步调整新旧版本的副本数# 第一步旧3→2新1→2各50%流量kubectl scale deployment deploy-xiuxian-old--replicas2kubectl scale deployment deploy-xiuxian-new--replicas2# 验证Pod状态kubectl get pods-owide NAME READY STATUS RESTARTS AGE IP deploy-xiuxian-new-845ffc675b-4zf2z1/1 Running02s10.100.1.146 deploy-xiuxian-new-845ffc675b-9jt5c1/1 Running080s10.100.2.232 deploy-xiuxian-old-568cf47956-fpx841/1 Running08m14s10.100.2.231 deploy-xiuxian-old-568cf47956-tgqnx1/1 Running08m14s10.100.1.145# 第二步旧2→1新2→3新版本占75%流量kubectl scale deployment deploy-xiuxian-new--replicas3kubectl scale deployment deploy-xiuxian-old--replicas1# 验证Pod状态kubectl get pods-owide NAME READY STATUS RESTARTS AGE IP deploy-xiuxian-new-845ffc675b-4zf2z1/1 Running063s10.100.1.146 deploy-xiuxian-new-845ffc675b-9jt5c1/1 Running02m21s10.100.2.232 deploy-xiuxian-new-845ffc675b-fsnwv1/1 Running014s10.100.2.233 deploy-xiuxian-old-568cf47956-fpx841/1 Running09m15s10.100.2.231# 第三步旧1→0完成全量切换kubectl scale deployment deploy-xiuxian-old--replicas0# 确认只剩新版本kubectl get pods-owide NAME READY STATUS RESTARTS AGE IP deploy-xiuxian-new-845ffc675b-4zf2z1/1 Running089s10.100.1.146 deploy-xiuxian-new-845ffc675b-9jt5c1/1 Running02m47s10.100.2.232 deploy-xiuxian-new-845ffc675b-fsnwv1/1 Running040s10.100.2.233提示在整个灰度过程中可以使用while true; do curl Service-IP; sleep 0.1; done持续观察响应内容确认新版本是否正常工作。2.5 灰度发布流程图解时间轴 → 阶段1 [全量v1] 阶段2 [灰度25%] 阶段3 [灰度50%] 阶段4 [灰度75%] 阶段5 [全量v2] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 旧版本Pod: [●][●][●] [●][●][●] [●][●] [●] (已清除) [●] new [●][●] new [●][●][●] new 新版本Pod: (未创建) ↑ 25% ↑↑ 50% ↑↑↑ 75% ↑↑↑ 100% Service: selector: selector: selector: selector: selector: apps:xiuxian apps:xiuxian apps:xiuxian apps:xiuxian apps:xiuxian 关键操作: 初始状态 部署new(1副本) scale old→2 new→2 scale old→1 new→3 scale old→02.6 灰度发布回滚如果在灰度过程中发现新版本有问题回滚非常简单# 一键回滚直接把新版本副本缩为0旧版本恢复到3kubectl scale deployment deploy-xiuxian-new--replicas0kubectl scale deployment deploy-xiuxian-old--replicas3# 确认回滚成功kubectl get pods-owide这就是灰度发布最大的优势回滚成本极低秒级恢复。三、蓝绿部署实战3.1 设计思路蓝绿部署与灰度发布的关键区别在于两套环境始终各自运行完整的副本数通过修改 Service 的selector来决定流量指向哪套环境。发布流程: 1. 旧版本蓝环境Deployment 部署 3 个副本 2. 新版本绿环境Deployment 部署 3 个副本 3. Service selector 指向旧版本标签version: v1 4. 验证新版本Pod正常运行后修改 Service selector 指向新版本标签version: v2 5. 流量瞬间全部切换到新版本3.2 同时部署两套环境蓝环境旧版本 v1# 01-deploy-apps-v1-blue.yamlapiVersion:apps/v1kind:Deploymentmetadata:name:deploy-xiuxian-bluespec:replicas:3selector:matchLabels:apps:xiuxianversion:v1template:metadata:labels:apps:xiuxianversion:v1spec:containers:-name:c1image:registry.cn-hangzhou.aliyuncs.com/eci_open/nginx:latest绿环境新版本 v2# 02-deploy-apps-v2-green.yamlapiVersion:apps/v1kind:Deploymentmetadata:name:deploy-xiuxian-greenspec:replicas:3selector:matchLabels:apps:xiuxianversion:v2template:metadata:labels:apps:xiuxianversion:v2spec:containers:-name:c1image:registry.cn-hangzhou.aliyuncs.com/acs/nginx:1.21部署两套环境kubectl apply-f01-deploy-apps-v1-blue.yaml-f02-deploy-apps-v2-green.yaml# 确认两套环境都正常运行kubectl get pods-owide NAME READY STATUS RESTARTS AGE IP deploy-xiuxian-blue-568cf47956-fff9l1/1 Running05s10.100.2.238 worker233 deploy-xiuxian-blue-568cf47956-ptvxm1/1 Running05s10.100.2.237 worker233 deploy-xiuxian-blue-568cf47956-x7nwn1/1 Running05s10.100.1.148 worker232 deploy-xiuxian-green-845ffc675b-jmq781/1 Running05s10.100.1.149 worker232 deploy-xiuxian-green-845ffc675b-nh2js1/1 Running05s10.100.2.239 worker233 deploy-xiuxian-green-845ffc675b-zdbsq1/1 Running05s10.100.2.236 worker233# 查看标签确认版本区分kubectl get pods --show-labels NAME READY LABELS deploy-xiuxian-blue-568cf47956-fff9l1/1appsxiuxian,pod-template-hash568cf47956,versionv1 deploy-xiuxian-blue-568cf47956-ptvxm1/1appsxiuxian,pod-template-hash568cf47956,versionv1 deploy-xiuxian-blue-568cf47956-x7nwn1/1appsxiuxian,pod-template-hash568cf47956,versionv1 deploy-xiuxian-green-845ffc675b-jmq781/1appsxiuxian,pod-template-hash845ffc675b,versionv2 deploy-xiuxian-green-845ffc675b-nh2js1/1appsxiuxian,pod-template-hash845ffc675b,versionv2 deploy-xiuxian-green-845ffc675b-zdbsq1/1appsxiuxian,pod-template-hash845ffc675b,versionv23.3 创建 Service 并指向蓝环境注意蓝绿部署中 Service 的 selector 使用的是version标签来区分版本这与灰度发布使用公共标签的方式完全不同。# 03-svc-xiuxian.yaml 初始指向蓝环境apiVersion:v1kind:Servicemetadata:name:svc-xiuxianspec:type:ClusterIPselector:version:v1# 指向蓝环境旧版本ports:-port:80kubectl apply-f03-svc-xiuxian.yaml kubectl get svc svc-xiuxian-owide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)AGE SELECTOR svc-xiuxian ClusterIP10.200.88.148none80/TCP 7sversionv1此时所有流量都指向蓝环境v1绿环境v2虽然运行着3个Pod但不接收任何流量——这正是蓝绿部署空跑的含义。3.4 切换流量一键发布确认绿环境Pod运行正常后只需修改 Service 的 selector# 03-svc-xiuxian.yaml 修改后指向绿环境apiVersion:v1kind:Servicemetadata:name:svc-xiuxianspec:type:ClusterIPselector:version:v2# 切换到绿环境新版本ports:-port:80kubectl apply-f03-svc-xiuxian.yaml kubectl get svc svc-xiuxian-owide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)AGE SELECTOR svc-xiuxian ClusterIP10.200.88.148none80/TCP 72sversionv2流量切换瞬间完成从这一刻起所有请求都由绿环境v2处理蓝环境变为空跑状态。3.5 蓝绿部署回滚如果发现问题回滚同样简单# 把selector改回v1即可# 修改 03-svc-xiuxian.yaml 中 selector.version 为 v1kubectl apply-f03-svc-xiuxian.yaml一键切换秒级回滚。这就是蓝绿部署的核心优势。3.6 蓝绿部署流程图解时间轴 → 阶段1 [蓝环境上线] 阶段2 [绿环境就绪] 阶段3 [流量切换] 阶段4 [清理蓝环境] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 蓝环境(v1): [●][●][●] [●][●][●] [●][●][●] (删除) ↑ 承载流量 ↑ 承载流量 (空跑) 绿环境(v2): (未创建) [●][●][●] [●][●][●] [●][●][●] (空跑) ↑ 承载流量 ↑ 承载流量 Service: selector: selector: selector: selector: version:v1 version:v1 version:v2 version:v2 关键操作: 部署蓝环境 部署绿环境 修改selector 删除蓝环境四、灰度发布 vs 蓝绿部署核心区别通过前面的实战我们来对比两种策略的关键差异4.1 Service Selector 使用方式对比这是两种策略最本质的技术差异对比项灰度发布蓝绿部署Service selector使用公共标签如apps: xiuxian使用版本标签如version: v1/v2流量分配方式按Pod数量比例自动分配Service只指向一套环境100%流量新旧版本关系新旧版本共存于同一个Service新旧版本各自独立Service只选其一资源消耗渐进式峰值约2倍始终2倍资源切换方式调整副本数kubectl scale修改selector标签kubectl apply4.2 适用场景决策你的发布需求是什么 │ ├── 需要精确控制流量比例如先放5%试试 │ └── ✅ 选择灰度发布 │ (通过副本数比例控制流量分配) │ ├── 需要瞬间完成切换不能有过渡期 │ └── ✅ 选择蓝绿部署 │ (修改selector即可切换即时生效) │ ├── 集群资源紧张不能双倍部署 │ └── ✅ 选择灰度发布 │ (总副本数保持不变逐步替换) │ ├── 发布风险极高需要随时秒级回滚 │ └── ✅ 选择蓝绿部署 │ (新旧环境都在运行回滚就是改回selector) │ └── 常规迭代风险可控 └── ✅ 选择灰度发布更省资源更常用五、生产环境进阶实践5.1 结合 ReadinessProbe 确保安全发布无论是灰度还是蓝绿都应该为新版本Pod配置就绪探针确保只有真正就绪的Pod才会被Service纳入后端spec:containers:-name:c1image:registry.cn-hangzhou.aliyuncs.com/acs/nginx:1.21readinessProbe:httpGet:path:/port:80initialDelaySeconds:5periodSeconds:3failureThreshold:3为什么这很重要如果新版本Pod启动后虽然处于Running状态但应用内部尚未完成初始化比如加载缓存、连接数据库等没有ReadinessProbe的话Service会立即将流量发给它导致大量请求失败。5.2 使用 kubectl rollout 管理发布版本Kubernetes 的 Deployment 控制器本身就内置了发布管理能力# 查看发布历史kubectl rollouthistorydeployment deploy-xiuxian-new# 查看某个版本的详细信息kubectl rollouthistorydeployment deploy-xiuxian-new--revision2# 回滚到上一版本kubectl rollout undo deployment deploy-xiuxian-new# 回滚到指定版本kubectl rollout undo deployment deploy-xiuxian-new --to-revision1# 查看发布状态kubectl rollout status deployment deploy-xiuxian-new5.3 灰度发布的比例控制优化在基础灰度方案中流量比例受限于副本总数如3个副本只能实现0%/33%/67%/100%的比例。在生产环境中可以结合以下方式实现更精细的控制方案一增加副本总数将总副本数从3增加到10就可以实现10%为步进的精细化灰度# 10%灰度v19, v21kubectl scale deployment deploy-old--replicas9kubectl scale deployment deploy-new--replicas1# 30%灰度v17, v23kubectl scale deployment deploy-old--replicas7kubectl scale deployment deploy-new--replicas3# 50%灰度v15, v25kubectl scale deployment deploy-old--replicas5kubectl scale deployment deploy-new--replicas5方案二使用 Ingress 控制器实现权重路由更高级的做法是借助 Nginx Ingress、Traefik 等网关通过注解实现基于权重的流量分配# Nginx Ingress Canary 方式需安装 nginx-ingress-controllerapiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:xiuxian-canaryannotations:nginx.ingress.kubernetes.io/canary:truenginx.ingress.kubernetes.io/canary-weight:30# 30%流量到新版本spec:rules:-http:paths:-path:/pathType:Prefixbackend:service:name:svc-xiuxian-newport:number:805.4 蓝绿部署的资源优化蓝绿部署最大的痛点是资源占用翻倍。在生产环境中可以采用以下策略优化降配空跑环境将空跑环境的副本数降低到最小可用数如1个而非与线上保持一致使用 HorizontalPodAutoscaler让非活跃环境自动缩容到最低副本数结合 PodDisruptionBudget确保切换过程中始终有足够的Pod可用# 蓝绿切换后将旧环境缩到1个副本备用kubectl scale deployment deploy-xiuxian-blue--replicas1# 观察24小时无问题后彻底删除kubectl delete deployment deploy-xiuxian-blue5.5 自动化发布流水线将发布策略集成到CI/CD流水线中可以实现自动化的灰度或蓝绿发布// Jenkinsfile - 灰度发布示例pipeline{agent any parameters{string(name:IMAGE_TAG,defaultValue:v2,description:镜像版本)}stages{stage(灰度部署 - 10%){steps{shkubectl scale deployment deploy-old --replicas9shkubectl scale deployment deploy-new --replicas1shsleep 60// 观察60秒}}stage(灰度部署 - 50%){steps{shkubectl scale deployment deploy-old --replicas5shkubectl scale deployment deploy-new --replicas5shsleep 120// 观察120秒}}stage(全量发布){steps{shkubectl scale deployment deploy-new --replicas10shkubectl scale deployment deploy-old --replicas0}}}}六、发布策略速查表操作场景灰度发布命令蓝绿部署命令部署新版本kubectl apply -f deploy-v2.yamlkubectl apply -f deploy-v2.yaml开始灰度/发布kubectl scale deploy-new --replicas1kubectl apply -f svc-v2.yaml扩大新版本比例kubectl scale deploy-new --replicasNN/A蓝绿是瞬间切换回滚kubectl scale deploy-new --replicas0 kubectl scale deploy-old --replicas3修改svc selector: version: v1后kubectl apply查看流量分布kubectl get pods --show-labelskubectl get svc -o wide清理旧版本kubectl delete deployment deploy-oldkubectl delete deployment deploy-blue七、总结本文通过完整的实战操作深入讲解了Kubernetes中两种最主流的发布策略灰度发布通过共享标签 逐步调整副本数实现渐进式发布资源利用率高是最常用的发布策略。核心是 Service selector 使用公共标签让K8S自动按Pod数量比例分配流量。蓝绿部署通过版本标签 切换 Service selector 实现瞬间切换适合高风险发布场景。核心是两套完整环境同时运行切换只是改一个标签值。实践建议在实际工作中推荐以灰度发布为主、蓝绿部署为辅的组合策略。日常迭代使用灰度发布节省资源重大版本升级时使用蓝绿部署确保安全。同时务必配合 ReadinessProbe 和健康检查机制让发布更加安全可控。环境信息Kubernetes: v1.23.17部署方式: kubeadm容器运行时: DockerCNI: Flannel

更多文章