kubernetes基于nginx-ingress进行蓝绿部署/金丝雀发布(canary)
几年前的发布方式:
在关闭版本A后部署版本B. 此技术意味着服务的停机时间取决于应用程序的关闭和启动持续时间。 对用户的影响很大
kubernetes滚动更新方式:
滚动更新策略包括通过逐个替换实例来逐步更新应用程序的版本,直到所有实例都更新为止。它通常遵循以下过程:在负载均衡器后面使用版本A池,部署版本B的一个实例。当服务准备好接受流量时,该实例将添加到池中。然后,从池中删除一个版本A的实例并关闭。
您可以调整以下参数以增加部署时间:
maxSurge:除当前数量外还要添加多少个实例。
maxUnavailable:滚动更新过程中的不可用实例数。
蓝绿部署:
蓝/绿部署策略,版本B(绿色)与版本A(蓝色)一起部署,实例数量完全相同。在测试新版本满足所有要求后,流量在负载均衡器级别从版本A切换到版本B.
canary:
丝雀部署包括逐渐将生产流量从版本A转移到版本B.通常,流量根据权重进行划分。例如,90%的请求转到版本A,10%请求转到版本B.
A / B测试
A / B测试部署包括在特定条件下将用户子集路由到新功能。它通常是一种基于统计信息而非部署策略制定业务决策的技术。可以通过为canary部署添加额外的功能来实现
- nginx ingress版本必须大于或等于0.22.0 在0.21.0版本基于cookie有问题
-
https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#canary
ingress-nginx 从 0.21.0 开始支持金丝雀(canary)模式在某些情况下,您可能希望通过将少量请求发送到与生产服务不同的服务来“加入”一组新的更改。金丝雀annotations使Ingress规范可以作为路由到请求的替代服务,具体取决于应用的规则。nginx.ingress.kubernetes.io/canary: “true” 设置后,可以启用以下annotations来配置canary
nginx.ingress.kubernetes.io/canary-by-header
用于通知Ingress将请求路由到Canary Ingress中指定的服务的标头。当请求标头设置always时,它将被路由到金丝雀。当标头设置never为时,它将永远不会被路由到金丝雀。对于任何其他值,将忽略标头,并通过优先级将请求与其他金丝雀规则进行比较。nginx.ingress.kubernetes.io/canary-by-header-value:
要匹配的标头值,用于通知Ingress将请求路由到Canary Ingress中指定的服务。当请求标头设置为此值时,它将被路由到金丝雀。对于任何其他标头值,标头将被忽略,并且请求与其他金丝雀规则的优先级进行比较。此注释必须与nginx.ingress.kubernetes.io/canary-by-header一起使用。nginx.ingress.kubernetes.io/canary-by-header允许自定义标头值而不是使用硬编码值的扩展。如果nginx.ingress.kubernetes.io/canary-by-header未定义注释,则没有任何效果。
nginx.ingress.kubernetes.io/canary-by-cookie:
用于通知Ingress将请求路由到Canary Ingress中指定的服务的cookie。当cookie值设置always时,它将被路由到金丝雀。当cookie被设置never时,它将永远不会被路由到金丝雀。对于任何其他值,将忽略cookie并将请求与其他金丝雀规则进行优先比较。nginx.ingress.kubernetes.io/canary-weight:
该路由到金丝雀Ingress中指定的服务的随机请求的整数(0 – 100)百分比。权重为0意味着该金丝雀规则不会向Canary入口中的服务发送任何请求。权重为100意味着所有请求都将被发送到Ingress中指定的替代服务。
金丝雀规则按优先顺序进行评估。优先顺序如下: canary-by-header -> canary-by-cookie -> canary-weight
已知限制目前,每个Ingress规则最多可以应用一个金丝雀入口。
Example:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: <appName>-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "version"
nginx.ingress.kubernetes.io/canary-by-header-value: "canary"
nginx.ingress.kubernetes.io/canary-by-cookie: "canary-cookie"
nginx.ingress.kubernetes.io/canary-weight: <weight>
spec:
rules:
- host: <host>
http:
paths:
- path: /
backend:
serviceName: <appName>-canary
servicePort: 80
a
带有 “version: canary” 头的请求都被发送到 canary 版本:curl -H "version: canary" -H "Host: xxx.xx.cm" 111。111。111。11
对应的参数: nginx.ingress.kubernetes.io/canary-by-header: "version" nginx.ingress.kubernetes.io/canary-by-header-value: "canary"
不带 “version: canary” 头的请求会根据权重转发到 canary 版本,相关参数为: nginx.ingress.kubernetes.io/canary-weight: <weight>cookie 的值为 always 转发给 canary, never不转发,指定 cookie 名称的参数为 :nginx.ingress.kubernetes.io/canary-by-cookie: "canary-cookie"
curl -v -b canary-cookie=always xxx.xx.cn # 访问金丝雀版本curl -v -b canary-cookie=never xxx.xx.cn # 访问非金丝雀版本
root@dev-k8s-m1 ~]# while sleep 0.5; do curl -H “version: canary” -H “Host: dev-xx.xxx.cn” http://ip;echo; done{“code”: 100, “data”: {“version”: “old”}, “msg”: “success”}{“code”: 100, “data”: {“version”: “old”}, “msg”: “success”}{“code”: 401, “msg”: “\u4f1a\u8bdd\u8d85\u65f6”, “data”: {}}{“code”: 401, “msg”: “\u4f1a\u8bdd\u8d85\u65f6”, “data”: {}}{“code”: 100, “data”: {“version”: “old”}, “msg”: “success”}{“code”: 100, “data”: {“version”: “old”}, “msg”: “success”}{“code”: 100, “data”: {“version”: “old”}, “msg”: “success”}{“code”: 100, “data”: {“version”: “old”}, “msg”: “success”}{“code”: 100, “data”: {“version”: “old”}, “msg”: “success”}{“code”: 401, “msg”: “\u4f1a\u8bdd\u8d85\u65f6”, “data”: {}}{“code”: 100, “data”: {“version”: “old”}, “msg”: “success”}{“code”: 100, “data”: {“version”: “old”}, “msg”: “success”}{“code”: 100, “data”: {“version”: “old”}, “msg”: “success”}{“code”: 100, “data”: {“version”: “old”}, “msg”: “success”}{“code”: 100, “data”: {“version”: “old”}, “msg”: “success”}{“code”: 100, “data”: {“version”: “old”}, “msg”: “success”}{“code”: 100, “data”: {“version”: “old”}, “msg”: “success”}