Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Ingress灰度路由策略-基于IP灰度路由

Ingress灰度路由策略-基于IP灰度路由

原创
作者头像
dufu
发布于 2025-03-06 13:21:01
发布于 2025-03-06 13:21:01
1450
举报
文章被收录于专栏:k8s相关实操k8s相关实操

应用背景:应用发布需要基于指定IP进行灰度测试,这个指定的IP段可能是测试机,也可能是某个网段。这些IP地址访问同域名应用自动转发请求到灰度服务。

组件支持:需要对ingress-nginx-controller做二次开发改造,这里略过改造部分,重点关注测试流程。

测试步骤:准备两套环境,生产环境/测试环境,准备测试应用镜像,根据环境变量输出日志方便观察日志判断流量是被路由到哪个环境的服务,分别部署应用到生产和测试环境,编写测试脚本进行测试。接下来重点展示部署和测试脚本。

一、测试应用app.py

代码语言:txt
AI代码解释
复制
import os
import logging
from flask import Flask, jsonify

app = Flask(__name__)

# 日志配置
logging.basicConfig(
    format='%(asctime)s [%(levelname)s] %(message)s',
    level=logging.INFO
)
logger = logging.getLogger(__name__)

@app.route('/')
def main():
    # 从环境变量获取配置
    service_name = os.getenv('SERVICE_NAME', 'default')
    log_message = os.getenv('LOG_MESSAGE', 'Default log message')
    version = os.getenv('VERSION', 'v1')
    
    # 记录日志
    logger.info(f"[{service_name}-{version}] {log_message}")
    
    return jsonify({
        "service": service_name,
        "version": version,
        "message": log_message
    })

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

二、Dockerfile文件

代码语言:txt
AI代码解释
复制
FROM python:3.9-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .

CMD ["python", "app.py"]

三、requirements.txt

代码语言:txt
AI代码解释
复制
flask==2.0.3
werkzeug==2.0.3  # 固定兼容版本

四、部署脚本k8s.yaml

代码语言:txt
AI代码解释
复制
# 生产版本部署
apiVersion: apps/v1
kind: Deployment
metadata:
  name: production
  namespace: python
spec:
  replicas: 3
  selector:
    matchLabels:
      app: demo
      track: stable
  template:
    metadata:
      labels:
        app: demo
        track: stable
    spec:
      imagePullSecrets:
      - name: harbor-admin
      containers:
      - name: web
        image: harbor-lite.tech.21cn.com/python/my-service:v4
        env:
        - name: SERVICE_NAME
          value: "production"
        - name: LOG_MESSAGE
          value: "This is production service"
        - name: VERSION
          value: "v1"
        ports:
        - containerPort: 5000

---
# 灰度版本部署
apiVersion: apps/v1
kind: Deployment
metadata:
  name: canary
  namespace: python-gray
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demo
      track: canary
  template:
    metadata:
      labels:
        app: demo
        track: canary
    spec:
      imagePullSecrets:
      - name: harbor-admin
      containers:
      - name: web
        image: harbor-lite.tech.21cn.com/python/my-service:v5
        env:
        - name: SERVICE_NAME
          value: "canary"
        - name: LOG_MESSAGE
          value: "This is canary service"
        - name: VERSION
          value: "v2"
        ports:
        - containerPort: 5000

---
# 生产环境 Service
apiVersion: v1
kind: Service
metadata:
  name: prod-svc
  namespace: python
spec:
  selector:
    app: demo
    track: stable  # 精确匹配生产 Pod
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5000

---
# 灰度环境 Service
apiVersion: v1
kind: Service
metadata:
  name: canary-svc
  namespace: python-gray
spec:
  selector:
    app: demo
    track: canary  # 精确匹配灰度 Pod
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5000

---
# 主Ingress(90%流量)
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: main-ingress
  namespace: python
  annotations:
    nginx.ingress.kubernetes.io/canary: "false"
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: canary.demo.com
    http:
      paths:
      - path: /
        backend:
          serviceName: prod-svc
          servicePort: 80

---
# 灰度Ingress(10%流量)
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: canary-ingress
  namespace: python-gray
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
  rules:
  - host: canary.demo.com
    http:
      paths:
      - path: /
        backend:
          serviceName: canary-svc
          servicePort: 80

五、测试脚本

代码语言:txt
AI代码解释
复制
#!/bin/bash
INGRESS_IP="your_ingress_ip"  # 替换为实际IP
TOTAL=100
SUCCESS=0
FAILED=0
V1_COUNT=0
V2_COUNT=0

# 创建临时文件记录结果
result_file=$(mktemp)
trap 'rm -f "$result_file"' EXIT

for i in $(seq 1 $TOTAL); do
  # 发送请求并记录结果
  {
    response=$(curl -sSf -m 5 -H "Host: canary.demo.com" http://172.19.0.93/ 2>&1)
    exit_code=$?
    
    if [ $exit_code -eq 0 ]; then
      version=$(echo "$response" | jq -r '.version' 2>/dev/null)
      if [[ "$version" == "v1" || "$version" == "v2" ]]; then
        echo "success $version" >> "$result_file"
      else
        echo "invalid" >> "$result_file"
      fi
    else
      echo "failed" >> "$result_file"
    fi
  } &
  
  # 控制并发数
  if (( i % 10 == 0 )); then
    wait
  fi
done

# 等待所有后台任务完成
wait

# 统计结果
while read -r line; do
  case $line in
    "success v1")
      ((SUCCESS++))
      ((V1_COUNT++))
      ;;
    "success v2")
      ((SUCCESS++))
      ((V2_COUNT++))
      ;;
    "invalid")
      ((FAILED++))
      ;;
    "failed")
      ((FAILED++))
      ;;
  esac
done < "$result_file"

# 生成报告
echo "=== 精准测试报告 ==="
echo "总请求数:   $TOTAL"
echo "成功请求:   $SUCCESS (v1: $V1_COUNT, v2: $V2_COUNT)"
echo "失败请求:   $FAILED"
echo "灰度比例:   $(( V2_COUNT * 100 / SUCCESS ))% (预期10%)"

# 验证总数
if [ $(( SUCCESS + FAILED )) -ne $TOTAL ]; then
  echo "[警告] 总数校验失败:$SUCCESS + $FAILED ≠ $TOTAL"
else
  echo "[校验] 总数匹配成功"
fi

测试结果:

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Ingress灰度路由策略-基于请求头灰度
应用背景:应用发布需要基于请求灰度头进行灰度测试,携带请求头的请求灰度到灰度服务。
dufu
2025/03/06
900
Ingress灰度路由策略-基于Url子路径灰度
应用背景:应用发布需要基于请求url子路径匹配,访问同域名根据url子路径匹配自动转发请求到灰度服务。
dufu
2025/03/06
1320
聊聊部署在不同K8S集群上的服务如何利用nginx-ingress进行灰度发布
之前有篇文章聊聊如何利用springcloud gateway实现简易版灰度路由,里面的主人公又有一个需求,他们有个服务是没经过网关的,而是直接通过nginx-ingress暴露出去,现在这个服务也想做灰度,他知道在同个集群如何利用nginx-ingress进行灰度发布,但是现在这个服务是部署在新的集群,他查了不少资料,都没查到他想要的答案,于是就和我交流了一下,看我这边有没有什么实现思路,今天就来聊下这个话题:不同K8S集群上的服务如何利用nginx-ingress进行灰度发布
lyb-geek
2023/12/05
4470
聊聊部署在不同K8S集群上的服务如何利用nginx-ingress进行灰度发布
如何通过ingress-nginx实现应用灰度发布?
在日常的工作中,我们会经常对应用进行发版升级,在互联网公司尤为频繁,主要是为了满足快速的业务发展。我们经常用到的发布方式有滚动更新、蓝绿发布、灰度发布。
没有故事的陈师傅
2022/04/05
1.4K0
如何通过ingress-nginx实现应用灰度发布?
Ingress-Nginx 服务暴露基础学习与实践
描述: 到目前为止我们了解kubernetes常用的三种暴露服务的方式:LoadBlancer Service、 NodePort Service、Ingress
全栈工程师修炼指南
2022/09/29
3.1K1
Ingress-Nginx 服务暴露基础学习与实践
ASP.NET Core on K8S深入学习(14)Ingress灰度发布
本篇已加入《.NET Core on K8S学习实践系列文章索引》,可以点击查看更多容器化技术相关系列文章。
Edison Zhou
2020/05/25
6780
ASP.NET Core on K8S深入学习(14)Ingress灰度发布
Ingress企业实战:金丝雀与蓝绿发布篇
现如今,越来越多的应用采用了微服务架构,这也导致了应用数量相比传统模式更多,管理更加复杂,发布更加频繁,如果直接将新版本上线发布给全部用户。一旦遇到线上事故(或BUG),对用户的影响极大,解决问题周期较长,甚至有时不得不回滚到前一版本,严重影响了用户体验。为了保证整体系统的稳定,风险降到最低,我们可以采用灰度发布与蓝绿发布等不同的发布方式。
用户1107783
2023/09/11
6810
Ingress企业实战:金丝雀与蓝绿发布篇
Ingress-Nginx 服务暴露基础学习与实践 (2)
更多学习笔记文章请关注 WeiyiGeek 公众账号,学习交流【邮箱联系: Master#weiyigeek.top】
全栈工程师修炼指南
2021/07/25
3.3K0
Ingress-Nginx 服务暴露基础学习与实践 (2)
Nginx Ingress的一些奇巧淫技
redirect主要用于域名重定向,比如访问a.com被重定向到b.com。 如下我们配置访问ng.coolops.com重定向到www.baidu.com
极客运维圈
2020/05/14
9.1K1
Ingress-Nginx 服务暴露基础学习与实践(1)
本章讲解通过服务发现的功能进行实现 , 由 Ingress controller 来提供路由信息的刷新, Ingress controller可以理解为一个监视器不断监听 kube-apiserver 实时感知service、Pod的变化
全栈工程师修炼指南
2021/07/25
3.2K0
【云原生 | Kubernetes篇】Ingress案例实战(十三)
ingress规则会生效到所有按照了IngressController的机器的nginx配置。
Lansonli
2022/06/16
1.1K0
【云原生 | Kubernetes篇】Ingress案例实战(十三)
真一文搞定 ingress-nginx 的使用
前面我们学习了在 Kubernetes 集群内部使用 kube-dns 实现服务发现的功能,那么我们部署在 Kubernetes 集群中的应用如何暴露给外部的用户使用呢?我们知道可以使用 NodePort 和 LoadBlancer 类型的 Service 可以把应用暴露给外部用户使用,除此之外,Kubernetes 还为我们提供了一个非常重要的资源对象可以用来暴露服务给外部用户,那就是 Ingress。对于小规模的应用我们使用 NodePort 或许能够满足我们的需求,但是当你的应用越来越多的时候,你就会发现对于 NodePort 的管理就非常麻烦了,这个时候使用 Ingress 就非常方便了,可以避免管理大量的端口。
我是阳明
2020/12/16
19.3K0
真一文搞定 ingress-nginx 的使用
K8S基于ingress-nginx实现灰度发布
通过给 Ingress 资源指定 Nginx Ingress 所支持的 annotation 可实现金丝雀发布。需给服务创建2个 Ingress,其中1个常规 Ingress,另1个为nginx.ingress.kubernetes.io/canary: "true"· 固定的 annotation 的 Ingress,称为 Canary Ingress。Canary Ingress 一般代表新版本的服务,结合另外针对流量切分策略的 annotation 一起配置即可实现多种场景的金丝雀发布。以下为相关 annotation 的详细介绍:
匿名用户的日记
2021/12/14
3.4K0
K8S基于ingress-nginx实现灰度发布
kubernetes1.22安装使用ingress-nginx
我们已经了解了 Ingress 资源对象只是一个路由请求描述配置文件,要让其真正生效还需要对应的 Ingress 控制器才行,Ingress 控制器有很多,这里我们先介绍使用最多的 ingress-nginx,它是基于 Nginx 的 Ingress 控制器。
我是阳明
2021/12/27
3.3K0
kubernetes1.22安装使用ingress-nginx
Ingress-nginx灰度发布功能详解
最近公司一直在推进DevOps,主要目标是减少对个人的依赖,降低团队之间的损耗,在保证质量的前提下,快速交付价值。在实际执行过程中表现出来的就是服务拆分粒度尽可能细,服务每次上线功能尽可能少,发布节奏尽可能快; 服务必须做到可灰度、可监控、可回滚。至于监控先暂且不聊,如何做到灰度发布升级以及回滚呢?整个PaaS平台是基于Kubernetes进行建设,Kubernetes资源对象Deployment可以做到滚动升级的功能,但并没有提供暂停点机制,即没有办法快捷方便的进行灰度功能的针对性测试。而灰度能力是业务快速发布过程中不可或缺的一种能力,如果出现问题,灰度能够保证其影响范围。
用户5166556
2020/08/05
1.9K0
Ingress-nginx灰度发布功能详解
ingress-nginx实现灰度和金丝雀发布
nginx-ingress作为K8S集群对外的流量入口,充当K8S集群内各个service的反向代理。日常工作中我们经常需要对服务进行版本更新升级,为此我们经常使用到的发布方式有滚动升级、分批暂停发布、蓝绿发布以及灰度发布等不同的发布操作。所以下面介绍下,通过配置nginx annotations来实现不同场景下的发布和测试。
我的小碗汤
2019/07/30
5.4K1
利用 Kruise Rollouts 对 Kubernetes 资源实现金丝雀发布
Kruise Rollouts 是一个旁路组件,它为一系列 Kubernetes 工作负载(如 Deployment and CloneSet)提供高级部署功能,如金丝雀、流量路由和渐进式交付功能
philentso
2022/12/29
9780
kubernetes-ingress(十)
https://kubernetes.io/docs/concepts/services-networking/ingress/
yuezhimi
2020/09/30
5370
kubernetes-ingress(十)
基于 Kubernetes 的 Nginx-Ingress 实现蓝绿部署
作者:chulinx 链接:https://juejin.cn/post/6844903927318577159
DevOps时代
2021/02/23
1.3K0
一、灰度发布
  灰度发布是一种发布方式,也叫金丝雀发布,起源是矿工在下井之前会先放一只金丝雀到井里,如果金丝雀不叫了,就代表瓦斯浓度高。原因是金丝雀对瓦斯气体很敏感。灰度发布的做法是:会在现存旧应用的基础上,启动一个新版应用,但是新版应用并不会直接让用户访问。而是先让测试同学去进行测试。如果没有问题,则可以将真正的用户流量慢慢导入到新版,在这中间,持续对新版本运行状态做观察,直到慢慢切换过去,这就是所谓的A/B测试。当然,你也可以招募一些灰度用户,给他们设置独有的灰度标示(Cookie,Header),来让他们可以访问到新版应用,当然,如果中间切换出现问题,也应该将流量迅速地切换到老应用上。
zaking
2022/05/10
1.7K0
相关推荐
Ingress灰度路由策略-基于请求头灰度
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档