基于K8s ingress灰度发布配置

这里只对基于ingress和configmap两种方式进行了演示,一种是流量控制,一种是configmap配置控制。
ingress:适用于整体版本更新迭代或者是某个页面的局部更新。
configmap:可以结合代码对指定地理区域或者指定机型(ios、安卓、pc)进行推送新版本。

一、安装ingress-nginx

bash 复制代码
#安装教程可以看另一篇文章

安装的是2025年7月份最新的ingress版本

https://helloops.cn/k8s/install_k8s_1_30_1.html

二、配置Ingress 权重路由(精准流量切分)

原理:通过 Ingress 控制器(如 Nginx Ingress)的权重配置,将指定比例的流量路由到新版本 Service,无需依赖副本数。
使用场景:精确流量控制(V1=5% , V2=95%)
1、创建两个不同版本的nginx deployment,并配置svc
bash 复制代码
vim nginx-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-v1
spec:
  replicas: 2  #初始副本数
  selector:
    matchLabels:
      app: nginx
      version: v1
  strategy:
    rollingUpdate:
      maxSurge: 1   # 最多比期望副本数多1个 (用于控制新版本创建速度)
      maxUnavailable: 0  #更新过程中不可用的Pod数为0 (用于保证服务的连续性)
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
        version: v1
    spec:
      containers:
      - name: nginx
        image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.27.4  
        ports:
        - containerPort: 80

--- 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-v2
spec:
  replicas: 2  #初始副本数
  selector:
    matchLabels:
      app: nginx
      version: v2
  strategy:
    rollingUpdate:
      maxSurge: 1   # 最多比期望副本数多1个 (用于控制新版本创建速度)
      maxUnavailable: 0  #更新过程中不可用的Pod数为0 (用于保证服务的连续性)
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
        version: v2
    spec:
      containers:
      - name: nginx
        image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.28.0  
        ports:
        - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc-v1
spec:
  selector:
    app: nginx
    version: v1
  ports:
  - port: 8080
    targetPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc-v2
spec:
  selector:
    app: nginx
    version: v2
  ports:
  - port: 8080
    targetPort: 80
部署deployment和service
复制代码
kubectl apply -f nginx-deployment.yaml
测试通过svc访问nginx
复制代码
#通过yaml获取已创建的资源列表

kubectl get -f nginx-deployment.yaml

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-v1   2/2     2            2           37m
deployment.apps/nginx-v2   2/2     2            2           37m

NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/nginx-svc-v1   ClusterIP   10.98.183.230   <none>        8080/TCP   37m
service/nginx-svc-v2   ClusterIP   10.97.71.111    <none>        8080/TCP   37m

# 能看到nginx版本号即可

curl 10.98.183.230:8080/nginx_status

curl 10.97.71.111:8080/nginx_status
2、创建ingress-nginx
bash 复制代码
vim ingress-ng-svc.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress-primary
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: nginx.ops.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-svc-v1
            port:
              number: 80

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress-canary
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/canary: "true" #启用金丝雀
    nginx.ingress.kubernetes.io/canary-weight: "50"
spec:
  rules:
  - host: nginx.ops.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-svc-v2
            port:
              number: 80
3、部署ingress
bash 复制代码
kubectl apply -f ingress-ng-svc.yaml

kubectl get -f ingress-ng-svc.yaml

NAME                    CLASS    HOSTS           ADDRESS         PORTS   AGE
nginx-ingress-primary   <none>   nginx.ops.com   10.110.74.177   80      29m
nginx-ingress-canary    <none>   nginx.ops.com   10.110.74.177   80      29m
4、测试流量控制是否生效
bash 复制代码
#如果和我一样是内网虚拟机,需要手动添加域名解析
vim /etc/hosts

10.110.74.177 nginx.ops.com
curl测试
bash 复制代码
curl nginx.ops.com/nginx_status

多次curl测试会发现,流量会分发到不同版本的nginx上说明流量控制生效

生产环境建议将多个ingress和deployment,用多个文件进行创建部署,方便调整流量权重,防止影响系统的可用性和连续性。

二、基于configmap配置隔离(配置灰度)

原理为一个svc绑定多个deployment,多个deployment挂载不同的configmap,来实现配置隔离,新配置渐进测试完后,将绑定旧configmap的deployment删除即可。
1、创建nginx deployment和svc
bash 复制代码
vim nginx-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-index-v1
spec:
  replicas: 2  #初始副本数
  selector:
    matchLabels:
      app: nginx
      env: configmap
  strategy:
    rollingUpdate:
      maxSurge: 1   # 最多比期望副本数多1个 (用于控制新版本创建速度)
      maxUnavailable: 0  #更新过程中不可用的Pod数为0 (用于保证服务的连续性)
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
        env: configmap
    spec:
      containers:
      - name: nginx
        image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.28.0
        ports:
        - containerPort: 80
        volumeMounts:
        - name: v1
          mountPath: /usr/share/nginx/html/
      volumes:
      - name: v1
        configMap:
          name: nginx-config-v1

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-index-v2
spec:
  replicas: 1  #初始副本数
  selector:
    matchLabels:
      app: nginx
      env: configmap
  strategy:
    rollingUpdate:
      maxSurge: 1   # 最多比期望副本数多1个 (用于控制新版本创建速度)
      maxUnavailable: 0  #更新过程中不可用的Pod数为0 (用于保证服务的连续性)
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
        env: configmap
    spec:
      containers:
      - name: nginx
        image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.28.0
        volumeMounts:
        - name: v2  
          mountPath: /usr/share/nginx/html/
        ports:
        - containerPort: 80
      volumes:
      - name: v2
        configMap:
          name: nginx-config-v2


---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx
    env: configmap
  ports:
  - port: 8080
    targetPort: 80
2、创建configmap
bash 复制代码
vim nginx-config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config-v1
data:
  version.html: |
    this is v1 version!!

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config-v2
data:
  version.html: |
    this is v2 version!!
3、部署测试
bash 复制代码
#部署deployment、svc、configmap
kubectl apply -f nginx-config.yaml

kubectl apply -f nginx-deployment.yaml

#查看svc的ip
kubectl get -f nginx-deployment.yaml

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-index-v1   2/2     2            2           24h
deployment.apps/nginx-index-v2   1/1     1            1           24h

NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
service/nginx-svc   ClusterIP   10.103.74.93   <none>        8080/TCP   24h

#测试访问
curl 10.103.74.93:8080/version.html
this is v1 version!!

curl 10.103.74.93:8080/version.html
this is v2 version!!

curl 10.103.74.93:8080/version.html
this is v1 version!!
相关推荐
老马啸西风1 小时前
windows wsl2-05-docker 安装笔记
运维·windows·笔记·docker·容器·k8s
老马啸西风2 小时前
windows docker-02-docker 最常用的命令汇总
linux·运维·ubuntu·docker·容器·eureka·maven
(:满天星:)2 小时前
JobSet:Kubernetes 分布式任务编排的统一解决方案
分布式·容器·kubernetes
cherishSpring4 小时前
Eureka服务端启动
云原生·eureka
慢慢慢时光4 小时前
本地k8s集群的搭建
云原生·容器·kubernetes
橘子编程5 小时前
Kubernetes (K8S)知识详解
云原生·容器·kubernetes
风清再凯6 小时前
prometheus 黑盒监控和docker检测
docker·容器·prometheus
观无7 小时前
基于Eureka和restTemple的负载均衡
云原生·eureka·负载均衡
阿杰技术9 小时前
Docker Compose 配置
运维·docker·容器