前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ingress-nginx实现灰度和金丝雀发布

ingress-nginx实现灰度和金丝雀发布

作者头像
我的小碗汤
发布2019-07-30 15:30:10
5.2K1
发布2019-07-30 15:30:10
举报
文章被收录于专栏:我的小碗汤

发布场景

  • 场景一
  • 场景二

  • 注解说明
    • 基于Request Header的流量切分
    • 基于Cookie的流量切分
    • 基于服务权重的流量切分
    • 三种注释的优先级和注意点

nginx-ingress作为K8S集群对外的流量入口,充当K8S集群内各个service的反向代理。日常工作中我们经常需要对服务进行版本更新升级,为此我们经常使用到的发布方式有滚动升级、分批暂停发布、蓝绿发布以及灰度发布等不同的发布操作。所以下面介绍下,通过配置nginx annotations来实现不同场景下的发布和测试。

发布场景

场景一

假设当前线上环境我们已经有一套服务Service A对外提供7层服务,此时我们新开发了一些新的特性,需要灰度发布上线一个新的版本Service A',但是我们暂时又不希望简单地直接替换掉Service A服务,而是希望将请求头中包含foo=bar或者cookie中包含foo=bar的客户端请求转发到Service A'服务中,待运行一段时间稳定,将所有的流量切换到Service A'服务中后,再平滑地下线掉Service A服务

场景二

假设当前线上环境我们已经有一套服务Service B对外提供7层服务,此时我们修复了一些问题,需要灰度发布上线一个新的版本Service B',但是我们又不希望简单直接地将所有客户端流量切换到新版本Service B'中,而是希望仅仅切换20%的流量到新版本Service B'中,待运行一段时间稳定,将所有的流量切换到Service B'服务中后,再平滑地下线掉Service B服务:

针对以上多种不同的应用发布需求,nginx Ingress 支持了多种流量切分方式:

  1. 基于Request Header的流量切分,适用于灰度发布以及AB测试场景
  2. 基于Cookie的流量切分,适用于灰度发布以及AB测试场景
  3. 基于服务权重的流量切分,适用于蓝绿发布场景

注解说明

K8S Ingress Controller通过下列Annotation来支持应用服务的不同发布机制,首先需要设置

代码语言:javascript
复制
nginx.ingress.kubernetes.io/canary: "true"

然后根据需要求设定对应的配置

基于Request Header的流量切分

nginx.ingress.kubernetes.io/canary-by-header:用于通知Ingress将请求路由到Canary Ingress中指定的服务的标头。当请求标头设置always为时,它将被路由到Canary。当标头设置never为时,它将永远不会被路由到Canary。对于任何其他值,将忽略标头,并通过优先级将请求与其他Canary规则进行比较。

nginx.ingress.kubernetes.io/canary-by-header-value:要匹配的标头值,用于通知Ingress将请求路由到Canary Ingress中指定的服务。当请求标头设置为此值时,它将被路由到Canary。对于任何其他标头值,标头将被忽略,并且请求与其他Canary规则的优先级进行比较。此注释必须与canary-by-header一起使用。nginx.ingress.kubernetes.io/canary-by-header注释允许自定义标头值而不是使用硬编码值的扩展。如果nginx.ingress.kubernetes.io/canary-by-header注释未定义,则没有任何效果。

例1:使用canary-by-header

代码语言:javascript
复制
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "new"
  labels:
    app: demo
  name: demo-ingress
  namespace: demo-canary
spec:
  rules:
  - host: canary.example.com
    http:
      paths:
      - backend:
          serviceName: demo-canary
          servicePort: 80
        path: /
---

上面这个示例,当你请求头加入new: always的时候就会访问demo-canary,当标头设置never为时,则不会访问。例如下面的这个curl

代码语言:javascript
复制
curl -s -H "new: always"  http://canary.example.com

下面这个示例使用的是自定义的标头值

例2:使用canary-by-header-value

代码语言:javascript
复制
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "new"
    nginx.ingress.kubernetes.io/canary-by-header-value:"xxx"
  labels:
    app: demo
  name: demo-ingress
  namespace: demo-canary
spec:
  rules:
  - host: canary.example.com
    http:
      paths:
      - backend:
          serviceName: demo-canary
          servicePort: 80
        path: /
---

使用如下请求可以正常访问demo-canary

代码语言:javascript
复制
curl -s -H "new: xxx" http://canary.example.com

基于Cookie的流量切分

nginx.ingress.kubernetes.io/canary-by-cookie:用于通知Ingress将请求路由到Canary Ingress中指定的服务的cookie。当cookie值设置always为时,它将被路由到Canary。当cookie被设置never为时,它将永远不会被路由到Canary。对于任何其他值,cookie将被加入,并且请求与其他Canary规则的优先级进行比较。

代码语言:javascript
复制
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-cookie: "use_under_30_feature"
  labels:
    app: demo
  name: demo-ingress
  namespace: demo-canary
spec:
  rules:
  - host: canary.example.com
    http:
      paths:
      - backend:
          serviceName: demo-canary
          servicePort: 80
        path: /
---

上面的这个示例,当cookie设置为use_under_30_feature为always的时候,则会访问demo-canary

基于服务权重的流量切分

nginx.ingress.kubernetes.io/canary-weight:将路由到金丝雀Ingress中指定的服务的随机请求的整数(0 - 100)百分比。权重为0意味着该Canary规则不会向Canary入口中的服务发送任何请求。权重为100意味着所有请求都将被发送到Ingress中指定的替代服务。示例如下(使用20%的权重):

代码语言:javascript
复制
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "20"
  labels:
    app: demo
  name: demo-ingress
  namespace: demo-canary
spec:
  rules:
  - host: canary.example.com
    http:
      paths:
      - backend:
          serviceName: demo-canary
          servicePort: 80
        path: /
---

注意这里权重不是一个精确的百分比,使用过程当中,只是会看到一个近似分布。

三种注释的优先级和注意点

上面的规则按优先顺序进行评估。优先顺序如下: canary-by-header -> canary-by-cookie -> canary-weight

注意:

当您将入口标记为canary时,除了nginx.ingress.kubernetes.io/load-balance和之外,所有其他非canary注释都将被忽略(从相应的主入口继承)nginx.ingress.kubernetes.io/upstream-hash-by

已知的限制 目前,每个Ingress规则最多可以应用一个canary入口。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 进击云原生 微信公众号,前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 发布场景
    • 场景一
      • 场景二
      • 注解说明
        • 基于Request Header的流量切分
          • 基于Cookie的流量切分
            • 基于服务权重的流量切分
              • 三种注释的优先级和注意点
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档