当前位置: 首页 > news >正文

Ingress蓝绿发布

Ingress蓝绿发布

    • Ingress常用注解说明
    • yaml资源清单
      • 绿色版本yml资源清单
      • 蓝色版本yaml资源清单
    • 主Ingress
    • 金丝雀Ingress
      • 基于客户端请求头的流量切分
        • 结果验证
      • 基于客户端来源IP的流量切分
        • 结果验证
      • 基于服务权重的流量切分
        • 结果验证
      • 基于IP来源区域来切分IP---方案未验证
      • 基于User-Agent的浏览切分

Ingress常用注解说明

参考: https://mp.weixin.qq.com/s?src=11&timestamp=1744441177&ver=5925&signature=UhWSx6O1yYqJfZTgogAKh35NhaDZeNgldN–plZ3RcRz-ifGfiOfPNcTOafFw9-dehVqXQkNMOrPPct7S1bX8-llmm1e54TAITu8Sj-XgJYk8Ov*bFGQ9hhN77G8i8Zd&new=1

Nginx Ingress支持通过配置注解(Annotations)来实现不同场景下的发布和测试,可以满足灰度发布蓝绿发布A/B测试等业务场景。具体实现过程如下:

为服务创建两个Ingress:

  • 一个为常规Ingress
  • 另一个为带nginx.ingress.kubernetes.io/canary: "true"注解的Ingress,称为Canary Ingress(金丝雀发布)
  • Canary Ingress(金丝雀发布)配置流量切分策略Annotation两个Ingress相互配合,即可实现多种场景的发布和测试。

Nginx Ingress的Annotation支持以下几种规则:

Annotation作用
nginx.ingress.kubernetes.io/canary-by-header适用于灰度发布基于Header的流量切分,如果请求头中包含指定的header名称,并且值为“always”,就将该请求转发给Canary Ingress定义的对应后端服务。如果值为“never”则不转发,可用于回滚到旧版本。如果为其他值则忽略该annotation,并通过优先级将请求流量分配到其他规则。
nginx.ingress.kubernetes.io/canary-by-header-value必须与canary-by-header一起使用,可自定义请求头的取值,包含但不限于“always”或“never”。当请求头的值命中指定的自定义值时,请求将会转发给Canary Ingress定义的对应后端服务,如果是其他值则忽略该annotation,并通过优先级将请求流量分配到其他规则。
nginx.ingress.kubernetes.io/canary-by-header-patterncanary-by-header-value类似,唯一区别是该annotation正则表达式匹配请求头的值,而不是某一个固定值。如果该annotationcanary-by-header-value同时存在,该annotation将被忽略。
nginx.ingress.kubernetes.io/canary-by-cookie基于Cookie的流量切分,适用于灰度发布。与canary-by-header类似,该annotation用于cookie,仅支持“always”和“never”,无法自定义取值。
nginx.ingress.kubernetes.io/canary-weight基于服务权重的流量切分,适用于蓝绿部署。表示Canary Ingress所分配流量的百分比,取值范围[0-100]。例如,设置为100,表示所有流量都将转发给Canary Ingress对应的后端服务。

以上注解规则会按优先级进行评估,优先级为:

canary-by-header(请求头) -> canary-by-cookie -> canary-weight(服务权重)


yaml资源清单

蓝色版本和绿色版本的区别

  • deployment的name不同
  • Labels不同
  • 镜像版本tag不同
  • svc的name不同


绿色版本yml资源清单

apiVersion: apps/v1 # 指定 Deployment 的 API 版本
kind: Deployment # 声明资源类型为 Deployment
metadata: # 元数据部分
  name: demo # Deployment 的名称
  labels: # 标签部分
    app: demo # 标签键值对,用于标识和选择资源
spec: # Deployment 的规格定义
  replicas: 1 # 副本数量,指定运行的 Pod 数量
  selector: # 用于选择匹配的 Pod
    matchLabels: # 匹配的标签
      app: demo # 匹配 app=demo 的 Pod
  template: # Pod 模板定义
    metadata: # Pod 的元数据
      labels: # Pod 的标签
        app: demo # 标签键值对,用于选择和标识 Pod
    spec: # Pod 的规格定义
      containers: # 容器列表
        - name: demo # 容器名称
          imagePullPolicy: Always # 镜像拉取策略,始终拉取最新镜像
          image: registry.cn-shanghai.aliyuncs.com/kubesre01/demo:v1 # 容器镜像地址
          ports: # 容器端口配置
            - containerPort: 8080 # 容器监听的端口号
---
apiVersion: v1 # 指定 Service 的 API 版本
kind: Service # 声明资源类型为 Service
metadata: # 元数据部分
  name: demo-svc # Service 的名称
spec: # Service 的规格定义
  type: ClusterIP # Service 类型,默认为 ClusterIP
  selector: # 用于选择关联的 Pod
    app: demo # 选择标签 app=demo 的 Pod
  ports: # Service 的端口配置
    - port: 8080 # Service 暴露的端口号
      targetPort: 8080 # 映射到 Pod 的目标端口号

蓝色版本yaml资源清单

apiVersion: apps/v1 # 指定 API 版本为 apps/v1,用于定义 Deployment
kind: Deployment # 声明资源类型为 Deployment
metadata: # 元数据部分
  name: demo-new # Deployment 的名称
  labels: # 标签部分
    app: demo-new # 标签键值对,用于标识该 Deployment
spec: # 规范部分
  replicas: 1 # 副本数量,指定运行的 Pod 数量
  selector: # 选择器部分
    matchLabels: # 匹配的标签
      app: demo-new # 选择具有 app=demo-new 标签的 Pod
  template: # Pod 模板
    metadata: # Pod 的元数据
      labels: # 标签部分
        app: demo-new # Pod 的标签,用于与选择器匹配
    spec: # Pod 的规范部分
      containers: # 容器列表
      - name: demo-new # 容器名称
        imagePullPolicy: Always # 镜像拉取策略,始终拉取最新镜像
        image: registry.cn-shanghai.aliyuncs.com/kubesre01/demo:v2 # 容器使用的镜像
        ports: # 容器端口配置
        - containerPort: 8080 # 容器监听的端口号
---
apiVersion: v1 # 指定 API 版本为 v1,用于定义 Service
kind: Service # 声明资源类型为 Service
metadata: # 元数据部分
  name: demo-new-svc # Service 的名称
spec: # 规范部分
  type: ClusterIP # Service 类型为 ClusterIP,默认类型
  selector: # 选择器部分
    app: demo-new # 选择具有 app=demo-new 标签的 Pod
  ports: # 端口配置
    - port: 8080 # Service 暴露的端口号
      targetPort: 8080 # 映射到 Pod 的目标端口号

主Ingress

默认将流量路由到主服务

apiVersion: networking.k8s.io/v1 # 定义 Ingress 的 API 版本
kind: Ingress # 声明资源类型为 Ingress
metadata: # 元数据部分
  name: demo # Ingress 的名称为 demo
spec: # 规范部分
  rules: # 定义 Ingress 的规则
    - host: demo.intel.dev # 指定主机名为 demo.intel.dev
      http: # 定义 HTTP 路由规则
        paths: # 定义路径规则
          - path: /info # 指定路径为 /info
            pathType: Prefix # 路径匹配类型为 Prefix(前缀匹配)
            backend: # 定义后端服务
              service: # 指定服务信息
                name: demo-svc # 服务名称为 demo-svc
                port: # 服务端口信息
                  number: 8080 # 服务端口号为 8080
  ingressClassName: nginx # 指定 Ingress 的类名为 nginx

金丝雀Ingress

基于客户端请求头的流量切分

  • 在注解中开启金丝雀发布功能
  • 为ingress添加请求头
  • 设置请求头为指定值时负载到 绿色版本的svc
apiVersion: networking.k8s.io/v1 # 使用 Kubernetes 的 Ingress API 版本 v1
kind: Ingress # 定义资源类型为 Ingress
metadata:
  name: demo-new-canary # 定义 Ingress 的名称为 demo-new-canary
  annotations: # 定义 Ingress 的注解,用于配置额外的功能
    # 启用金丝雀发布功能
    nginx.ingress.kubernetes.io/canary: "true"
    # 指定请求头名称为 "X-Beta-User"
    nginx.ingress.kubernetes.io/canary-by-header: "X-Beta-User"
    # 当请求头 "X-Beta-User" 的值为 "green" 时,将流量路由到金丝雀版本
    # 这里的 "X-Beta-User" 是一个示例值,可以根据实际需求进行修改
    # 例如,可以使用 "X-Beta-User" 来标识特定的用户或请求来源
    nginx.ingress.kubernetes.io/canary-by-header-value: "green"
spec:
  rules: # 定义 Ingress 的路由规则
    - host: demo.intel.dev # 指定主机名为 demo.intel.dev,匹配该域名的请求
      http: # 定义 HTTP 路由规则
        paths: # 定义路径规则
          - path: /info # 匹配路径为 /info 的请求
            pathType: Prefix # 路径匹配类型为 Prefix,表示以 /info 为前缀的路径都会匹配
            backend: # 定义后端服务
              service: # 指定后端服务的配置
                name: demo-new-svc # 后端服务的名称为 demo-new-svc
                port: # 定义后端服务的端口
                  number: 8080 # 后端服务的端口号为 8080
  ingressClassName: nginx # 指定使用 nginx 作为 Ingress 控制器

结果验证
# 使用 curl 命令向目标 URL 发送 HTTP 请求
## -H 参数用于设置请求头
### "X-Beta-User: green" 是一个自定义请求头,用于标识内测用户
curl -H "X-Beta-User: green" http://demo.intel.dev/info

# 没有请求头则访问到老的版本
curl http://demo.intel.dev/info

基于客户端来源IP的流量切分

apiVersion: networking.k8s.io/v1  # 定义 Ingress 资源的 API 版本
kind: Ingress  # 声明资源类型为 Ingress
metadata:
  name: demo-new-canary  # 定义 Ingress 的名称
  annotations:  # 为 Ingress 添加注解
    # # 启用金丝雀发布功能
    nginx.ingress.kubernetes.io/canary: "true"
    # 根据请求头 X-Forwarded-For 进行金丝雀流量分配
    nginx.ingress.kubernetes.io/canary-by-header: "X-Forwarded-For" 
    # 当请求头的值为指定 IP 时,将流量分发到 金丝雀版本 
    # 假定这个IP是测试部门的IP
    nginx.ingress.kubernetes.io/canary-by-header-value: "123.253.189.223"  
spec:
  rules:  # 定义 Ingress 的路由规则
  - host: demo.intel.dev  # 指定主机名
    http:
      paths:  # 定义路径规则
      - path: /info  # 指定路径为 /info
        pathType: Prefix  # 路径匹配类型为前缀匹配
        backend:  # 定义后端服务
          service:
            name: demo-new-svc  # 后端服务的名称
            port:
              number: 8080  # 后端服务的端口号
  ingressClassName: nginx  # 指定使用的 IngressClass 为 nginx

结果验证
#### "X-Forwarded-For:123.253.189.223" 模拟客户端 IP 地址
curl -H "X-Forwarded-For:123.253.189.223" http://demo.intel.dev/info

基于服务权重的流量切分

apiVersion: networking.k8s.io/v1 # 指定 Ingress 的 API 版本
kind: Ingress # 定义资源类型为 Ingress
metadata:
  name: demo-new-canary # 定义 Ingress 的名称
  annotations: # 定义 Ingress 的注解
    # 启用金丝雀发布功能
    nginx.ingress.kubernetes.io/canary: "true"
    # 根据请求头 X-Forwarded-For 进行金丝雀流量分配
    nginx.ingress.kubernetes.io/canary-by-header: "X-Forwarded-For"
    # 将 20% 的流量分配给金丝雀版本
    nginx.ingress.kubernetes.io/canary-weight: "20"

spec:
  rules: # 定义 Ingress 的规则
    - host: demo.intel.dev # 定义主机名
      http:
        paths: # 定义 HTTP 路径规则
          - path: /info # 定义路径为 /info
            pathType: Prefix # 路径匹配类型为前缀匹配
            backend: # 定义后端服务
              service:
                name: demo-new-svc # 后端服务的名称
                port:
                  number: 8080 # 后端服务的端口号
  ingressClassName: nginx # 指定使用的 IngressClass 为 nginx

结果验证
# 使用 for 循环发送 100 次 HTTP 请求到指定的 URL
for i in {1..100}; do
  # curl 命令用于发送 HTTP 请求
  # http://demo.intel.dev/info 是目标 URL,表示访问 demo.intel.dev 的 /info 路径
  curl http://demo.intel.dev/info;
done;
# 查看结果是否符合20%服务权重的设置。
# 提前设置好新版本的回显标记

基于IP来源区域来切分IP—方案未验证

  • 修改 Nginx Ingress ControllerConfigMap,添加 geo模块匹配特定 IP 地址段
    示例 ConfigMap 配置:
apiVersion: v1 # API版本,v1表示核心组的资源
kind: ConfigMap # 资源类型,这里是ConfigMap
metadata: # 元数据部分
  name: nginx-ingress-controller # ConfigMap的名称
  namespace: ingress-nginx # ConfigMap所在的命名空间
data: # 数据部分
  geoip: | # geoip配置数据,使用多行字符串格式
    geo $region { # 定义一个geo变量,用于根据IP地址分配区域
      default unknown; # 默认值为unknown
      123.253.189.0/24 region-a; # 指定IP地址范围对应的区域为region-a
    }
  • 使用 nginx.ingress.kubernetes.io/configuration-snippet 注解,根据 $region 变量进行流量分发
apiVersion: networking.k8s.io/v1 # 定义 Kubernetes Ingress 的 API 版本
kind: Ingress # 资源类型为 Ingress
metadata: # 元数据部分
  name: demo-new-canary # Ingress 的名称为 demo-new-canary
  annotations: # 注解部分
    # 启用金丝雀发布功能
    nginx.ingress.kubernetes.io/canary: "true"
    # 如果请求的 region 是 "region-a",设置服务名称为 "demo-new-svc"
    # $region 是一个 NGINX 变量,通常由外部输入(如请求头、客户端 IP 地址等)或上游配置(如 Nginx 的 geo 模块)定义。
    # $service_name 是一个自定义变量,可以被后续的 NGINX 配置引用,用于动态选择后端服务。
    nginx.ingress.kubernetes.io/configuration-snippet: | # 自定义 NGINX 配置片段
      if ($region = "region-a") { 
        set $service_name "demo-new-svc"; # 
      }
spec: # 规范部分
  rules: # 定义 Ingress 的规则
    - host: demo.intel.dev # 规则适用于主机名 demo.intel.dev
      http: # HTTP 路由规则
        paths: # 定义路径规则
          - path: /info # 匹配路径为 /info
            pathType: Prefix # 路径类型为前缀匹配
            backend: # 后端服务配置
              service: # 指定服务
                name: demo-new-svc # 服务名称为 demo-new-svc
                port: # 服务端口配置
                  number: 8080 # 服务端口号为 8080
  ingressClassName: nginx # 使用的 Ingress 类为 nginx

基于User-Agent的浏览切分

  • 未完待续

相关文章:

  • Redis 特性和应用场景
  • 测试模板1
  • python高级编程一(生成器与高级编程)
  • arcpy基础之环境搭建
  • 【QT】学习笔记1
  • leetcode刷题日记——赎金信
  • 【PyTorch项目实战】反卷积(Deconvolution)
  • 解决 weditor 报错AttributeError: ‘Device‘ object has no attribute ‘address’
  • Java对象内存结构详解
  • 文献总结:AAAI2025-UniV2X-End-to-end autonomous driving through V2X cooperation
  • linux RCU技术
  • Android11车载WiFi热点默认名称及密码配置
  • 蓝桥杯嵌入式考前模块总结
  • CMake中add_custom_command用法详解
  • Kubernetes安装与集群构建详细过程
  • 【STM32标准库】--新建工程
  • redis之缓存击穿
  • JavaScript Symbol与BigInt
  • Vue.js组件安全工程化演进:从防御体系构建到安全性能融合
  • 计算机系统设计中的一些常用方法
  • 做网站的 视频/西安网站建设排名
  • 网站建设肆金手指排名/南宁seo营销推广
  • 学校内部网站开发价格/百度推广官方网站登录入口
  • 湖北网站建设论文题目要求/营销比较好的知名公司有哪些
  • 小兔自助建站系统/推广策划
  • 做网站个体户经营范围/关键词网站