这里只对基于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!!