灰度的方式有很多中,这里介绍在kubernetes中ingress根据head头做灰度,灰度的目的是为了在上线之前指定一部分用户可以访问,针对整个业务流程访问都没有问题之后在发布到线上,如果在灰度环境中出现bug也不会影响到所有用户使用,这种发布方式是很多互联网企业比较在意的方式。
一、介绍
类型 | 解释 | |
---|---|---|
nginx.ingress.kubernetes.io/canary | "true","false" | 开启灰度发布功能,如果没有开启此属性,则如下属性不生效。 |
nginx.ingress.kubernetes.io/canary-by-header | string | 基于 Request Header 的流量切分,适用于灰度发布以及 A/B 测试。当 Request Header 设置为 always时,请求将会被一直发送到 Canary 版本;当 Request Header 设置为 never时,请求不会被发送到 Canary 入口;对于任何其他 Header 值,将忽略 Header,并通过优先级将请求与其他金丝雀规则进行优先级的比较。 |
nginx.ingress.kubernetes.io/canary-by-header-value | string | 要匹配的 Request Header 的值,用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务。当 Request Header 设置为此值时,它将被路由到 Canary 入口。该规则允许用户自定义 Request Header 的值,必须与上一个 annotation (即canary-by-header)一起使用。 |
nginx.ingress.kubernetes.io/canary-by-header-pattern | string | 正则表达式匹配的 Request Header 的值,用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务。当 Request Header 设置为此值时,它将被路由到 Canary 入口。该规则允许用户自定义 Request Header 的值,必须与上一个 annotation (即canary-by-header)一起使用,如果已经使用canary-by-header-value,那么此属性将被忽略。 |
nginx.ingress.kubernetes.io/canary-by-cookie | string | 基于 Cookie 的流量切分,适用于灰度发布与 A/B 测试。用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务的cookie。当 cookie 值设置为 always时,它将被路由到 Canary 入口;当 cookie 值设置为 never时,请求不会被发送到 Canary 入口;对于任何其他值,将忽略 cookie 并将请求与其他金丝雀规则进行优先级的比较。 |
nginx.ingress.kubernetes.io/canary-weight | string |
二、环境
灰度的场景是通过用户的head头判断用户的请求转发到不同的服务上,这里使用域名demo.wulaoer.org,然后创建了两个服务分别是nginx-v1和nginx-v2,我这里实现的是符合要求的请求到nginx-v2上,不符合的请求到nginx-v1,下面是我的服务。
[wolf@wulaoer.org🔥🔥🔥🔥 test]# kubectl get service -n ops-team NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-v1 ClusterIP 172.16.80.63 <none> 80/TCP 99m nginx-v2 ClusterIP 172.16.214.16 <none> 80/TCP 99m
服务已经创建好了,下面给服务做域名解析,我这使用同一个域名解析到两个不同的服务上,解析后测试一下是否能给访问正常。
[wolf@wulaoer.org🔥🔥🔥🔥 test]# kubectl edit ingress -n ops-team ops-nginx-v1 kind: Ingress apiVersion: networking.k8s.io/v1 metadata: name: ops-nginx-v1 namespace: ops-tem annotations: kubesphere.io/creator: admin spec: rules: - host: demo.wulaoer.org http: paths: - path: / pathType: ImplementationSpecific backend: service: name: nginx-v1 port: number: 80 [wolf@wulaoer.org🔥🔥🔥🔥 test]# kubectl edit ingress -n ops-team ops-nginx-v2 kind: Ingress apiVersion: networking.k8s.io/v1 metadata: name: ops-nginx-v2 namespace: ops-tem annotations: kubesphere.io/creator: admin nginx.ingress.kubernetes.io/service-match: 'nginx-v2: header("far", "bor")' spec: rules: - host: demo.wulaoer.org http: paths: - path: / pathType: ImplementationSpecific backend: service: name: nginx-v2 port: number: 80 [wolf@wulaoer.org🔥🔥🔥🔥 test]# kubectl apply -f ops-team ops-nginx-v1.yaml [wolf@wulaoer.org🔥🔥🔥🔥 test]# kubectl apply -f ops-team ops-nginx-v2.yaml
正常情况下我们请求域名的时候应该返回两个服务的返回值,但是这里没有,默认访问nginx- v1的值,如果想两者都有在阿里云的ack里需要加[nginx.ingress.kubernetes.io/service-weight: 'nginx-v1: 100, nginx-v2: 100']就会在两个服务之间来回切换。
[wolf@wulaoer.org🔥🔥🔥🔥 ~]# for ((i=0;i<100;i ++));do curl http://demo.wulaoer.org;done nginx-v1 nginx-v1 nginx-v1 nginx-v1 nginx-v2
三、配置灰度服务
灰度服务要求符合要求的header才可以请求到灰度服务,不符合的header不允许请求灰度服务,这里给灰度的header增加far:bor标签,这样header头为far:bor的服务都请求到nginx-v2服务上了。
[wolf@wulaoer.org🔥🔥🔥🔥 test]# kubectl edit ingress -n ops-team ops-nginx-v2 .......................................... metadata: annotations: ............................ nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-by-header: far nginx.ingress.kubernetes.io/canary-by-header-value: bor creationTimestamp: "2022-01-17T03:22:49Z" ............................................
已修改,看下面的测试结果
[wolf@wulaoer.org🔥🔥🔥🔥 ~]# curl -H "far:bor" http://demo.wulaoer.org nginx-v2 [wolf@wulaoer.org🔥🔥🔥🔥 ~]# curl http://demo.wulaoer.org nginx-v1
实验结束,这里说一个问题,因为我这是在测试环境做的,测试环境是自建的kubernetes服务,生产环境使用的阿里云的ack,两者有明显的区别,首先第一个,阿里云的直接使用两个ingress都不会创建成功,阿里云环境的灰度只需要创建一个ingress,但是在灰度时不能使用权重。
[wolf@wulaoer.org🔥🔥🔥🔥 test]# kubectl edit ingress -n ops-team ops-nginx-v2 .......................................... kind: Ingress apiVersion: networking.k8s.io/v1 metadata: name: ops-nginx-v2 namespace: ops-tem annotations: kubesphere.io/creator: admin nginx.ingress.kubernetes.io/service-match: 'nginx-v2: header("far", "bor")' spec: tls: - hosts: - demo.reach.store secretName: reach-ssl rules: - host: demo.wulaoer.org http: paths: - path: / pathType: ImplementationSpecific backend: service: name: nginx-v1 port: number: 80 - path: / pathType: ImplementationSpecific backend: service: name: nginx-v2 port: number: 80
不管是阿里云还是自建的,在灰度和正式环境时,第一个创建的ingress都会被认为是正式的,默认请求的服务,除非特别配置才会请求到第二个服务上,所以这个在创建时需要注意。
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助
赏