【Kubernetes运维篇】ingress-nginx实现业务灰度发布详解

这篇具有很好参考价值的文章主要介绍了【Kubernetes运维篇】ingress-nginx实现业务灰度发布详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、理论:实现灰度发布的几种场景

1、场景一:将新版本灰度给部分用户

假设线上运行了一套对外提供 7 层服务的 Service A 服务,后来开发了个新版本 Service AA需要上线,但不想直接替换掉原来的 Service A,希望先灰度一小部分用户,等运行一段时间足够稳定了再逐渐全量上线新版本,最后平滑下线旧版本。

这个时候就可以利用 Nginx Ingress 基于 Header 或 Cookie 进行流量切分的策略来发布,业务使用 Header 或 Cookie 来标识不同类型的用户,我们通过配置 Ingress 来实现让带有指定 Header 或 Cookie 的请求被转发到新版本,其它的仍然转发到旧版本,从而实现将新版本灰度给部分用户。

【Kubernetes运维篇】ingress-nginx实现业务灰度发布详解,# 3-Kubernetes容器编排,运维,kubernetes,nginx,ingress,ingress灰度发布,ingress-nginx

2、场景二:按照比例流程给新版本

假设线上运行了一套对外提供 7 层服务的 Service B 服务,后来修复了一些问题,需要灰度上线一个新版本 Service BB,但又不想直接替换掉原来的 Service B而是让先切 10% 的流量到新版本。

等观察一段时间稳定后再逐渐加大新版本的流量比例直至完全替换旧版本,最后再滑下线旧版本,从而实现切一定比例的流量给新版本。

【Kubernetes运维篇】ingress-nginx实现业务灰度发布详解,# 3-Kubernetes容器编排,运维,kubernetes,nginx,ingress,ingress灰度发布,ingress-nginx

3、实现灰度发布字段解释

Ingress-Nginx是一个K8S ingress工具,支持配置Ingress Annotations来实现不同场景下的灰度发布和测试。 Nginx Annotations 支持以下几种Canary规则:

假设我们现在部署了两个版本的服务,老版本和canary版本

  • nginx.ingress.kubernetes.io/canary-by-header:基于Request Header的流量切分,适用于灰度发布以及 A/B 测试。当Request Header 设置为 always时,请求将会被一直发送到 Canary 版本;当 Request Header 设置为 never时,请求不会被发送到 Canary 入口。

  • nginx.ingress.kubernetes.io/canary-by-header-value:要匹配的 Request Header 的值,用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务。当 Request Header 设置为此值时,它将被路由到 Canary 入口。

  • nginx.ingress.kubernetes.io/canary-weight:基于服务权重的流量切分,适用于蓝绿部署,权重范围 0 - 100 按百分比将请求路由到 Canary Ingress 中指定的服务。权重为 0 意味着该金丝雀规则不会向 Canary 入口的服务发送任何请求。权重为60意味着60%流量转到canary。权重为 100 意味着所有请求都将被发送到 Canary 入口。

  • nginx.ingress.kubernetes.io/canary-by-cookie:基于 Cookie 的流量切分,适用于灰度发布与 A/B 测试。用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务的cookie。当 cookie 值设置为 always时,它将被路由到 Canary 入口;当 cookie 值设置为 never时,请求不会被发送到 Canary 入口。

二、实践:

1、实验前提环境

1、增加V1环境:

cat v1.yaml 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
      version: v1
  template:
    metadata:
      labels:
        app: nginx
        version: v1
    spec:
      containers:
      - name: nginx
        image: "openresty/openresty:centos"
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          protocol: TCP
          containerPort: 80
        volumeMounts:    # 挂载卷
        - mountPath: /usr/local/openresty/nginx/conf/nginx.conf
          name: config
          subPath: nginx.conf
      volumes:          # 定义卷,引用configMap
      - name: config
        configMap:
          name: nginx-v1
---
apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    app: nginx
    version: v1
  name: nginx-v1
data:
  nginx.conf: |-
    worker_processes  1;
    events {
        accept_mutex on;
        multi_accept on;
        use epoll;
        worker_connections  1024;
    }
    http {
        ignore_invalid_headers off;
        server {
            listen 80;
            location / {
                access_by_lua '
                    local header_str = ngx.say("nginx-v1")
                ';
            }
        }
    }
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-v1
spec:
  type: ClusterIP
  ports:
  - port: 80
    protocol: TCP
    name: http
  selector:
    app: nginx
    version: v1

2、增加V2环境:

cat v2.yaml 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
      version: v2
  template:
    metadata:
      labels:
        app: nginx
        version: v2
    spec:
      containers:
      - name: nginx
        image: "openresty/openresty:centos"
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          protocol: TCP
          containerPort: 80
        volumeMounts:
        - mountPath: /usr/local/openresty/nginx/conf/nginx.conf
          name: config
          subPath: nginx.conf
      volumes:
      - name: config
        configMap:
          name: nginx-v2
---
apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    app: nginx
    version: v2
  name: nginx-v2
data:
  nginx.conf: |-
    worker_processes  1;
    events {
        accept_mutex on;
        multi_accept on;
        use epoll;
        worker_connections  1024;
    }
    http {
        ignore_invalid_headers off;
        server {
            listen 80;
            location / {
                access_by_lua '
                    local header_str = ngx.say("nginx-v2")
                ';
            }
        }
    }
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-v2
spec:
  type: ClusterIP
  ports:
  - port: 80
    protocol: TCP
    name: http
  selector:
    app: nginx
    version: v2

3、执行YAML文件

kubectl apply -f v1.yaml 
kubectl apply -f v2.yaml 

4、验证Pod是启动

kubectl get pods -o wide

【Kubernetes运维篇】ingress-nginx实现业务灰度发布详解,# 3-Kubernetes容器编排,运维,kubernetes,nginx,ingress,ingress灰度发布,ingress-nginx

5、验证,请求Pod内容

curl http://10.244.247.2
curl http://10.244.84.134

【Kubernetes运维篇】ingress-nginx实现业务灰度发布详解,# 3-Kubernetes容器编排,运维,kubernetes,nginx,ingress,ingress灰度发布,ingress-nginx

如上图,请求不同版本的环境,返回不同版本号,表示无误。

2、基于Request Header(请求头)进行流量分割

1、创建v1版本的ingress规则

cat v1-ingress.yaml 
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-v1
spec:
  ingressClassName: nginx
  rules:
  - host: qinzt.ingress.com
    http:
      paths:
      - path: /  #配置访问路径,如果通过url进行转发,需要修改;空默认为访问的路径为"/"
        pathType:  Prefix
        backend:  #配置后端服务
         service:
           name: nginx-v1
           port:
            number: 80

执行YAML文件:

kubectl apply -f v1-ingress.yaml

访问验证一下:16.32.15.201:30080是我ingress-nginx访问地址

curl -H "Host: qinzt.ingress.com" http://16.32.15.201:30080
nginx-v1

2、创建ingress规则,基于Request Header进行流量分割

cat v2-request.yaml 
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "Region" #基于Request Header的流量切分
    nginx.ingress.kubernetes.io/canary-by-header-pattern: "cd|sz" #Header信息中带有 Region=cd,Region=sz的转发到此ingress
  name: nginx-request-v2
spec:
  ingressClassName: nginx
  rules:
  - host: qinzt.ingress.com
    http:
      paths:
      - path: /  #配置访问路径,如果通过url进行转发,需要修改;空默认为访问的路径为"/"
        pathType:  Prefix
        backend:  #配置后端服务
         service:
           name: nginx-v2
           port:
            number: 80

执行YAML文件:

kubectl apply -f v2-request.yaml

访问验证一下:16.32.15.201:30080是我ingress-nginx访问地址

curl -H "Host: qinzt.ingress.com" -H "Region: cd" http://16.32.15.201:30080
curl -H "Host: qinzt.ingress.com" -H "Region: sz" http://16.32.15.201:30080

【Kubernetes运维篇】ingress-nginx实现业务灰度发布详解,# 3-Kubernetes容器编排,运维,kubernetes,nginx,ingress,ingress灰度发布,ingress-nginx

OK,可以看到上图,携带Region: cdRegion: sz请求头消息,会转发到V2环境。

3、基于Cookie进行流量切分

与前面 Header 类似,不过使用 Cookie 就无法自定义 value 了,这里以模拟灰度成都地域用户为例,仅将带有名为 user_from_cd 的 cookie 的请求转发给当前V2环境 。

1、先删除前面基于 Header 的流量切分的 Ingress

kubectl delete -f v2-request.yaml

2、创建基于cookie 转发的ingress规则

cat v2-cookie.yaml 
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-cookie: "user_from_cd" # 匹配cookie携带user_from_cd,使用此ingress规则
  name: nginx-cookie-v2
spec:
  ingressClassName: nginx
  rules:
  - host: qinzt.ingress.com
    http:
      paths:
      - path: /  #配置访问路径,如果通过url进行转发,需要修改;空默认为访问的路径为"/"
        pathType:  Prefix
        backend:  #配置后端服务
         service:
           name: nginx-v2
           port:
            number: 80

执行YAML文件

kubectl apply -f v2-cookie.yaml 

3、测试验证,http://16.32.15.201:30080是我ingress nginx地址

curl -s -H "Host: qinzt.ingress.com" --cookie "user_from_cd=always" http://16.32.15.201:30080
nginx-v2

curl -s -H "Host: qinzt.ingress.com" --cookie "user_from_bj=always" http://16.32.15.201:30080
nginx-v1

可以看到只有cookie=user_from_cd的才会转发到V2的ingress

4、基于服务权重进行流量切分

基于服务权重的直接定义需要导入的流量比例,这里以导入 10% 流量到 v2 环境版本为。

1、删除上面基于cookie的ingress规则

kubectl delete -f v2-cookie.yaml

2、创建基于权重流量分配的ingress规则

cat v2-weight.yaml 
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"
  name: nginx-weight-v2
spec:
  ingressClassName: nginx
  rules:
  - host: qinzt.ingress.com
    http:
      paths:
      - path: /  #配置访问路径,如果通过url进行转发,需要修改;空默认为访问的路径为"/"
        pathType:  Prefix
        backend:  #配置后端服务
         service:
           name: nginx-v2
           port:
            number: 80

执行YAML文件:

kubectl apply -f v2-weight.yaml

3、测试验证

for i in {1..10}; do curl -H "Host: qinzt.ingress.com" http://16.32.15.201:30080; done;

【Kubernetes运维篇】ingress-nginx实现业务灰度发布详解,# 3-Kubernetes容器编排,运维,kubernetes,nginx,ingress,ingress灰度发布,ingress-nginx

OK,如上图大约10%的记录会请求到V2环境上面文章来源地址https://www.toymoban.com/news/detail-605998.html

到了这里,关于【Kubernetes运维篇】ingress-nginx实现业务灰度发布详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 记安装ingress-nginx遇到的一些坑

    环境: Linux:CentOS Linux release 7.9.2009 (Core) Kubernetes:v1.23.5 Dokcer:20.10.14 一、安装ingress-nginx 二、修改deploy.yaml文件 1、注释掉external Traffic Policy:Local 2、因默认镜像源国内无法访问 ,修改为dockerhub上的镜像源        修改controller/deploy的image:

    2023年04月09日
    浏览(23)
  • k8s helm ingress-nginx Error: template: ingress-nginx/templates/controller-role “update-status“

    k8s,使用helm包管理器安装ingress-nginx时,安装文件出错 helm 版本:Version:“v3.2.3” k8s 版本:Kubernetes v1.23.6 ingress-nginx chart version:4.9.0 app version:1.9.5 前面都按网上的教程做,没有什么大问题 最后一步执行安装命令 命令执行失败,报错 问题可能出现在对.Values.controller.extraArg

    2024年03月20日
    浏览(106)
  • K8s的ingress-nginx配置https

    在另一台机器上配置hosts解析www.yaoyao.com,然后访问 curl --cacert tls.crt https://www.yaoyao.com:10443 这里的10443端口是ingress-nginx-controller服务暴露的nodeport端口

    2024年02月07日
    浏览(28)
  • K8S(1.28)--部署ingress-nginx(1.9.1)

    原文网址:K8S(1.28)--部署ingress-nginx(1.9.1)-CSDN博客 本文介绍K8S部署ingress-nginx的方法。 本文使用的K8S和ingress-nginx都是最新的版本。 官网地址 https://kubernetes.github.io/ingress-nginx/deploy/ Ingress里Nginx的代理流程: 1.确定版本 首先确定版本:https://github.com/kubernetes/ingress-nginx 我K8S是1.2

    2024年02月20日
    浏览(32)
  • 【Kubernetes运维篇】RBAC认证授权详解(一)

    1、什么是RBAC授权? RBAC是一种 基于角色访问控制方式 ,它将权限和角色相关联,用户加入到角色中,就会拥有角色中的权限,RBAC的核心思想是,将权限赋予给角色,角色中加入多个用户,加入进来的用户会具有角色的权限,如果修改权限也是针对角色进行操作,而不是针对

    2024年02月16日
    浏览(32)
  • 【Kubernetes运维篇】RBAC认证授权详解(二)

    官方中文参考连接: 在K8S中,所有资源对象都是通过API进行操作,他们保存在ETCD里面,而对ETCD的操作,我们需要通过访问kube-apiserver来实现, ServiceAccount其实就是apiserver的认证过程,而授权的机制是通过RBAC,基于角色的访问控制实现。 RBAC中有四个资源对象,分别是Role、

    2024年02月16日
    浏览(35)
  • 【Kubernetes运维篇】RBAC之准入控制器详解

    中文官方参考文档: 1、ResourceQuota是什么? ResourceQuota准入控制器是K8S中内置的准入控制器,默认该控制器是启用状态, 主要功能是限制名称空间下的资源使用 ,防止在一个名称空间下的Pod占用过多的资源, 简单理解就是针对名称空间限制用户资源的使用。 2、限制CPU、内存

    2024年02月16日
    浏览(33)
  • 【Kubernetes运维篇】零故障升级Pod健康探测详解

    中文官方参考文档: Pod探测是Kubernetes中的一种机制, 用于检测Pod的状态和健康状况。当探测到Pod状态不正常时,根据重启策略进行相应的Pod操作 ,探测可以帮助Kubernetes集群自动化地管理容器的健康状态,提高应用程序的可靠性和可用性。 探测针对Pod中容器进行操作,所以探

    2024年02月08日
    浏览(42)
  • K8s实战4-使用Helm在Azure上部署Ingress-Nginx和Tokengateway

    az login az account set --subscription ${sub ID} az aks get-credentials --resource-group ${groupname} --name ${aks name} curl -LO https://github.com/kubernetes/ingress-nginx/releases/download/helm-chart-4.7.1/ingress-nginx-4.7.1.tgz sudo tar -xvf ingress-nginx-4.2.5.tgz sudo cd ingress-nginx #创建命名空间 kubectl create ns ingress-nginx-public # 使用

    2024年02月12日
    浏览(31)
  • 第12关 精通K8s下的Ingress-Nginx控制器:生产环境实战配置指南

    ------ 课程视频同步分享在今日头条和B站 大家好,我是博哥爱运维,这节课带来k8s的流量入口ingress,作为业务对外服务的公网入口,它的重要性不言而喻,大家一定要仔细阅读,跟着博哥的教程一步步实操去理解。 Ingress基本概念 在Kubernetes集群中,Ingress作为集群内服务对外

    2024年02月03日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包