聊聊部署在不同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-...

相关推荐
weixin_453965001 小时前
[单master节点k8s部署]31.ceph分布式存储(二)
分布式·ceph·kubernetes
大G哥4 小时前
记一次K8S 环境应用nginx stable-alpine 解析内部域名失败排查思路
运维·nginx·云原生·容器·kubernetes
妍妍的宝贝4 小时前
k8s 中微服务之 MetailLB 搭配 ingress-nginx 实现七层负载
nginx·微服务·kubernetes
福大大架构师每日一题6 小时前
23.1 k8s监控中标签relabel的应用和原理
java·容器·kubernetes
程序那点事儿6 小时前
k8s 之动态创建pv失败(踩坑)
云原生·容器·kubernetes
唐大爹18 小时前
项目实战:k8s部署考试系统
云原生·容器·kubernetes
Zl1597531597531 天前
k8s基础环境部署
云原生·容器·kubernetes
花酒锄作田1 天前
[kubernetes]二进制方式部署单机k8s-v1.30.5
kubernetes
陌殇殇殇1 天前
使用GitLab CI构建持续集成案例
运维·ci/cd·云原生·容器·kubernetes·gitlab
daxian_am4611 天前
k8s image error
java·数据库·kubernetes