k8s下的发布策略详解
一. 引言:
在 Kubernetes(K8s)的生态体系中,保障应用部署的稳定性与可靠性至关重要。业界常见的发布策略有: 金丝雀发布、蓝绿发布以及灰度发布。接下来我们探讨这三种发布方案在 K8s 环境中的实现方式、优势及适用场景。
二. 不同发布策略对比:
类型 | 优点 | 使用场景 |
金丝雀发布 | 降低风险,通过小范围测试提前发现问题,避免影响大量用户;能够快速获取真实用户反馈,便于及时优化;可以灵活控制新版本的推广速度和范围。 | 适用于对稳定性要求极高、新功能变动较大或可能对用户体验产生较大影响的应用发布,如核心业务系统、金融交易类应用等。 |
蓝绿发布 | 切换过程理论上可以瞬时完成,能最大程度减少服务中断时间;回滚操作非常简单,只需切换 Service 选择器;新版本有独立完整的环境进行充分测试。 | 适用于对服务中断时间要求极高、版本差异较大且需要完整环境测试的关键业务系统,如电商平台的核心交易模块、在线支付系统等。资源消耗较大 |
灰度发布 | 降低发布风险,通过小范围验证避免全局性故障;可以快速回滚到旧版本;能够根据多种条件精准选择灰度用户,优化用户体验;逐步发布对整体系统的冲击较小。 | 适用于各类应用的发布,尤其是对用户体验较为敏感、需要根据不同用户群体进行差异化发布的应用,如社交类应用、内容平台等。可以根据用户活跃度、地域等因素,先对部分用户进行灰度测试,收集反馈后再进行优化和扩大发布范围。 |
接下来我们讲一讲不同发布策略
三. 金丝雀发布
1. 概念与原理:金丝雀发布的灵感来源于煤矿工人利用金丝雀检测瓦斯泄漏的做法。在软件发布领域,它指的是先将新版本软件部署到一小部分服务器或用户中,这部分服务器或用户就如同 “金丝雀”。通过密切监控这一小部分实例的运行情况,收集性能指标、错误率、用户反馈等数据,来评估新版本的稳定性和兼容性。如果金丝雀版本运行良好,没有出现严重问题,那么就可以逐步扩大新版本的部署范围,直到完全替代旧版本。在 K8s 中,实现金丝雀发布主要依靠对 Deployment 资源的灵活运用以及合理配置 Service 来控制流量路由。
2. 实现方式:
a). 基于 Deployment 副本比例:通过创建两个 Deployment,分别对应旧版本和新版本。例如,旧版本的 Deployment 设置较高的副本数(如 3 个),新版本的 Deployment 设置较低的副本数(如 1 个)。这样,在 Service 进行负载均衡时,大部分流量(75%)会被导向旧版本 Pod,小部分流量(25%)会被导向新版本 Pod。
然后创建一个 Service,通过标签选择器同时选中新旧版本的 Pod,实现流量在两者之间的分配。
apiVersion: v1
kind: Service
metadata:name: myapp-service
spec:selector:app: myappports:- port: 80targetPort: 8080
b). 借助服务网格(如 Istio):Istio 提供了强大的流量管理功能。通过定义 VirtualService 和 DestinationRule 资源,可以非常精细地控制流量。例如,可以根据请求的来源、目标、请求头等多种条件,将特定比例的流量导向新版本服务。
# VirtualService定义流量路由规则
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: myapp-vs
spec:hosts:- myapp.example.comhttp:- route:- destination:host: myapp-v1subset: v1weight: 90 - destination:host: myapp-v2subset: v2weight: 10
# DestinationRule定义服务子集
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:name: myapp-dr
spec:host: myappsubsets:- name: v1labels:version: v1- name: v2labels:version: v2
四. 蓝绿发布:
1. 概念与原理: 蓝绿发布的核心是同时维护两个完全相同的生产环境,即 “蓝环境” 和 “绿环境”。蓝环境运行当前稳定的旧版本应用,绿环境部署即将上线的新版本应用。在发布时,先将绿环境部署好并进行充分的内部测试。当绿环境验证通过后,通过快速切换负载均衡器的配置,将所有用户流量从蓝环境切换到绿环境,完成发布过程。如果在新版本上线后发现问题,可以立即将流量切回蓝环境,实现快速回滚。
2. 实现方式:
# 蓝环境(旧版本)Deployment
apiVersion: apps/v1
kind: Deployment
metadata:name: app-blue
spec:replicas: 3selector:matchLabels:app: myappversion: bluetemplate:metadata:labels:app: myappversion: bluespec:containers:- name: myappimage: myapp:v1.0.0ports:- containerPort: 8080
---
# 绿环境(新版本)Deployment
apiVersion: apps/v1
kind: Deployment
metadata:name: app-green
spec:replicas: 3selector:matchLabels:app: myappversion: greentemplate:metadata:labels:app: myappversion: greenspec:containers:- name: myappimage: myapp:v1.1.0ports:- containerPort: 8080
---
# 流量入口Service
apiVersion: v1
kind: Service
metadata:name: myapp-service
spec:selector:app: myappversion: blue ports:- port: 80targetPort: 8080type: LoadBalancer
在初始阶段,Service 的选择器指向蓝环境的 Deployment。当绿环境部署并测试完成后,通过修改 Service 的选择器,将其指向绿环境的 Deployment,实现流量的快速切换。
kubectl patch service myapp-service -p '{"spec":{"selector":{"version":"green"}}}'
五. 灰度发布:
1. 概念与原理: 灰度发布,本质上与金丝雀发布类似,也是一种渐进式的发布策略。它将新版本应用逐步推送给一小部分用户,通过对这部分用户使用情况的观察和数据分析,评估新版本的稳定性和性能。与金丝雀发布略有不同的是,灰度发布更强调按比例逐步扩大新版本的覆盖范围,并且可以根据多种条件(如用户地域、用户类型等)来精准地选择灰度用户群体。在 K8s 中,灰度发布同样依赖于对资源的精细管理和流量控制。
2. 实现方式:
通过 Ingress 注解实现:利用 Nginx Ingress Controller 的注解功能,可以方便地实现灰度发布。首先部署新旧两个版本的应用,创建对应的 Deployment 和 Service 资源。
# v1版本Deployment
apiVersion: apps/v1
kind: Deployment
metadata:name: my-app-v1
spec:replicas: 3selector:matchLabels:app: my-appversion: v1template:metadata:labels:app: my-appversion: v1spec:containers:- name: my-appimage: my-app:v1ports:- containerPort: 80
# v1版本Service
apiVersion: v1
kind: Service
metadata:name: my-app-v1
spec:selector:app: my-appversion: v1ports:- port: 80targetPort: 80
然后配置 Ingress 资源,通过注解来控制流量分配。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: my-app-ingressannotations:nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "10"
spec:rules:- host: my-app.example.comhttp:paths:- path: /pathType: Prefixbackend:service:name: my-app-v2 port:number: 80- host: my-app.example.comhttp:paths:- path: /pathType: Prefixbackend:service:name: my-app-v1 port:number: 80
这里,nginx.ingress.kubernetes.io/canary: "true"
启用灰度发布功能,nginx.ingress.kubernetes.io/canary-weight: "10"
表示将 10% 的流量分配到新版本(v2),剩余 90% 的流量继续使用旧版本(v1)。在发布过程中,可以根据需要动态调整canary-weight
的值,逐步增加新版本的流量比例。
不同场景,选择不同的策略。
- - ---------------------------------------------------------------------------------------------------------------------
深耕运维行业多年,擅长运维体系建设,方案落地。欢迎交流!
“V-x”: ywjw996
《 运维经纬 》