点击上方“分布式实验室”关注公众号

回复“1”抽取技术书

Ingress基于七层的HTTP和HTTPS协议进行转发,可以通过域名和路径对访问做到更细粒度的划分。Ingress作为Kubernetes集群中一种独立的资源,需要通过创建它来制定外部访问流量的转发规则,并通过Ingress Controller将其分配到一个或多个Service中。Ingress Controller在不同厂商之间有着不同的实现方式,Kubernetes官方维护的Controller为Nginx Ingress。Nginx Ingress支持通过配置注解(Annotations)来实现不同场景下的发布和测试,可以满足灰度发布、蓝绿发布、A/B测试等业务场景。本文将介绍使用Nginx Ingress实现灰度发布和蓝绿发布的应用场景、用法详解及实践步骤。


 1 

应用场景

使用Nginx Ingress实现灰度发布适用场景主要取决于业务流量切分的策略,目前Nginx Ingress支持基于Header、Cookie和服务权重三种流量切分的策略,基于这三种策略可实现以下两种发布场景:

场景一:切分部分用户流量到新版本

假设线上已运行了一套对外提供七层服务的Service A,此时开发了一些新的特性,需要发布上线一个新的版本Service A',但又不想直接替换原有的Service A,而是期望将Header中包含foo=bar或者Cookie中包含foo=bar的用户请求转发到新版本Service A'中。待运行一段时间稳定后,再逐步全量上线新版本,平滑下线旧版本。示意图如下:

场景二:切分一定比例的流量到新版本

假设线上已运行了一套对外提供七层服务的Service B,此时修复了一些问题,需要发布上线一个新的版本Service B',但又不想直接替换原有的Service B,而是期望将20%的流量切换到新版本Service B'中。待运行一段时间稳定后,再将所有的流量从旧版本切换到新版本中,平滑下线旧版本。


 2 

注解说明

Nginx Ingress支持通过配置注解(Annotations)来实现不同场景下的发布和测试,可以满足灰度发布、蓝绿发布、A/B测试等业务场景。具体实现过程如下:为服务创建两个Ingress,一个为常规Ingress,另一个为带nginx.ingress.kubernetes.io/canary: "true"注解的Ingress,称为Canary Ingress;为Canary Ingress配置流量切分策略Annotation,两个Ingress相互配合,即可实现多种场景的发布和测试。Nginx Ingress的Annotation支持以下几种规则:

  • nginx.ingress.kubernetes.io/canary-by-header,基1于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-pattern,与8canary-by-header-value类似,唯一区别是该annotation用正则表达式匹配请求头的值,而不是某一个固定值。如果该annotation与canary-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对应的后端服务。


 3 

操作说明

1、文中的Kubernetes集群为华为云CCE所提供,与之关联的其他云服务也均来自华为云。

2、准备工作:

  • 使用Nginx Ingress实现灰度发布的集群,需安装nginx-ingress插件作为Ingress Controller,并且对外暴露统一的流量入口。

  • 已上传Nginx镜像至容器镜像服务。为方便观测流量切分效果,Nginx镜像包含新旧两个版本,欢迎页分别为“Old Nginx”和“New Nginx”。

3、资源创建方式说明:本文提供以下两种方式使用YAML部署Deployment和Service:

  • 方式1:在控制台创建无状态工作负载向导页面,单击右侧“YAML创建”,再将本文示例的YAML文件内容输入编辑窗中。

  • 方式2:将本文的示例YAML保存为文件,再使用kubectl指定YAML文件进行创建。例如:kubectl create -f xxx.yaml。


 4 

部署两个版本的服务

在集群中部署两个版本的Nginx服务,并通过Nginx Ingress对外提供七层域名访问。

步骤1:创建第一个版本的Deployment和Service,本文以old-nginx为例。YAML示例如下:

apiVersion: apps/v1
kind: Deployment
metadata: name: old-nginx
spec: replicas: 2 selector: matchLabels: app: old-nginx template: metadata: labels: app: old-nginx spec: containers: - image: swr.cn-east-3.myhuaweicloud.com/hwfstaff_pub_cbuinfo/nginx:old    # 容器使用的镜像为:nginx:old name: container-0 resources: limits: cpu: 100m memory: 200Mi requests: cpu: 100m memory: 200Mi imagePullSecrets: - name: default-secret --- apiVersion: v1
kind: Service
metadata: name: old-nginx
spec: selector: app: old-nginx ports: - name: service0 targetPort: 80 port: 8080 protocol: TCP type: NodePort

步骤2:创建第二个版本的Deployment和Service,本文以new-nginx为例。YAML示例如下:

apiVersion: apps/v1
kind: Deployment
metadata: name: new-nginx
spec: replicas: 2 selector: matchLabels: app: new-nginx template: metadata: labels: app: new-nginx spec: containers: - image: swr.cn-east-3.myhuaweicloud.com/hwfstaff_pub_cbuinfo/nginx:new    # 容器使用的镜像为:nginx:new name: container-0 resources: limits: cpu: 100m memory: 200Mi requests: cpu: 100m memory: 200Mi imagePullSecrets: - name: default-secret --- apiVersion: v1
kind: Service
metadata: name: new-nginx
spec: selector: app: new-nginx ports: - name: service0 targetPort: 80 port: 8080 protocol: TCP type: NodePort

你可以登录云容器引擎控制台,在“工作负载 > 无状态负载 Deployment”页面查看部署情况。

步骤3:创建Ingress,对外暴露服务,指向old版本的服务。YAML示例如下:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata: name: gray-release namespace: default annotations: kubernetes.io/ingress.class: nginx    # 使用Nginx型Ingress kubernetes.io/elb.port: '80'
spec: rules: - host: www.example.com http: paths: - path: '/' backend: serviceName: old-nginx      # 指定后端服务为old-nginx servicePort: 80

执行以下命令,进行访问验证。

curl -H "Host: www.example.com"  http://<EXTERNAL_IP>

其中,为Nginx Ingress对外暴露的IP。

预期输出:

Old Nginx


 5 

灰度发布新版本服务

设置访问新版本服务的流量切分策略。云容器引擎CCE支持设置基于Header、Cookie和服务权重三种策略,来实现灰度发布和蓝绿发布,你可以根据实际情况进行选择:

基于Header、Cookie和服务权重三种流量切分策略均可实现灰度发布;基于服务权重的流量切分策略,调整新服务权重为100%,即可实现蓝绿发布。你可以在下述示例中了解具体使用方法。

基于Header的流量切分

以下示例仅Header中包含Region且值为bj或gz的请求才能转发到新版本服务,模拟灰度新版本给北京和广州地域的用户。

创建Canary Ingress,指向新版本的后端服务,并增加annotation。

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata: name: canary-ingress namespace: default annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true"                       # 启用Canary nginx.ingress.kubernetes.io/canary-by-header: "Region" nginx.ingress.kubernetes.io/canary-by-header-pattern: "bj|gz"    # Header中包含Region且值为bj或gz的请求转发到Canary Ingress kubernetes.io/elb.port: '80'
spec: rules: - host: www.example.com http: paths: - path: '/' backend: serviceName: new-nginx      # 指定后端服务为new-nginx servicePort: 80

执行以下命令,进行访问测试。

$ curl -H "Host: www.example.com" -H "Region: bj" http://<EXTERNAL_IP>
New Nginx
$ curl -H "Host: www.example.com" -H "Region: sh" http://<EXTERNAL_IP>
Old Nginx
$ curl -H "Host: www.example.com" -H "Region: gz" http://<EXTERNAL_IP>
New Nginx
$ curl -H "Host: www.example.com" http://<EXTERNAL_IP>
Old Nginx

其中,为Nginx Ingress对外暴露的IP。

可以看出,仅当Header中包含Region且值为bj或gz的请求才由新版本服务响应。

基于Cookie的流量切分

以下示例仅Cookie中包含user_from_bj的请求才能转发到新版本服务,模拟灰度新版本给北京地域的用户。

创建Canary Ingress,指向新版本的后端服务,并增加annotation。

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata: name: canary-ingress namespace: default annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true"                      # 启用Canary nginx.ingress.kubernetes.io/canary-by-cookie: "user_from_bj"    # Cookie中包含user_from_bj的请求转发到Canary Ingress kubernetes.io/elb.port: '80'
spec: rules: - host: www.example.com http: paths: - path: '/' backend: serviceName: new-nginx      # 指定后端服务为new-nginx servicePort: 80

执行以下命令,进行访问测试。

$ curl -s -H "Host: www.example.com" --cookie "user_from_bj=always" http://<EXTERNAL_IP>
New Nginx
$ curl -s -H "Host: www.example.com" --cookie "user_from_gz=always" http://<EXTERNAL_IP>
Old Nginx
$ curl -s -H "Host: www.example.com" http://<EXTERNAL_IP>
Old Nginx

其中,为Nginx Ingress对外暴露的IP。

可以看出,仅当Cookie中包含user_from_bj且值为always的请求才由新版本服务响应。

基于服务权重的流量切分

示例1:仅允许20%的流量被转发到新版本服务中,实现灰度发布。

创建Canary Ingress,并增加annotation,将20%的流量导入新版本的后端服务。

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata: name: canary-ingress namespace: default annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true"         # 启用Canary nginx.ingress.kubernetes.io/canary-weight: "20"    # 将20%的流量转发到Canary Ingress kubernetes.io/elb.port: '80'
spec: rules: - host: www.example.com http: paths: - path: '/' backend: serviceName: new-nginx      # 指定后端服务为new-nginx servicePort: 80

执行以下命令,进行访问测试。

$ for i in {1..20}; do curl -H "Host: www.example.com" http://<EXTERNAL_IP>; done;
Old Nginx
Old Nginx
Old Nginx
New Nginx
Old Nginx
New Nginx
Old Nginx
New Nginx
Old Nginx
Old Nginx
Old Nginx
Old Nginx
Old Nginx
New Nginx
Old Nginx
Old Nginx
Old Nginx
Old Nginx
Old Nginx
Old Nginx

其中,为Nginx Ingress对外暴露的IP。

可以看出,有4/20的几率由新版本服务响应,符合20%服务权重的设置。

示例2:允许所有的流量被转发到新版本服务中,实现蓝绿发布。

创建Canary Ingress,并增加annotation,将100%的流量导入新版本的后端服务。

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata: name: canary-ingress namespace: default annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true"          # 启用Canary nginx.ingress.kubernetes.io/canary-weight: "100"    # 所有流量均转发到Canary Ingress kubernetes.io/elb.port: '80'
spec: rules: - host: www.example.com http: paths: - path: '/' backend: serviceName: new-nginx      # 指定后端服务为new-nginx servicePort: 80

执行以下命令,进行访问测试。

$ for i in {1..10}; do curl -H "Host: www.example.com" http://<EXTERNAL_IP>; done;
New Nginx
New Nginx
New Nginx
New Nginx
New Nginx
New Nginx
New Nginx
New Nginx
New Nginx
New Nginx

其中,为Nginx Ingress对外暴露的IP。

可以看出,所有的访问均由新版本服务响应,成功实现了蓝绿发布。

文章来源:容器魔方

推荐阅读:《彻底搞懂Nginx的五大应用场景》


点击下方卡片关注分布式实验室,和我们一起

关注分布式最佳实践

 点击上方卡片关注分布式实验室,掌握前沿分布式技术

长按识别下方二维码,了解培训主题。

如何使用Nginx Ingress实现灰度发布和蓝绿发布?相关推荐

  1. k8s 使用Nginx Ingress实现灰度发布和蓝绿发布

    **导语:**云原生最佳实践系列,涵盖了灰度发布.弹性伸缩.集群迁移.网络通信.应用容器化改造等等场景,针对各行业面临的应用现状,提出最佳解决方案,并提供详细操作指导,希望对您有所帮助. Ingres ...

  2. 灰度发布与滚动发布、蓝绿发布介绍

    文章目录 灰度发布与滚动发布.蓝绿发布介绍 一.灰度发布与滚动发布.蓝绿发布介绍 1.蓝绿部署 2.滚动发布 3.灰度发布 二.灰度发布好处 三.Gitee上高热度的开源灰度发布系统 四.安装使用 灰 ...

  3. k8s_deployment 以及灰度发布、滚动发布和蓝绿发布的零散笔记

    deployment 可以简写为deploy Deployment 相比与replicaSet 多出一些功能设定. Deployment VS replicaSet PS: 对比版本 1.18.0 项 ...

  4. 一文看懂ingress nginx实现灰度发布和蓝绿发布过程

    背景信息 灰度及蓝绿发布是为新版本创建一个与老版本完全一致的生产环境,在不影响老版本的前提下,按照一定的规则把部分流量切换到新版本,当新版本试运行一段时间没有问题后,将用户的全量流量从老版本迁移至新版 ...

  5. CI/CD发布方式-蓝绿发布、灰度发布和滚动发布

    发布方式 应用程序升级面临最大挑战是新旧业务切换,将软件从测试的最后阶段带到生产环境,同时要保证系统不间断提供服务.长期以来,业务升级渐渐形成了几个发布策略:蓝绿发布.灰度发布和滚动发布,目的是尽可能 ...

  6. k8s之滚动更新、金丝雀发布、蓝绿发布

    k8s Pod三种升级方式 哪几种发布方式 滚动更新 金丝雀发布 蓝绿发布 演示时间 滚动更新 金丝雀发布 蓝绿发布 哪几种发布方式 滚动更新 滚动更新通过设置MaxSurge和MaxUnavaila ...

  7. k8s 应用更新策略:灰度发布和蓝绿发布

    生产环境如何实现蓝绿部署? 什么是蓝绿部署? 蓝绿部署中,一共有两套系统:一套是正在提供服务系统,标记为"绿色":另一套是准备发布的系统,标记为"蓝色".两套系 ...

  8. 灰度(金丝雀)发布、蓝绿部署、滚动发布

    概念 一.灰度(金丝雀)发布 定义 灰度发布又叫金丝雀发布,只升级部分服务,即让一部分用户继续用老版本,一部分用户开始用新版本,如果用户对新版本没什么意见,那么逐步扩大范围,把所有用户都迁移到新版本上 ...

  9. 掌门1对1微服务体系Solar第1弹:全链路灰度蓝绿发布智能化实践

    掌门教育自2014年正式转型在线教育以来,秉承"让教育共享智能,让学习高效快乐"的宗旨和愿景,经历云计算.大数据.人工智能.AR/VR/MR以及现今最火的5G,一直坚持用科技赋能教 ...

  10. K8S的灰度发布、滚动更新、蓝绿发布

    K8S灰度发布.蓝绿发布.滚动更新 一.简介 1.1灰度发布(金丝雀发布) 金丝雀发布一般是先发1台机器,或者一个小比例,例如2%的服务器,主要做流量验证用,也称为金丝雀 (Canary) 测试,国内 ...

最新文章

  1. java list_Java集合-List
  2. C# 中泛型与非泛型?(摘)
  3. hystrix源码小贴士之Yammer Publisher
  4. BZOJ 2442: [Usaco2011 Open]修剪草坪 单调队列
  5. Svcutil.exe详解
  6. Ubuntu20.04 NAT 网络配置
  7. python 伪多线程_Python实现简单多线程任务队列
  8. 【设计素材】表格数据形平面海报素材
  9. C# 中的委托和事件 (转)
  10. 相机姿态估计(六)--EPnP
  11. 数据分析中数据概览神器pandas_profiling介绍
  12. QTouch Linux 组态软件
  13. C++ 什么是句柄?为什么会有句柄?HANDLE
  14. Redhat Crash Utility-Ramdump
  15. Activemq优点和缺点
  16. 早间简评:黄金亚盘快速下跌   1300关口岌岌可危?
  17. PAT 1037 在霍沃茨找零钱
  18. Oracle 服务器 客户端 US7ASCII、 UTF8字符编码问题
  19. 学习笔记之MOOC《计算机程序设计C++》第5周编程作业
  20. 互联网晚报 | 1月8日 星期六 | 小米商城已支持数字人民币支付;微信视频号将上线付费直播间;苹果CEO去年薪酬近1亿美元...

热门文章

  1. SVN更新报the working copy needs to be upgraded解决办法
  2. 权威的PHP 5.6、7.0、7.1、7.2、7.3和7.4 php运行效率基准测试
  3. C++ WA, 超时,爆栈错误总结
  4. websphere7 mysql_websphere7
  5. 0xl c语言中003是整形常量,整型常量
  6. 影响力最大化 RIS 反向影响力采样算法
  7. 到底如何理解文本?一文读懂命名实体识别(实体消歧和实体统一)
  8. Python爬虫实战--小猪短租爬虫
  9. pandas_day08
  10. 【seeprettyface.com】开源源码:Video-Auto-Wipe