基于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!!
相关推荐
直饮水观察哨10 分钟前
商用净水器亲测对比,哪个更专业?
容器
塔克拉玛攻城狮10 分钟前
最新!银河麒麟v11 kubeadm部署k8s v1.35.0高可用集群
kubernetes·银河麒麟
eso19831 小时前
如何确保程序化广告系统中微服务架构的高可用性和可扩展性?
微服务·云原生·架构
Suchadar1 小时前
Docker基础命令(二)——数据卷管理端口映射与容器互联
运维·docker·容器
firstacui1 小时前
Docker容器网络管理与容器数据卷管理
运维·docker·容器
王锋(oxwangfeng)2 小时前
Apache Flink 在 Kubernetes 上的高效部署与优化实践
flink·kubernetes·apache
江畔何人初2 小时前
/etc/profile,.profile,.bashrc三者区分
linux·运维·云原生
codeRichLife2 小时前
docker拷贝,导入/导出等常用命令
docker
努力搬砖的咸鱼3 小时前
部署你的第一个应用到 K8s
微服务·云原生·容器·kubernetes