K8S Gateway AB测试、蓝绿发布、金丝雀(灰度)发布

假设有如下三个节点的 K8S 集群:

k8s31master 是控制节点

k8s31node1、k8s31node2 是工作节点

容器运行时是 containerd

一、场景分析

阅读本文,默认您已经安装了 K8S Gateway

关于 AB 测试、金丝雀发布,可以看这篇文章

二、实验准备

镜像下载

bash 复制代码
# 在各个工作节点下载
[root@k8s31node1 ~]# ctr -n=k8s.io images pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/openresty/openresty:latest
[root@k8s31node1 ~]# ctr -n=k8s.io images tag  swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/openresty/openresty:latest  docker.io/openresty/openresty:latest

[root@k8s31node2 ~]# ctr -n=k8s.io images pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/openresty/openresty:latest
[root@k8s31node2 ~]# ctr -n=k8s.io images tag  swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/openresty/openresty:latest  docker.io/openresty/openresty:latest

部署 v1

javascript 复制代码
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:latest"
        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-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

该 yml 定义了三个资源 ConfigMap、Deployment、Service。

  • ConfigMap 定义了一个 nginx.conf 配置文件,使用 lua 脚本输出 nginx-v1。
  • Deployment 定义了一个 Pod,里面运行 openresty 它是一个封装了 nginx+lua 的 web 服务器。Pod 有两个标签 app: nginx、version: v1。
  • Service 代理了 Deployment 运行的 Pod。

部署 v2

javascript 复制代码
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:latest"
        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

三、AB 测试

1)创建 gateway

javascript 复制代码
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: nginx-gateway
  namespace: default
spec:
  gatewayClassName: nginx
  listeners:
  - name: http
    protocol: HTTP
    port: 80

2)创建 httproute

javascript 复制代码
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: abtest-route
  namespace: default
spec:
  parentRefs:
    - name: nginx-gateway
  hostnames:
    - "abtest.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: / 
          headers:
            - name: "version"
              value: "v1"
      backendRefs:
        - name: nginx-v1
          kind: Service
          port: 80
    - matches:
        - path:
            type: PathPrefix
            value: /
          headers:
            - name: "version"
              value: "v2"  
      backendRefs:
        - name: nginx-v2
          kind: Service
          port: 80
  • parentRefs:绑定我们新建的 gateway。
  • hostnames:定义访问的主机名。
  • rules.matches:定义路由规则,PathPrefix 表示路径前缀匹配。headers 对请求头进行匹配。
  • backendRefs:定义后端服务以及服务端口。

3)测试

bash 复制代码
curl -H "Host: abtest.example.com" -H "version: v1" http://192.168.40.20:30185/
curl -H "Host: abtest.example.com" -H "version: v2" http://192.168.40.20:30185/

30185 为 nginx-gateway-controller 80 映射端口。

四、金丝雀发布

1)创建 httproute

javascript 复制代码
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: canary-route
  namespace: default
spec:
  parentRefs:
    - name: nginx-gateway
  hostnames:
    - "canary.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: / 
      backendRefs:
        - name: nginx-v1
          kind: Service
          port: 80
          weight: 10
        - name: nginx-v2
          kind: Service
          port: 80
          weight: 90

backendRefs.weight 定义流量分发的权重。

2)测试

bash 复制代码
for i in {1..20}; do curl -H "Host: canary.example.com" http://192.168.40.20:30185/; done;
相关推荐
❀͜͡傀儡师19 小时前
完成一个可交互的k8s管理平台的页面开发
容器·kubernetes·交互
not coder19 小时前
验证负载均衡与弹性伸缩
运维·jmeter·kubernetes·负载均衡
某某1 天前
DashBoard安装使用
大数据·开发语言·kubernetes
youliroam1 天前
Ubuntu24.04.2 + kubectl1.33.1 + containerdv1.7.27 + calicov3.30.0
ubuntu·kubernetes·kubesphere·containerd·calico
ascarl20102 天前
k8s更新证书
云原生·容器·kubernetes
xyhshen2 天前
麒麟v10+信创x86处理器离线搭建k8s集群完整过程
docker·容器·kubernetes·国产操作系统
编码如写诗2 天前
【信创-k8s】海光/兆芯+银河麒麟V10离线部署k8s1.31.8+kubesphere4.1.3
云原生·容器·kubernetes
MonkeyKing_sunyuhua2 天前
Kubernetes资源申请沾满但是实际的资源占用并不多,是怎么回事?
云原生·容器·kubernetes
ytttr8732 天前
k8s的出现解决了java并发编程胡问题了
java·容器·kubernetes
qq_312920112 天前
K8S上使用helm部署 Prometheus + Grafana
kubernetes·grafana·prometheus