基于K8s ingress灰度发布配置
这里只对基于ingress和configmap两种方式进行了演示,一种是流量控制,一种是configmap配置控制。
ingress:适用于整体版本更新迭代或者是某个页面的局部更新。
configmap:可以结合代码对指定地理区域或者指定机型(ios、安卓、pc)进行推送新版本。
一、安装ingress-nginx
#安装教程可以看另一篇文章安装的是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
vim nginx-deployment.yamlapiVersion: apps/v1
kind: Deployment
metadata:name: nginx-v1
spec:replicas: 2 #初始副本数selector:matchLabels:app: nginxversion: v1strategy:rollingUpdate:maxSurge: 1 # 最多比期望副本数多1个 (用于控制新版本创建速度)maxUnavailable: 0 #更新过程中不可用的Pod数为0 (用于保证服务的连续性)type: RollingUpdatetemplate:metadata:labels:app: nginxversion: v1spec:containers:- name: nginximage: 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: nginxversion: v2strategy:rollingUpdate:maxSurge: 1 # 最多比期望副本数多1个 (用于控制新版本创建速度)maxUnavailable: 0 #更新过程中不可用的Pod数为0 (用于保证服务的连续性)type: RollingUpdatetemplate:metadata:labels:app: nginxversion: v2spec:containers:- name: nginximage: 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: nginxversion: v1ports:- port: 8080targetPort: 80---
apiVersion: v1
kind: Service
metadata:name: nginx-svc-v2
spec:selector:app: nginxversion: v2ports:- port: 8080targetPort: 80
部署deployment和service
kubectl apply -f nginx-deployment.yaml
测试通过svc访问nginx
#通过yaml获取已创建的资源列表kubectl get -f nginx-deployment.yamlNAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-v1 2/2 2 2 37m
deployment.apps/nginx-v2 2/2 2 2 37mNAME 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_statuscurl 10.97.71.111:8080/nginx_status
2、创建ingress-nginx
vim ingress-ng-svc.yamlapiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: nginx-ingress-primaryannotations:kubernetes.io/ingress.class: "nginx"
spec:rules:- host: nginx.ops.comhttp:paths:- path: /pathType: Prefixbackend:service:name: nginx-svc-v1port:number: 80---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: nginx-ingress-canaryannotations:kubernetes.io/ingress.class: "nginx"nginx.ingress.kubernetes.io/canary: "true" #启用金丝雀nginx.ingress.kubernetes.io/canary-weight: "50"
spec:rules:- host: nginx.ops.comhttp:paths:- path: /pathType: Prefixbackend:service:name: nginx-svc-v2port:number: 80
3、部署ingress
kubectl apply -f ingress-ng-svc.yamlkubectl get -f ingress-ng-svc.yamlNAME 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、测试流量控制是否生效
#如果和我一样是内网虚拟机,需要手动添加域名解析
vim /etc/hosts10.110.74.177 nginx.ops.com
curl测试
curl nginx.ops.com/nginx_status
多次curl测试会发现,流量会分发到不同版本的nginx上说明流量控制生效
生产环境建议将多个ingress和deployment,用多个文件进行创建部署,方便调整流量权重,防止影响系统的可用性和连续性。
二、基于configmap配置隔离(配置灰度)
原理为一个svc绑定多个deployment,多个deployment挂载不同的configmap,来实现配置隔离,新配置渐进测试完后,将绑定旧configmap的deployment删除即可。
1、创建nginx deployment和svc
vim nginx-deployment.yamlapiVersion: apps/v1
kind: Deployment
metadata:name: nginx-index-v1
spec:replicas: 2 #初始副本数selector:matchLabels:app: nginxenv: configmapstrategy:rollingUpdate:maxSurge: 1 # 最多比期望副本数多1个 (用于控制新版本创建速度)maxUnavailable: 0 #更新过程中不可用的Pod数为0 (用于保证服务的连续性)type: RollingUpdatetemplate:metadata:labels:app: nginxenv: configmapspec:containers:- name: nginximage: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.28.0ports:- containerPort: 80volumeMounts:- name: v1mountPath: /usr/share/nginx/html/volumes:- name: v1configMap:name: nginx-config-v1---
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-index-v2
spec:replicas: 1 #初始副本数selector:matchLabels:app: nginxenv: configmapstrategy:rollingUpdate:maxSurge: 1 # 最多比期望副本数多1个 (用于控制新版本创建速度)maxUnavailable: 0 #更新过程中不可用的Pod数为0 (用于保证服务的连续性)type: RollingUpdatetemplate:metadata:labels:app: nginxenv: configmapspec:containers:- name: nginximage: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.28.0volumeMounts:- name: v2 mountPath: /usr/share/nginx/html/ports:- containerPort: 80volumes:- name: v2configMap:name: nginx-config-v2---
apiVersion: v1
kind: Service
metadata:name: nginx-svc
spec:selector:app: nginxenv: configmapports:- port: 8080targetPort: 80
2、创建configmap
vim nginx-config.yamlapiVersion: 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、部署测试
#部署deployment、svc、configmap
kubectl apply -f nginx-config.yamlkubectl apply -f nginx-deployment.yaml#查看svc的ip
kubectl get -f nginx-deployment.yamlNAME 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 24hNAME 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!!