首页 > 其他分享 >Ingress企业实战:金丝雀发布与蓝绿发布

Ingress企业实战:金丝雀发布与蓝绿发布

时间:2024-01-20 17:04:36浏览次数:29  
标签:Ingress 运维圈 金丝雀 蓝绿 canary 版本 demo new message

背景

现如今,越来越多的应用采用了微服务架构,这也导致了应用数量相比传统模式更多,管理更加复杂,发布更加频繁,如果直接将新版本上线发布给全部用户。一旦遇到线上事故(或BUG),对用户的影响极大,解决问题周期较长,甚至有时不得不回滚到前一版本,严重影响了用户体验。为了保证整体系统的稳定,风险降到最低,我们可以采用灰度发布与蓝绿发布等不同的发布方式。

什么是金丝雀发布

金丝雀发布,又称灰度发布,是指通过让小部份用户流量引入的新版本进行测试,如果一切顺利,则可以增加(可能逐渐增加)百分比,逐步替换旧版本。如在过程中出现任何问题,则可以中止并快速回滚到旧版本。最简单的方式是随机选择百分比请求到金丝雀版本,但在更复杂的方案下,则可以基于请求的内容、特定范围的用户或其他属性等。 金丝雀发布.png

什么是蓝绿发布

蓝绿发布,提供了一种零宕机的部署方式,是一种以可观测的方式发布应用的方式,目的减少发布过程中停止时间。在保留老版本的同时部署新版本,将两个版本同时在线,新版本和老版本相互热备,通过切换路由权重的方式(非0即100)实现应用的不同版本上线或者下线,如果有问题可以快速地回滚到老版本。这样做的好处是无需停机,并且风险较小。 蓝绿发布.png

示例应用部署

部署示例版本:

$ cat demo.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo
  labels:
    app: demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: demo
        imagePullPolicy: Always
        image: registry.cn-shanghai.aliyuncs.com/kubesre01/demo:v1
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: demo-svc
spec:
  type: ClusterIP
  selector:
    app: demo
  ports:
    - port: 8080
      targetPort: 8080
$ kubectl apply -f demo.yml
deployment.apps/demo created

部署新版本:

$ cat demo_new.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-new
  labels:
    app: demo-new
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demo-new
  template:
    metadata:
      labels:
        app: demo-new
    spec:
      containers:
      - name: demo-new
        imagePullPolicy: Always
        image: registry.cn-shanghai.aliyuncs.com/kubesre01/demo:v2
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: demo-new-svc
spec:
  type: ClusterIP
  selector:
    app: demo-new
  ports:
    - port: 8080
      targetPort: 8080

$ kubectl apply -f demo_new.yml
deployment.apps/demo_new created

创建Ingress记录:

$ cat demo-ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo
spec:
  rules:
  - host: demo.kubesre.com
    http:
      paths:
      - path: /info
        pathType: Prefix
        backend:
          service:
            name: demo-svc 
            port:
              number: 8080
  ingressClassName: nginx

$ kubectl apply -f demo-ingress.yml
ingress.networking.k8s.io/demo-ingress created

# 访问如下内容说明部署成功!
$ curl  http://demo.kubesre.com/info
{"message":"云原生运维圈!"}

到此为止,示例应用与新版本已部署完毕!

基于客户端请求头的流量切分

假设线上已运行了一套对外提供的七层demo应用,此时开发了一些新的功能,需要上线新版本demo应用,但是又不想直接替换成新版本demo应用,而是希望将请求头包含user=kubesre的客户端请求转发到新版本demo应用中,进行验证测试新版本demo应用,等测试验证通过并稳定后,可将所有流量从老版本demo应用切换到新版本demo应用中,再平滑地将老版本demo应用下线。 创建新版本Ingress:

$ cat demo-new-canary.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-new-canary
  annotations:
    # 开启Canary。
    nginx.ingress.kubernetes.io/canary: "true"
    # 请求头为user
    nginx.ingress.kubernetes.io/canary-by-header: "user"
    # 请求头user的值为kubesre时,请求才会被路由到新版本服务new-new中。
    nginx.ingress.kubernetes.io/canary-by-header-value: "kubesre"

spec:
  rules:
  - host: demo.kubesre.com
    http:
      paths:
      - path: /info
        pathType: Prefix
        backend:
          service:
            name: demo-new-svc
            port:
              number: 8080
  ingressClassName: nginx

$ kubectl apply -f demo-new-canary.yml
ingress.networking.k8s.io/demo-new-canary created

测试验证:

# 请求头为user: kubesre,访问到新的版本
$ curl -H "user: kubesre" http://demo.kubesre.com/info
{"message":"云原生运维圈!新版本"}

# 其他则访问到老的版本
$ curl  http://demo.kubesre.com/info
{"message":"云原生运维圈!"}

基于客户端来源IP的流量切分

假设线上已运行了一套对外提供的七层demo应用,此时开发了一些新的功能,需要上线新版本demo应用,又不想直接替换成新版本demo应用,而是只希望公司内部人员能访问到新版本demo应用中,进行测试验证新版本demo应用,非公司内部人员访问还是访问到老版本应用中。等公司内部人员测试验证通过并稳定后,可将所有流量从老版本demo应用切换到新版本demo应用中,再平滑地将老版本demo应用下线。 创建新版本Ingress:

$ cat demo-new-canary.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-new-canary
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "X-Forwarded-For"
    # 假设客户端来源IP为123.456.789.123
    nginx.ingress.kubernetes.io/canary-by-header-value: "123.456.789.123"
    
spec:
  rules:
  - host: demo.kubesre.com
    http:
      paths:
      - path: /info
        pathType: Prefix
        backend:
          service:
            name: demo-new-svc
            port:
              number: 8080
  ingressClassName: nginx

$ kubectl apply -f demo-new-canary.yml
ingress.networking.k8s.io/demo-new-canary created

测试验证:

# 通过请求头模拟来源IP,真实环境不需要
$ curl -H "X-Forwarded-For:123.456.789.123" http://demo.kubesre.com/info
{"message":"云原生运维圈!新版本"}

# 其他则访问到老的版本
$ curl  http://demo.kubesre.com/info
{"message":"云原生运维圈!"}

基于服务权重的流量切分

假设线上已运行了一套对外提供的七层demo应用,此时修复了一些问题,需要上线新版本demo应用,又不想直接替换成新版本demo应用,而是希望将20%的流量切换新版本。待运行一段时间稳定后,可将所有流量从老版本demo应用切换到新版本demo应用中,再平滑地将老版本demo应用下线。 创建新版本Ingress:

$ cat demo-new-canary.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-new-canary
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "X-Forwarded-For"
    # 将20%的流量转发到新版本
    nginx.ingress.kubernetes.io/canary-weight: "20"
    
spec:
  rules:
  - host: demo.kubesre.com
    http:
      paths:
      - path: /info
        pathType: Prefix
        backend:
          service:
            name: demo-new-svc
            port:
              number: 8080
  ingressClassName: nginx

$ kubectl apply -f demo-new-canary.yml
ingress.networking.k8s.io/demo-new-canary created

测试验证:

# 可以看出,有4/20的几率由新版本服务响应,符合20%服务权重的设置。
$ for i in {1..20}; do curl http://demo.kubesre.com/info; done;
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!新版本"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!新版本"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!新版本"}{
"message":"云原生运维圈!新版本"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}
{"message":"云原生运维圈!"}

注解说明

Nginx Ingress支持通过配置注解(Annotations)来实现不同场景下的发布和测试,可以满足灰度发布、蓝绿发布、A/B测试等业务场景。具体实现过程如下:为服务创建两个Ingress,一个为常规Ingress,另一个为带nginx.ingress.kubernetes.io/canary: "true"注解的Ingress,称为Canary Ingress;为Canary Ingress配置流量切分策略Annotation,两个Ingress相互配合,即可实现多种场景的发布和测试。Nginx Ingress的Annotation支持以下几种规则:

  • nginx.ingress.kubernetes.io/canary-by-header基于Header的流量切分,适用于灰度发布。如果请求头中包含指定的header名称,并且值为“always”,就将该请求转发给Canary Ingress定义的对应后端服务。如果值为“never”则不转发,可用于回滚到旧版本。如果为其他值则忽略该annotation,并通过优先级将请求流量分配到其他规则。
  • nginx.ingress.kubernetes.io/canary-by-header-value必须与canary-by-header一起使用,可自定义请求头的取值,包含但不限于“always”或“never”。当请求头的值命中指定的自定义值时,请求将会转发给Canary Ingress定义的对应后端服务,如果是其他值则忽略该annotation,并通过优先级将请求流量分配到其他规则。
  • nginx.ingress.kubernetes.io/canary-by-header-pattern与canary-by-header-value类似,唯一区别是该annotation用正则表达式匹配请求头的值,而不是某一个固定值。如果该annotation与canary-by-header-value同时存在,该annotation将被忽略。
  • nginx.ingress.kubernetes.io/canary-by-cookie基于Cookie的流量切分,适用于灰度发布。与canary-by-header类似,该annotation用于cookie,仅支持“always”和“never”,无法自定义取值。
  • nginx.ingress.kubernetes.io/canary-weight基于服务权重的流量切分,适用于蓝绿部署。表示Canary Ingress所分配流量的百分比,取值范围[0-100]。例如,设置为100,表示所有流量都将转发给Canary Ingress对应的后端服务。

以上注解规则会按优先级进行评估,优先级为:canary-by-header -> canary-by-cookie -> canary-weight。

总结

本文介绍了金丝雀发布与蓝绿发布,并以企业案例的方式讲解了不同的场景使用什么样的发布方式,下一章将介绍Ingress 证书管理与双向认证,请敬请期待!

标签:Ingress,运维圈,金丝雀,蓝绿,canary,版本,demo,new,message
From: https://blog.51cto.com/u_14136800/9345765

相关文章

  • argo-rollout使用--金丝雀结合ingress-nginx
    1.金丝雀发布流程,安装比例发布,又名灰度发布举例:共10pod第一批发布30%V1:10个PodV2:3个Pod第二批发布60%V1:10个PodV2:6个Pod第三批发布100%V1:10个PodV2:10个Pod第四批发布V2:10个Pod(active)V1:0个Pod 2.资源文件准备文......
  • 蓝绿发布、滚动发布、灰度发布,有什么区别 ?
    蓝绿发布   蓝绿部署中,一共有两套系统:一套是正在提供服务系统(也就是上面说的旧版),标记为“绿色”;另一套是准备发布的系统,标记为“蓝色”。两套系统都是功能完善的,并且正在运行的系统,只是系统版本和对外服务情况不同。正在对外提供服务的老系统是绿色系统,新部署的系统是蓝色......
  • KubeSphere实现金丝雀发布(Canary Release)
    0前言KubeSphere基于[Istio]向用户提供金丝雀发布功能,即:引入服务的新版本,并向其发送一小部分流量来进行测试同时,旧版本负责处理其余的流量如果一切顺利,就可逐渐增加向新版本发送的流量,同时逐步停用旧版本如出现任何问题,可用KubeSphere更改流量比例来回滚至先前版本该......
  • KubeSphere实现金丝雀发布(Canary Release)
    0前言KubeSphere基于[Istio]向用户提供金丝雀发布功能,即:引入服务的新版本,并向其发送一小部分流量来进行测试同时,旧版本负责处理其余的流量如果一切顺利,就可逐渐增加向新版本发送的流量,同时逐步停用旧版本如出现任何问题,可用KubeSphere更改流量比例来回滚至先前版本......
  • Argo-rollout使用--蓝绿和金丝雀发布
    1.安装argo-rolloutkubectlcreatenamespaceargo-rolloutskubectlapply-nargo-rollouts-fhttps://github.com/argoproj/argo-rollouts/releases/download/v1.5.0/install.yaml官网:https://argoproj.github.io/argo-rollouts/ 2.蓝绿部署部署applicationapiVersion......
  • 在Kubernetes中优雅地导出和清理Ingress资源
    引言Kubernetes的Ingress资源是定义外部访问集群服务的规则。随着微服务架构和容器化技术的普及,Ingress作为路由流量的关键组件变得愈发重要。当我们需要在环境之间迁移Ingress资源或者备份当前的配置时,就会用到导出功能。然而,直接使用kubectl导出可能会包括一些我们不需要的元数......
  • 当创建一个ingress后,kubernetes会发什么?
    本文分享自华为云社区《当创建一个ingress后,kubernetes会发什么?》,作者:可以交个朋友。一、Ingress概述Ingress是一组路由转发规则合集,将集群内部服务通过7层协议暴露给用户,是一种k8s默认的资源。Ingress资源对象用于定义来自外网的HTTP和HTTPS规则,流量路由由Ingress资源上定义的规则......
  • 使用springcloud 实现 蓝绿发布、灰度发布(金丝雀发布)
    介绍工作中经常要涉及到功能发布,这个时候也经常是业务系统最有可能遇到问题的时候,需要要尽量减少发布引起的风险。比如在系统负载比较小的时候使用。还有蓝绿发布、灰度发布等等,今天介绍一下这几种常见的发布,并使用springcloud实现。1.传统发布方式一个系统最初的时候,使用量小,用户......
  • 跨集群流量调度实现 Kubernetes 集群金丝雀升级
    有了多集群服务和跨集群的流量调度之后,使用Kubernetes的方式会发生很大的变化。流量的管理不再限制单一集群内,而是横向跨越了多个集群。最重要的是这一切“静悄悄地”发生,对应用来说毫无感知。就拿Kubernetes版本升级来说吧。记得曾经经历过集群的原地升级:团队的几个人经过多次......
  • Kubernetes 网络之 Ingress 介绍
    一、ingress在Kubernetes集群中,Ingress作为集群内服务对外暴露的访问接入点,几乎承载着集群内服务访问的所有流量。Ingress是Kubernetes中的一个资源对象,用来管理集群外部访问集群内部服务的方式。可以通过Ingress资源来配置不同的转发规则,从而实现根据不同的规则设置访问集群内不同......