Rancher-ingress实现蓝绿发布

软件版本
rancher2.5.11-ent
k8s1.20.12

概述

使用Nginx Ingress实现灰度发布适用场景主要取决于业务流量切分的策略,目前Nginx Ingress支持基于Header、Cookie和服务权重三种流量切分的策略,基于这三种策略可实现以下两种发布场景:
• 场景一:切分部分用户流量到新版本
原应用:Service A
升级后的应用:Service A’(Header中包含foo=bar或者Cookie中包含foo=bar)
假设线上已运行了一套对外提供七层服务的Service A,此时需要发布上线一个新特性的版本Service A’,但又不想直接替换原有的Service A,而是期望将Header中包含foo=bar,或者Cookie中包含foo=bar的用户请求,转发到新版本Service A’中。待运行一段时间业务稳定后,再逐步升级到新版本,平滑下线旧版本。示意图如下:

• 场景二:切分一定比例的流量到新版本
假设线上已运行了一套对外提供七层服务的Service B,此时修复了一些问题,需要发布上线一个新的版本Service B’,但又不想直接替换原有的Service B,而是期望将20%的流量切换到新版本Service B’中。待运行一段时间业务稳定后,再将所有的流量从旧版本切换到新版本中,平滑下线旧版本。

注解说明

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被标记为Canary Ingress时,除了nginx.ingress.kubernetes.io/load-balance和nginx.ingress.kubernetes.io/upstream-hash-by外,所有其他非Canary的注解都将被忽略。

前提条件

使用Nginx Ingress实现灰度发布的集群,需安装nginx-ingress插件作为Ingress Controller,并且对外暴露统一的流量入口。Rancher企业版已集成。

资源创建方式

部署两个版本的服务

old-nginx为老版本
new-nginx为新版本,用于对old-nginx做升级测试

创建第一个版本的nginx:old-nginx

新建配置映射configmap,用于nginx的主页显示

选择 资源 菜单中的 配置映射 菜单项

指定配置映射的名称与命名空间
指定配置映射的键值,键为文件名,值为显示的内容,此处为old-nginx

Configmap对应的yaml

apiVersion: v1
data:
  index.html: old-nginx
kind: ConfigMap
metadata:
  annotations:
    field.cattle.io/creatorId: user-k2shc
  labels:
    cattle.io/creator: norman
  name: old-nginx

新建工作负载部署


工作负载的详细信息:
名称:old-nginx
镜像:nginx:latest
端口:80
副本数:1
发布方式:Nodeport
指定命名空间

并且指定上一步中创建的配置映射,挂载到/usr/share/nginx/html/

指定挂载模式644
选择指定的键
键的名称为:index.html
路径为:index.html
容器路径:/usr/share/nginx/html/

对工作负载添加标签(重要)
用于service与pod的关联筛选
标签为app=old-nginx
注意:生产环境时注意标签不可以与其他工作负载重复


增加cpu与内存的配额限制

部署对应的yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
    field.cattle.io/creatorId: user-k2shc
  labels:
    cattle.io/creator: norman
    workload.user.cattle.io/workloadselector: deployment-test-old-nginx
  name: old-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      workload.user.cattle.io/workloadselector: deployment-test-old-nginx
  template:
    metadata:
      labels:
        app: old-nginx
        workload.user.cattle.io/workloadselector: deployment-test-old-nginx
    spec:
      containers:
      - image: nginx:latest
        imagePullPolicy: Always
        name: old-nginx
        ports:
        - containerPort: 80
          name: 80tcp01
          protocol: TCP
        resources:
          limits:
            cpu: 100m
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        stdin: true
        tty: true
        volumeMounts:
        - mountPath: /usr/share/nginx/html/
          name: vol2
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
      volumes:
      - configMap:
          defaultMode: 420
          items:
          - key: index.html
            path: index.html
          name: old-nginx
          optional: false
        name: vol2

新建svc
用于外部ingress访问的对应service

选择 资源 菜单中的工作负载菜单项,切换到服务发现

添加service,指定名称、命名空间
解析到选择pod
指定标签 app=old-nginx
注意:标签必须在工作负载中指定好并且不能与其他的工作负载重复

类型为:clusterIP或headless
端口映射指定为80

Svc对应的yaml

apiVersion: v1
kind: Service
metadata:
  annotations:
    field.cattle.io/creatorId: user-k2shc
    field.cattle.io/ipAddresses: "null"
    field.cattle.io/targetDnsRecordIds: "null"
    field.cattle.io/targetWorkloadIds: "null"
  labels:
    cattle.io/creator: norman
  name: old-nginx-svc
spec:
  clusterIP: 10.43.219.43
  clusterIPs:
  - 10.43.219.43
  ports:
  - name: 80tcp2
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: old-nginx
  sessionAffinity: None
  type: ClusterIP

创建第二个版本的nginx:new-nginx

新建配置映射configmap,用于nginx的主页显示

选择 资源 菜单中的 配置映射 菜单项

指定配置映射的名称与命名空间
指定配置映射的键值,键为文件名,值为显示的内容,此处为new-nginx

Configmap对应的yaml

apiVersion: v1
data:
  index.html: new-nginx
kind: ConfigMap
metadata:
  annotations:
    field.cattle.io/creatorId: user-k2shc
  labels:
    cattle.io/creator: norman
  name: new-nginx

新建工作负载部署


工作负载的详细信息:
名称:new-nginx
镜像:nginx:latest
端口:80
副本数:1
发布方式:Nodeport
指定命名空间

并且指定上一步中创建的配置映射,挂载到/usr/share/nginx/html/

指定挂载模式644
选择指定的键
键的名称为:index.html
路径为:index.html
容器路径:/usr/share/nginx/html/

对工作负载添加标签(重要)
用于service与pod的关联筛选
标签为app=new-nginx
注意:生产环境时注意标签不可以与其他工作负载重复

增加cpu与内存的配额限制

部署对应的yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
    field.cattle.io/creatorId: user-k2shc
  labels:
    cattle.io/creator: norman
    workload.user.cattle.io/workloadselector: deployment-test-new-nginx
  name: new-nginx
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      workload.user.cattle.io/workloadselector: deployment-test-new-nginx
  template:
    metadata:
      labels:
        app: new-nginx
        workload.user.cattle.io/workloadselector: deployment-test-new-nginx
    spec:
      containers:
      - image: nginx:latest
        imagePullPolicy: Always
        name: new-nginx
        ports:
        - containerPort: 80
          name: 80tcp01
          protocol: TCP
        resources:
          limits:
            cpu: 100m
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        stdin: true
        tty: true
        volumeMounts:
        - mountPath: /usr/share/nginx/html/
          name: vol1
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
      volumes:
      - configMap:
          defaultMode: 420
          items:
          - key: index.html
            path: index.html
          name: new-nginx
          optional: false
        name: vol1

新建svc
用于外部ingress访问的对应service

选择 资源 菜单中的工作负载菜单项,切换到服务发现

添加service,指定名称、命名空间
解析到选择pod
指定标签 app=new-nginx
注意:标签必须在工作负载中指定好并且不能与其他的工作负载重复

类型为:clusterIP或headless
端口映射指定为80

Svc对应的yaml

apiVersion: v1
kind: Service
metadata:
  annotations:
    field.cattle.io/creatorId: user-k2shc
    field.cattle.io/ipAddresses: "null"
    field.cattle.io/targetDnsRecordIds: "null"
    field.cattle.io/targetWorkloadIds: "null"
  labels:
    cattle.io/creator: norman
  name: new-nginx-svc
spec:
  clusterIP: 10.43.55.151
  clusterIPs:
  - 10.43.55.151
  ports:
  - name: 80tcp2
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: new-nginx
  sessionAffinity: None
  type: ClusterIP

使用nodeport方式访问测试

切换到工作负载查看nodeport端口

打开浏览器输入edge节点的IP与old-nginx nodeport端口验证业务的可用

打开浏览器输入edge节点的IP与new-nginx nodeport端口验证业务的可用

灰度发布新版本服务

创建Ingress,对外暴露服务,指向old版本的服务

新建ingress
用于外部用户的http访问

切换到资源菜单,选择工作负载,切换到负载均衡选项

添加规则
名称:old-nginx
选中自定义域名,并指定访问域名,域名为dns能解析的A记录
选择服务,访问路径为/, 服务名称指定为old-nginx-svc,端口为80

注释为:

kubernetes.io/ingress.class=nginx
    kubernetes.io/elb.port='80'

Ingress对应的yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    field.cattle.io/creatorId: user-k2shc
    kubernetes.io/elb.port: "80"
    kubernetes.io/ingress.class: nginx
  labels:
    cattle.io/creator: norman
  name: old-nginx
spec:
  rules:
  - host: www.demo-test.com
    http:
      paths:
      - backend:
          serviceName: old-nginx-svc
          servicePort: 80
        path: /
        pathType: ImplementationSpecific

命令行验证old 版本的ingress可用性

命令:curl -H “Host: <ingress对应的域名>” http://< Ingress对外暴露的IP>

基于Header的流量切分 (注意: Canary Ingress的优先级)

以下示例仅模拟灰度新版本给北京和广州地域的用户,Header中包含Region且值为bj或gz的请求才能转发到新版本服务。
新建ingress
用于外部用户的http访问

切换到资源菜单,选择工作负载,切换到负载均衡选项

添加规则
名称:new-nginx-header
选中自定义域名,并指定访问域名,域名为dns能解析的A记录
选择服务,访问路径为/, 服务名称指定为new-nginx-svc,端口为80

注释为:

kubernetes.io/ingress.class=nginx
    kubernetes.io/elb.port='80'
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "Region"
nginx.ingress.kubernetes.io/canary-by-header-pattern: "bj|gz"

Ingress对应的yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    field.cattle.io/creatorId: user-k2shc
    kubernetes.io/elb.port: "80"
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: Region
    nginx.ingress.kubernetes.io/canary-by-header-pattern: bj|gz
  labels:
    cattle.io/creator: norman
  name: new-nginx-header
spec:
  rules:
  - host: www.demo-test.com
    http:
      paths:
      - backend:
          serviceName: new-nginx-svc
          servicePort: 80
        path: /
        pathType: ImplementationSpecific
验证访问测试

命令:curl -H “Host: <ingress对应的域名>” -H “Region: bj/gz” http:// < Ingress对外暴露的IP>


基于Cookie的流量切分 (注意:Canary Ingress的优先级)

以下示例仅Cookie中包含user_from_bj的请求才能转发到新版本服务,模拟灰度新版本给北京地域的用户。
删除原有的ingress

新建ingress
用于外部用户的http访问

切换到资源菜单,选择工作负载,切换到负载均衡选项

添加规则
名称:new-nginx-cookie
选中自定义域名,并指定访问域名,域名为dns能解析的A记录
选择服务,访问路径为/, 服务名称指定为new-nginx-svc,端口为80

注释为:

kubernetes.io/ingress.class=nginx
kubernetes.io/elb.port='80'
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-cookie: user_from_bj

Uploading file..._2mpfir28z

Ingress对应的yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    field.cattle.io/creatorId: user-k2shc
    kubernetes.io/elb.port: "80"
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-cookie: user_from_bj
  labels:
    cattle.io/creator: norman
  name: new-nginx-cookie
spec:
  rules:
  - host: www.demo-test.com
    http:
      paths:
      - backend:
          serviceName: new-nginx-svc
          servicePort: 80
        path: /
        pathType: ImplementationSpecific
验证访问测试

命令:curl -H “Host: <ingress对应的域名>” --cookie “user_from_bj=always” http:// < Ingress对外暴露的IP>

基于服务权重的流量切分 (注意:Canary Ingress的优先级)

仅允许20%的流量被转发到新版本服务中,实现灰度发布。

删除原有的ingress

新建ingress
用于外部用户的http访问

切换到资源菜单,选择工作负载,切换到负载均衡选项

添加规则
名称:new-nginx-weight20
选中自定义域名,并指定访问域名,域名为dns能解析的A记录
选择服务,访问路径为/, 服务名称指定为new-nginx-svc,端口为80

注释为:

kubernetes.io/ingress.class=nginx
kubernetes.io/elb.port='80'
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "20"

Ingress对应的yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    field.cattle.io/creatorId: user-k2shc
    kubernetes.io/elb.port: "80"
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "20"
  labels:
    cattle.io/creator: norman
  name: new-nginx-weight20
spec:
  rules:
  - host: www.demo-test.com
    http:
      paths:
      - backend:
          serviceName: new-nginx-svc
          servicePort: 80
        path: /
        pathType: ImplementationSpecific
验证访问测试

命令:for i in {1…20}; do curl -H “Host: <ingress对应的域名>” http:// < Ingress对外暴露的IP>; echo; done;

允许所有的流量被转发到新版本服务中,实现蓝绿发布

删除原有的ingress

新建ingress
用于外部用户的http访问

切换到资源菜单,选择工作负载,切换到负载均衡选项
添加规则
名称:new-nginx-weight100
选中自定义域名,并指定访问域名,域名为dns能解析的A记录
选择服务,访问路径为/, 服务名称指定为new-nginx-svc,端口为80

注释为:

kubernetes.io/ingress.class=nginx
kubernetes.io/elb.port='80'
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "100"

Ingress对应的yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    field.cattle.io/creatorId: user-k2shc
    kubernetes.io/elb.port: "80"
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "100"
  labels:
    cattle.io/creator: norman
  name: new-nginx-weight100
spec:
  rules:
  - host: www.demo-test.com
    http:
      paths:
      - backend:
          serviceName: new-nginx-svc
          servicePort: 80
        path: /
        pathType: ImplementationSpecific
验证访问测试

命令:for i in {1…20}; do curl -H “Host: <ingress对应的域名>” http:// < Ingress对外暴露的IP>;echo ; done;

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Rancher是一个开源的容器管理平台,它提供了丰富的功能来简化和管理容器的部署和管理过程。其中一个重要的功能是警报驱动程序(Alerting Drivers),它可以帮助用户及时了解集群和容器的健康状况,并及时采取相应的措施。 Rancher支持多种警报驱动程序,其中之一是sachet配置。Sachet是一个基于Web的错误日志和异常信息聚合工具,它可以将来自不同源的警报信息集中展示,帮助用户更好地监控和分析系统中的问题。 要使用rancher-alerting-drivers-sachet配置,首先需要在Rancher中启用警报驱动程序插件。然后,您需要从Rancher的应用商店中安装rancher-alerting-drivers-sachet插件。安装完成后,您可以在Rancher的Alerting配置页面中配置Sachet。 在Sachet的配置中,您需要提供Sachet的API地址、API密钥等信息。这些信息将用于与Sachet服务器建立连接,将Rancher中的警报数据传输到Sachet中。您还可以选择配置警报的级别、触发条件等。 一旦配置完成,当Rancher中的警报触发时,警报信息将被发送到Sachet中,并在Sachet的控制台中显示出来。您可以通过Sachet的界面查看警报信息、分析问题,并采取相应的措施。 总的来说,rancher-alerting-drivers-sachet配置是在Rancher中启用和配置Sachet作为警报驱动程序的一种方式。它可以帮助用户更好地监控和管理容器集群,及时发现和解决问题,提高系统的稳定性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值