Ingress蓝绿发布

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的浏览切分

  • 未完待续
在Docker和Kubernetes的集成环境中,实现蓝绿部署和金丝雀部署策略是提升应用发布可靠性和减少风险的有效手段。首先,需要深入理解这两种部署策略的基本原理和区别。 参考资源链接:[Docker与Kubernetes实战:CICD与云原生应用部署](https://wenku.youkuaiyun.com/doc/250dsiqjbm?spm=1055.2569.3001.10343) 蓝绿部署是一种在两个环境之间进行切换的方法,其中一个环境始终处于激活状态,另一个处于非激活状态。在蓝绿部署中,新的版本部署在非激活环境(绿)中,一旦测试验证无误后,通过简单的路由切换,将流量从旧版本(蓝)转移到新版本(绿)。 而金丝雀部署则更注重渐进式发布,即逐步将用户流量从旧版本转移到新版本,通常是通过用户分段或按比例的方式。这种方法可以在不影响大部分用户的情况下,对新版本进行压力测试和监控。 在Docker和Kubernetes环境下实施蓝绿部署,首先需要定义两个完全相同的Kubernetes部署配置文件,一个对应蓝色环境,另一个对应绿色环境。通过Kubernetes的服务(Service)资源来控制流量路由。在金丝雀部署中,则需要调整Kubernetes的部署配置文件,设置相应的 replicas 数量,并利用服务的选择器(selector)和负载均衡器来控制流量分配的比例。 为了实现这些部署策略,需要合理利用Kubernetes的ReplicaSets、Deployments、Services以及Ingress资源。在部署过程中,可以使用Kubernetes的声明式API来确保所需状态始终得到保持。 此外,通过Semaphore等CI/CD工具,可以实现自动化测试和部署。在Semaphore的管道中设置自动化任务,当代码提交到版本库后,自动构建Docker镜像,并推送到镜像仓库。然后,触发Kubernetes集群来更新部署,从而实现蓝绿或金丝雀部署。 深入掌握这些概念和工具的使用方法,将有助于在生产环境中实施高效和安全的部署策略。为了更全面地了解和实践这些部署方法,建议参阅《Docker与Kubernetes实战:CICD与云原生应用部署》一书。该书详细介绍了云原生应用的CI/CD流程,并提供了实操案例,帮助读者深入理解和应用蓝绿部署和金丝雀部署策略。 参考资源链接:[Docker与Kubernetes实战:CICD与云原生应用部署](https://wenku.youkuaiyun.com/doc/250dsiqjbm?spm=1055.2569.3001.10343)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

教Linux的李老师

赞赏是第一生产力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值