首页 > 系统相关 >聊聊部署在不同K8S集群上的服务如何利用nginx-ingress进行灰度发布

聊聊部署在不同K8S集群上的服务如何利用nginx-ingress进行灰度发布

时间:2023-12-05 10:35:35浏览次数:41  
标签:ingress old svc canary nginx 灰度 K8S

前言

之前有篇文章聊聊如何利用springcloud gateway实现简易版灰度路由,里面的主人公又有一个需求,他们有个服务是没经过网关的,而是直接通过nginx-ingress暴露出去,现在这个服务也想做灰度,他知道在同个集群如何利用nginx-ingress进行灰度发布,但是现在这个服务是部署在新的集群,他查了不少资料,都没查到他想要的答案,于是就和我交流了一下,看我这边有没有什么实现思路,今天就来聊下这个话题:不同K8S集群上的服务如何利用nginx-ingress进行灰度发布

前置知识

nginx-ingress自身能提供哪些灰度能力?

首先nginx-ingress是通过配置注解(Annotations)来实现灰度能力。当配置nginx.ingress.kubernetes.io/canary属性值为true时,开启灰度功能,如果为false,则不开启。

nginx-ingress默认支持的灰度规则如下

  • 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对应的后端服务。

  • nginx.ingress.kubernetes.io/canary-weight-total基于设定的权重总值。若未设定总值,默认总值为100。

注: 不同灰度规则优先级由高到低为::canary-by-header -> canary-by-cookie -> canary-weight

更多灰度规则配置信息,可以查看官网

https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#canary

同集群利用ingress进行灰度示例

注: 以服务权重的流量切分为例,实现的效果如图

实现步骤如下

1、配置旧服务相关的deployment 、service、ingress

apiVersion: apps/v1
kind: Deployment
metadata:
  name: svc-old
  labels:
    app: svc-old
spec:
  replicas: 1
  selector:
    matchLabels:
      app: svc-old
  template:
    metadata:
      labels:
        app: svc-old
    spec:
      containers:
      - name: svc-old
        imagePullPolicy: Always
        image: lybgeek.harbor.com/lybgeek/svc-old:v1
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: svc-old
spec:
  type: ClusterIP
  selector:
    app: svc-old
  ports:
    - port: 80
      targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: svc-old
spec:
  rules:
  - host: lybgeek.svc.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: svc-old 
            port:
              number: 80

2、配置新服务相关的deployment 、service、ingress

apiVersion: apps/v1
kind: Deployment
metadata:
  name: svc-new
  labels:
    app: svc-new
spec:
  replicas: 1
  selector:
    matchLabels:
      app: svc-new
  template:
    metadata:
      labels:
        app: svc-new
    spec:
      containers:
      - name: svc-new
        imagePullPolicy: Always
        image: lybgeek.harbor.com/lybgeek/svc-new:v1
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: svc-new
spec:
  type: ClusterIP
  selector:
    app: svc-new
  ports:
    - port: 80
      targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
   annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "20"
  name: svc-new
spec:
  rules:
  - host: lybgeek.svc.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: svc-new
            port:
              number: 80

核心配置:

    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "20"

该配置的意思是将20%的流量打到新服务

3、测试

[root@master ~]# for i in {1..10}; do curl http://lybgeek.svc.com; done;
svc-old 
svc-old 
svc-old 
svc-new
svc-old 
svc-old 
svc-old 
svc-old 
svc-new
svc-old 

可以看出大概有20%的比例打到新服务

不同集群利用ingress进行灰度示例

实现核心点如图


其实就是多加了一台nginx服务器,通过nginx再转发到新服务

步骤如下

1、旧服务同之前配置

2、新增nginx相关deployment,service、ingress配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: svc-nginx
spec:
  selector:
    matchLabels:
      app: svc-nginx
  template:
    metadata:
      labels:
        app: svc-nginx
    spec:
      containers:
      - image: lybgeek.harbor.com/lybgeek/nginx:1.23.2
        name: svc-nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /etc/nginx/conf.d/api.conf
          name: vol-nginx
          subPath: api.conf
      restartPolicy: Always
      volumes:
      - configMap:
          name: nginx-svc
        name: vol-nginx
---
apiVersion: v1
kind: Service
metadata:
  name: svc-nginx
spec:
  type: ClusterIP
  selector:
    app: svc-nginx
  ports:
    - port: 80
      targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
   annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "20"
  name: svc-nginx
spec:
  rules:
  - host: lybgeek.svc.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: svc-nginx
            port:
              number: 80

nginx.conf的核心相关配置如下

server {

        listen    80;

        gzip on;

        gzip_min_length 100;

        gzip_types text/plain text/css application/xml application/javascript;

        gzip_vary on;
		
		underscores_in_headers on;
       
       location / {

                proxy_pass http://lybgeek.svcnew.com/; 
				
				proxy_set_header Host lybgeek.svcnew.com;

                proxy_set_header X-Real-IP $remote_addr;

                proxy_set_header X-Forward-For $http_x_forwarded_for;

                proxy_pass_request_headers on;

                proxy_next_upstream off;

                proxy_connect_timeout 90;

                proxy_send_timeout 3600;

                proxy_read_timeout 3600;

                client_max_body_size 10m;

        }
   

  }

核心配置

proxy_pass http://lybgeek.svcnew.com/; 
proxy_set_header Host lybgeek.svcnew.com;

核心配置其实就是路由到新的服务

3、测试

[root@master ~]# for i in {1..10}; do curl http://lybgeek.svc.com; done;
svc-old 
svc-old 
svc-old 
svc-old 
svc-old 
svc-new 
svc-old 
svc-old 
svc-new

可以看出大概有20%的比例打到新服务

总结

本文主要还是借助ingress本身提供的灰度能力,至于不同集群的灰度,其实是通过多加一层来实现,很多时候做方案设计,如果没思路,可以先通过加一层来推演。当然如果公司已经上了servicemesh,直接用mesh就可以提供强大的灰度能力,最后ingress其他灰度能力,大家可以通过官网或者下方提供的链接学习一下
https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/use-the-nginx-ingress-controller-for-canary-releases-and-blue-green-deployments-1

标签:ingress,old,svc,canary,nginx,灰度,K8S
From: https://www.cnblogs.com/linyb-geek/p/17635439.html

相关文章

  • 云原生周刊:K8s 的 YAML 技巧 | 2023.12.4
    开源项目推荐HelmfileHelmfile是用于部署HelmChart的声明性规范。其功能有:保留图表值文件的目录并维护版本控制中的更改。将CI/CD应用于配置更改。定期同步以避免环境偏差。Docketeer一款Docker和Kubernetes开发人员工具,用于管理容器并可视化集群和容器指标。......
  • 使用 anasible 搭建一个多 master 多 worker 的 k8s 集群
    kubernetes+istio是目前最强大,也是最易于使用的服务网格方案。要使用kubernetes+istio,首先要搭建kubernets集群。搭建kubernetes集群的方式有很多,其中使用anisble自动化搭建kubernetes集群算是最具合适的方案了。服务器列表:192.168.2.58k8s-lvs-01#lvs主服务器1......
  • k8s fsgroup
    k8s的配置中又fsgroup这个概念,请看下面这个配置:apiVersion:v1kind:Podmetadata:name:testspec:restartPolicy:NeversecurityContext:runAsUser:1001fsGroup:999containers:-name:mounttest-containerimage:ubuntuvolumeMounts:......
  • 怎么使用K8S部署禅道
    使用Docker部署禅道参考https://www.cnblogs.com/minseo/p/15879412.html本文介绍使用K8S部署最新版禅道软件即系统版本#操作系统#cat/etc/redhat-releaseCentOSLinuxrelease7.9.2009(Core)#uname-aLinuxCentOS7K8SMaster010633.10.0-1160.el7.x86_64#1SMP......
  • k8s集群部署nginx服务以及外网访问nginx服务
    1、查看k8s进群状态[root@k8s-mastertest]#kubectlgetnodeNAMESTATUSROLESAGEVERSIONk8s-masterReadymaster16dv1.15.1k8s-node1Ready<none>16dv1.15.12、编写nginx服务yaml文件kind:NamespaceapiVersion:v1metad......
  • k8s安装mysql
    镜像:mysql:8.0.34apiVersion:apps/v1kind:Deploymentmetadata:name:mysqllabels:workload.user.cattle.io/workloadselector:apps.deployment-wfs-test-mysqlnamespace:wfs-testselector:matchLabels:workload.user.cattle.io/workloads......
  • k8s 安装kubevirt v0.59.0 (k3s v1.26.4)
    1.安装kubevirt-operator.yaml(可以直接指定VERSION=v0.59.0-alpha.2;可以直接先在浏览器访问github下载yaml)exportVERSION=$(curl-shttps://api.github.com/repos/kubevirt/kubevirt/releases|greptag_name|grep-v--'-rc'|sort-r|head-1|awk-F':'&#......
  • K8S内POD使用内存缓慢增长问题
    背景生产环境服务容器化后,部分服务频繁触发内存使用超80%告警,POD内存限制内存以及JVM内存设置如下resources:requests: cpu:1000m memory:2200Milimits: cpu:3000m memory:3000MiJAVA_OPTS='-Xmx2000m'问题排查步骤通过查看K8Spod的监......
  • 从物理机到K8S:应用系统部署方式的演进及其影响
    公众号「架构成长指南」,专注于生产实践、云原生、分布式系统、大数据技术分享。概述随着科技的进步,软件系统的部署架构也在不断演进,从以前传统的物理机到虚拟机、Docker和Kubernetes,我们经历了一系列变化。这些技术的引入给我们带来了更高的资源利用率、更快的部署速度和更......
  • zabbix6监控k8s指标说明
    一.deploy中的指标1.1Deployment副本数未达预期告警min(/Kubernetes_testclusterstatebyHTTP/kube.deployment.replicas_mismatched[{#NAMESPACE}/{#NAME}],{$KUBE.REPLICA.MISMATCH.EVAL_PERIOD:"deployment:{#NAMESPACE}:{#NAME}"})>0andlast(/Kubernetes_testclus......