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

前言

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

前置知识

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

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

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

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

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

kubernetes.github.io/ingress-ngi...

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

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

实现步骤如下

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

yaml 复制代码
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

yaml 复制代码
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

核心配置:

yaml 复制代码
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "20"

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

3、测试

powershell 复制代码
[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配置

yaml 复制代码
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的核心相关配置如下

xml 复制代码
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;

        }
   

  }

核心配置

xml 复制代码
proxy_pass http://lybgeek.svcnew.com/; 
proxy_set_header Host lybgeek.svcnew.com;

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

3、测试

powershell 复制代码
[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其他灰度能力,大家可以通过官网或者下方提供的链接学习一下 help.aliyun.com/zh/ack/ack-...

相关推荐
荣光波比8 小时前
K8S(一)—— 云原生与Kubernetes(K8S)从入门到实践:基础概念与操作全解析
云原生·容器·kubernetes
伞啊伞8 小时前
K8s概念基础(一)
云原生·容器·kubernetes
hello_2509 小时前
k8s基础监控promql
云原生·容器·kubernetes
静谧之心12 小时前
在 K8s 上可靠运行 PD 分离推理:RBG 的设计与实现
云原生·容器·golang·kubernetes·开源·pd分离
1024find16 小时前
Spark on k8s部署
大数据·运维·容器·spark·kubernetes
能不能别报错1 天前
K8s学习笔记(十六) 探针(Probe)
笔记·学习·kubernetes
能不能别报错1 天前
K8s学习笔记(十四) DaemonSet
笔记·学习·kubernetes
火星MARK1 天前
k8s面试题
容器·面试·kubernetes
赵渝强老师1 天前
【赵渝强老师】Docker容器的资源管理机制
linux·docker·容器·kubernetes
能不能别报错1 天前
K8s学习笔记(十五) pause容器与init容器
笔记·学习·kubernetes