【云原生】| 作者/Edison Zhou

这是恰童鞋骚年的第236篇原创文章


上一篇介绍了Ingress的基本概念和Nginx Ingress的基本配置和使用,然后我还录了一个快速分享小视频介绍了一下蓝绿发布和灰度发布策略的基本概念,本篇介绍一下如何实战使用Nginx Ingress实现灰度发布(金丝雀发布)。

1一些准备工作

1.1 WebAPI项目准备

首先,我们还是准备两个版本的ASP.NET Core WebAPI项目,具体项目代码可以参考我的这篇Rolling Update的文章。

他们之间的差别在于一个接口的返回JSON数据,比如V1.0版本中返回的是Version: 1.0,而V1.1版本中返回的是Version:1.1。

[Route("api/[controller]")]
[ApiController]
public class HomeController : ControllerBase
{// GET api/home[HttpGet]public ActionResult<IEnumerable<string>> Get(){return new string[] {"Hello, welcome to EDC's demo. Version: 1.0"};}
}

运行结果为:

(2)将此项目各个版本根据Dockerfile打成镜像,分别是xilife/canary-api-demo:1.0,1.1。

(3)将本地镜像push到远程镜像仓库,这里我传送到了我在docker hub的一个公共仓库里边:

docker push xilife/canary-api-demo:1.0
docker push xilife/canary-api-demo:1.1

1.2 WebAPI项目部署

其次,我们将这两个WebAPI项目部署到K8s集群中,还是通过熟悉的yaml文件来将其部署为Service:

(1)V1.0版本(假设为线上版本)

apiVersion: apps/v1
kind: Deployment
metadata:name: canary-api-demonamespace: xdp-poclabels:name: canary-api-demo
spec:replicas: 2selector:matchLabels:name: canary-api-demotemplate:metadata:labels:name: canary-api-demospec:containers:- name: canary-api-demoimage: xilife/canary-api-demo:1.0ports:- containerPort: 80imagePullPolicy: IfNotPresent---kind: Service
apiVersion: v1
metadata:name: canary-api-svcnamespace: xdp-poc
spec:type: NodePortports:- port: 80targetPort: 80selector:name: canary-api-demo

(2)V1.1版本(假设为灰度版本)

apiVersion: apps/v1
kind: Deployment
metadata:name: canary-api-demo-graynamespace: xdp-poclabels:name: canary-api-demo-gray
spec:replicas: 2selector:matchLabels:name: canary-api-demo-graytemplate:metadata:labels:name: canary-api-demo-grayspec:containers:- name: canary-api-demo-grayimage: xilife/canary-api-demo:1.1ports:- containerPort: 80imagePullPolicy: IfNotPresent---kind: Service
apiVersion: v1
metadata:name: canary-api-svc-graynamespace: xdp-poc
spec:type: NodePortports:- port: 80targetPort: 80selector:name: canary-api-demo-gray

将这两个应用部署至K8s集群:

kubectl apply -f deploy-canary-api-svc.yml
kubectl apply -f deploy-canary-api-gray-svc.yml

2Ingress实现灰度发布

Ingress-Nginx 支持配置 Ingress Annotations 来实现不同场景下的灰度发布和测试,可以满足金丝雀发布、蓝绿部署与 A/B 测试等业务场景。

因此我们准备两个版本的Ingress的yml文件,它提供了两种方式:

一是基于用户请求的流量切分,具体又包括了基于Request Header的流量切分与基于Cookie的流量切分两种方式;如下图所示:

二是基于服务权重的流量切分;如下图所示:

2.1 基于Request Header的流量切分

根据Request Header的流量切分方式的约定,适用于灰度发布及A/B测试。当 Request Header 设置为 always时,请求将会被一直发送到 Canary 版本;当 Request Header 设置为 never时,请求不会被发送到 Canary 入口;对于任何其他 Header 值,将忽略 Header,并通过优先级将请求与其他金丝雀规则进行优先级的比较。

为1.0版本准备一个Ingress,让它先工作着:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:name: nginx-ingressnamespace: xdp-pocannotations:kubernetes.io/ingress.class: "nginx"nginx.ingress.kubernetes.io/rewrite-target: /api/$2
spec:rules:- host: portal.k8s.xi-life.cnhttp:paths:- path: /api(/|$)(.*)backend:serviceName: canary-api-svcservicePort: 80

应用至K8s集群:

kubectl apply -f ingress-nginx.yaml

再为1.1版本准备一个Ingress,让它作为灰度版本的入口逐步替换原v1版本的流量接入:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:name: nginx-ingress-graynamespace: xdp-pocannotations:kubernetes.io/ingress.class: "nginx"nginx.ingress.kubernetes.io/rewrite-target: /api/$2nginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-by-header: "canary"nginx.ingress.kubernetes.io/canary-by-header-value: "true"
spec:rules:- host: portal.k8s.xi-life.cnhttp:paths:- path: /api(/|$)(.*)backend:serviceName: canary-api-svc-grayservicePort: 80

应用至K8s集群:

kubectl apply -f ingress-nginx-gray.yaml

快速验证:

2.2 基于Cookie的流量切分

根据基于 Cookie 的流量切分方式的约定,当 Cookie 值设置为 always时,它将被路由到 Canary 入口;当 Cookie 值设置为 never时,请求不会被发送到 Canary 入口;对于任何其他值,将忽略 Cookie 并将请求与其他金丝雀规则进行优先级的比较。

为灰度版本准备Ingress:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:name: nginx-ingress-graynamespace: xdp-pocannotations:kubernetes.io/ingress.class: "nginx"nginx.ingress.kubernetes.io/proxy-body-size: "100m"nginx.ingress.kubernetes.io/limit-rps: '10'nginx.ingress.kubernetes.io/rewrite-target: /api/$2nginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-by-cookie: "xdp-v2-cookie"
spec:rules:- host: portal.k8s.xi-life.cnhttp:paths:- path: /api(/|$)(.*)backend:serviceName: canary-api-svc-grayservicePort: 80

应用至K8s集群:

kubectl apply -f ingress-nginx-gray.yaml

快速验证:

(1)未添加Cookie

(2)为要访问的域名添加一个Cookie

(3)再次请求验证

2.3 基于服务权重的流量切分

根据基于服务权重的流量切分方式的约定,适用于蓝绿部署,权重范围 0 - 100 按百分比将请求路由到 Canary Ingress 中指定的服务。权重为 0 意味着该金丝雀规则不会向 Canary 入口的服务发送任何请求。权重为 100 意味着所有请求都将被发送到 Canary 入口。

为灰度版本准备Ingress:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:name: nginx-ingress-graynamespace: xdp-pocannotations:kubernetes.io/ingress.class: "nginx"nginx.ingress.kubernetes.io/proxy-body-size: "100m"nginx.ingress.kubernetes.io/limit-rps: '10'nginx.ingress.kubernetes.io/rewrite-target: /api/$2nginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-weight: "50"
spec:rules:- host: portal.k8s.xi-life.cnhttp:paths:- path: /api(/|$)(.*)backend:serviceName: canary-api-svc-grayservicePort: 80

应用至K8s集群:

kubectl apply -f ingress-nginx-gray.yaml

快速验证:这里我直接通过浏览器来测试,需要注意的是这里的50%是一个近似分布值,可能实际中不会太精确。

2.4 三种方式的优先级

Nginx Ingress提供的三种灰度发布的方式的优先级顺序为:

canary-by-header -> canary-by-cookie -> canary-weight

对于Nginx Ingress的使用目前已知限制:

(1)Ingress-Nginx是在0.21.0版本中才引入的Canary功能,因此建议确保版本在0.22.0及之后(据说0.21.0版本的基于Cookie方式有点问题);

(2)目前每个Ingress规则中最多只能应用一个canary入口

3小结
本文介绍了Nginx Ingress提供的三种灰度发布(canary)的方式,然后介绍了如何使用Nginx Ingress并进行配置实现ASP.NET Core WebAPI应用服务的灰度发布实践,最后对比三种方式的优先级及限制,希望对你有所帮助。

4参考资料

JadePeng,《K8s基于Nginx Ingress实现灰度发布》

我的小碗汤,《Nginx Ingress实现灰度和金丝雀发布》

梁宽,《再也不采坑的K8s实战指南》

WangT,《K8s基于Nginx Ingress进行蓝绿部署/金丝雀发布》

linus.lin,《一文明白蓝绿部署、滚动部署、灰度发布、金丝雀发布》

往期精彩回顾

.NET Core on K8s学习系列文章目录

骚年快享:K8s下发布策略基本概念一览

基于Jenkins的开发测试全流程持续集成实践

基于Jenkins的ASP.NET Core持续集成实践

如果本文对你有用,

不妨点个“在看”/转发朋友圈

ASP.NET Core on K8s学习之旅(14)Ingress灰度发布相关推荐

  1. ASP.NET Core on K8s学习之旅(13)Ocelot API网关接入

    [云原生]| 作者/Edison Zhou 这是恰童鞋骚年的第232篇原创文章 上一篇介绍了Ingress的基本概念和Nginx Ingress的基本配置和使用,考虑到很多团队都在使用Ocelot作为 ...

  2. 文章目录 | .NET Core on K8s学习之旅 (更新至20200618)

    .NET Core on K8s学习之旅 更新记录: -- 20200511 增加Ingress & Nginx Ingress介绍 -- 20200515 增加Ocelot API网关集成示 ...

  3. ASP.NET Core on K8S学习初探(1)

    " [LOG] ASP.NET Core on K8S Starting..." 01 - 写在之前 当近期的一个App上线后,发现目前的docker实例(应用服务BFF+中台服务 ...

  4. ASP.NET Core on K8S学习初探(3)部署API到K8S

    " 终于可以部署ASP.NET Core到K8S中了..." 在上一篇<基本概念快速一览>中,我们把基本的一些概念快速地简单地不求甚解地过了一下,本篇开始我们会将ASP ...

  5. ASP.NET Core on K8S学习初探(2)

    " [LOG] ASP.NET Core on K8S Starting..." 在上一篇<单节点环境搭建>中,通过Docker for Windows在Windows ...

  6. ASP.NET Core on K8S深入学习(2)部署过程解析与部署Dashboard

    上一篇<K8S集群部署>中搭建好了一个最小化的K8S集群,这一篇我们来部署一个ASP.NET Core WebAPI项目来介绍一下整个部署过程的运行机制,然后部署一下Dashboard,完 ...

  7. ASP.NET Core on K8S深入学习(1)K8S基础知识与集群搭建

    在上一个小系列文章<ASP.NET Core on K8S学习初探>中,通过在Windows上通过Docker for Windows搭建了一个单节点的K8S环境,并初步尝试将ASP.NE ...

  8. .NET Core on K8S 学习与实践系列文章索引 (更新至20191126)

    更新记录: -- 2019-11-26 增加Docker容器日志系列文章 近期在学习Kubernetes,基于之前做笔记的习惯,已经写了一部分文章,因此给自己立一个flag:完成这个<.NET ...

  9. .NET Core on K8S学习实践系列文章索引(持续更新)

    近期在学习Kubernetes,基于之前做笔记的习惯,已经写了一部分文章,因此给自己立一个2019年的flag:完成这个<.NET Core on K8S学习实践>系列文章!这个系列会持续 ...

最新文章

  1. 一. synchronized 的局限性 与 Lock 的优点
  2. 【数字智能三篇】之三: 一页纸说清楚“什么是深度学习?”
  3. 平台积分体系设计方案
  4. wxWidgets:wxStdOutputStreamBuffer类用法
  5. 笔记本本地连接显示电缆拔出_没有安全电缆槽的笔记本电脑如何固定?
  6. 【渝粤题库】陕西师范大学164108 网络营销与策划 作业 (高起专)
  7. java usecompressedclasspointers_聊聊jvm的CompressedClassSpace
  8. 15 个第三方Web 表单资源
  9. Golang web filter 轻量级实现
  10. mysql query cache_MySQL Query Cache开启与否的必要性分析
  11. 【笔记1-4】陈丹琦毕业论文 NEURAL READING COMPREHENSION AND BEYOND
  12. 74HC595级联电路编程篇(三)
  13. scrapy爬虫实战教程
  14. 几个寓意深远的小故事
  15. 多級commentable處理
  16. Cindy Message/MessageRecognizer interface
  17. window10右下角 天气 关闭
  18. 汇编语言指令英文全称
  19. error: VNDK library: liblog‘s ABI has EXTENDING CHANGES Please check compatiblity report at
  20. BladeX——精心设计的微服务架构

热门文章

  1. 现在是2016-09-23,查询2个月后的月份和入职的月份相同的数据
  2. Chrome浏览器切换到之前打开的标签页会重新加载
  3. Technical User Stories – What, When, and How?
  4. wxGlade的图标,原来是来自蒙德里安的名画!
  5. webservice发布
  6. 【转】sqlserver游标概念与实例全面解说
  7. UI设计师应了解最终用户的十件事
  8. static_cast、dynamic_cast、reinterpret_cast、const_cast[转]
  9. tomcat学习笔记(JDK+TOMCAT+AXIS)
  10. 如何在Windows上设置BitLocker加密