基于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!!
相关推荐
天河归来7 分钟前
本地windows环境升级dify到1.11.1版本
java·spring boot·docker
么么...2 小时前
在 Ubuntu 上安装 Docker 并部署 MySQL 容器
linux·运维·经验分享·笔记·mysql·ubuntu·docker
学Linux的语莫2 小时前
kompose、docker转k8s
docker·容器·kubernetes
阿里云云原生2 小时前
探秘 AgentRun丨流量一大就瘫痪?如何解决 AI 模型调用之痛
云原生
AI视觉网奇3 小时前
nvcr.io 登录方法
docker·ue5
是Yu欸3 小时前
从Ascend C算子开发视角看CANN的“软硬协同”
c语言·开发语言·云原生·昇腾·ascend·cann·开放社区
光头熊3 小时前
一次 nerdctl prune -a 导致 Kubernetes 节点不可用的复盘
kubernetes
码界奇点4 小时前
基于微服务架构的企业身份与访问管理系统设计与实现
微服务·云原生·架构·车载系统·毕业设计·源代码管理
weixin_445476685 小时前
Docker 在 Ubuntu(国内网络)安装及问题解决总结
网络·ubuntu·docker
一点晖光6 小时前
docker配置npm环境变量出现问题
docker·容器·npm