首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Ingress灰度路由策略-基于Url子路径灰度

Ingress灰度路由策略-基于Url子路径灰度

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

应用背景:应用发布需要基于请求url子路径匹配,访问同域名根据url子路径匹配自动转发请求到灰度服务。

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

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

一、测试应用app.py

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

app = Flask(__name__)

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

# 获取环境变量来判断是生产还是灰度环境
ENVIRONMENT = os.getenv('ENVIRONMENT', 'production')

@app.route('/')
def main():
    # 获取客户端真实IP
    client_ip = request.headers.get('X-Forwarded-For', request.remote_addr)
    
    # 从环境变量获取配置
    service_name = os.getenv('SERVICE_NAME', 'default')
    version = os.getenv('VERSION', 'v1')
    
    # 记录带IP的日志
    logger.info(f"Client IP: {client_ip} | Service: {service_name}-{version}")
    
    return jsonify({
        "service": service_name,
        "version": version,
        "client_ip": client_ip.split(',')[0]  # 处理多级代理情况
    })

# 生产环境路由
@app.route('/v1/<path:path>')
def production(path):
    # 获取客户端真实IP
    client_ip = request.headers.get('X-Forwarded-For', request.remote_addr)
    
    # 从环境变量获取配置
    service_name = os.getenv('SERVICE_NAME', 'default')
    version = os.getenv('VERSION', 'v1')
    
    # 记录带IP的日志
    logger.info(f"Client IP: {client_ip} | Service: {service_name}-{version} | Environment: production")
    
    return jsonify({
        "service": service_name,
        "version": version,
        "client_ip": client_ip.split(',')[0],  # 处理多级代理情况
        "environment": "production"
    })

# 灰度环境路由
@app.route('/v2/<path:path>')
def gray(path):
    # 获取客户端真实IP
    client_ip = request.headers.get('X-Forwarded-For', request.remote_addr)
    
    # 从环境变量获取配置
    service_name = os.getenv('SERVICE_NAME', 'default')
    version = os.getenv('VERSION', 'v1')
    
    # 记录带IP的日志
    logger.info(f"Client IP: {client_ip} | Service: {service_name}-{version} | Environment: gray")
    
    return jsonify({
        "service": service_name,
        "version": version,
        "client_ip": client_ip.split(',')[0],  # 处理多级代理情况
        "environment": "gray"
    })

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

二、Dockerfile文件

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

# 设置工作目录
WORKDIR /app

# 复制项目文件到工作目录
COPY . .

# 安装依赖
RUN pip install -r requirements.txt

# 暴露端口
EXPOSE 5000

# 启动应用
CMD ["python", "app.py"]

三、requirements.txt

代码语言:txt
复制
flask==2.0.3
werkzeug==2.0.3

四、ingress配置

灰度ingress配置

代码语言:txt
复制
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: 'true'
    nginx.ingress.kubernetes.io/canary-by-cookie: aaa
    nginx.ingress.kubernetes.io/canary-by-cookie-value: 'true'
  creationTimestamp: '2025-03-04T02:27:50Z'
  generation: 2
  managedFields:
    - apiVersion: networking.k8s.io/v1
      fieldsType: FieldsV1
      fieldsV1:
        f:metadata:
          f:annotations:
            .: {}
            f:kubernetes.io/ingress.class: {}
            f:nginx.ingress.kubernetes.io/canary: {}
      manager: kubectl-client-side-apply
      operation: Update
      time: '2025-03-04T02:27:50Z'
    - apiVersion: networking.k8s.io/v1
      fieldsType: FieldsV1
      fieldsV1:
        f:metadata:
          f:annotations:
            f:nginx.ingress.kubernetes.io/canary-by-cookie: {}
            f:nginx.ingress.kubernetes.io/canary-by-cookie-value: {}
        f:spec:
          f:rules: {}
      manager: fabric8-kubernetes-client
      operation: Update
      time: '2025-03-04T03:14:46Z'
  name: canary-ingress
  namespace: python3-gray
  resourceVersion: '11679371'
  uid: 196ce65e-8da3-4d9f-a084-08ff30d7ff8f
spec:
  rules:
    - host: canary.test3.com
      http:
        paths:
          - backend:
              serviceName: canary-svc
              servicePort: 80
            path: /
            pathType: ImplementationSpecific

生产ingress配置

代码语言:txt
复制
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: 'false'
  creationTimestamp: '2025-03-04T02:11:00Z'
  generation: 3
  labels:
    clusterId: 0f72be07aba84651940445f4573b99e2
    creator: xlf-ops
  managedFields:
    - apiVersion: networking.k8s.io/v1
      fieldsType: FieldsV1
      fieldsV1:
        f:metadata:
          f:annotations:
            f:kubernetes.io/ingress.class: {}
            f:nginx.ingress.kubernetes.io/canary: {}
      manager: kubectl-client-side-apply
      operation: Update
      time: '2025-03-04T02:27:50Z'
    - apiVersion: networking.k8s.io/v1
      fieldsType: FieldsV1
      fieldsV1:
        f:metadata:
          f:annotations: {}
          f:labels:
            .: {}
            f:clusterId: {}
            f:creator: {}
        f:spec:
          f:rules: {}
      manager: fabric8-kubernetes-client
      operation: Update
      time: '2025-03-04T02:51:58Z'
  name: main-ingress
  namespace: python3
  resourceVersion: '11674145'
  uid: 141d1304-c3ea-4793-ac17-9b936cfb32eb
spec:
  rules:
    - host: canary.test3.com
      http:
        paths:
          - backend:
              serviceName: prod-svc
              servicePort: 80
            path: /
            pathType: ImplementationSpecific

五、测试结果

由下图可以看到,可以根据url子路劲进行灰度路由

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档