当前位置:首页 > 技术文章 > 正文内容

.NET Core on K8s学习之旅:Ingress灰度发布

arlanguage3个月前 (01-31)技术文章30

上一篇介绍了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> 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-demo
  namespace: xdp-poc
  labels:
    name: canary-api-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      name: canary-api-demo
  template:
    metadata:
      labels:
        name: canary-api-demo
    spec:
      containers:
      - name: canary-api-demo
        image: xilife/canary-api-demo:1.0
        ports:
        - containerPort: 80
        imagePullPolicy: IfNotPresent

---

kind: Service
apiVersion: v1
metadata:
  name: canary-api-svc
  namespace: xdp-poc
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
  selector:
    name: canary-api-demo

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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: canary-api-demo-gray
  namespace: xdp-poc
  labels:
    name: canary-api-demo-gray
spec:
  replicas: 2
  selector:
    matchLabels:
      name: canary-api-demo-gray
  template:
    metadata:
      labels:
        name: canary-api-demo-gray
    spec:
      containers:
      - name: canary-api-demo-gray
        image: xilife/canary-api-demo:1.1
        ports:
        - containerPort: 80
        imagePullPolicy: IfNotPresent

---

kind: Service
apiVersion: v1
metadata:
  name: canary-api-svc-gray
  namespace: xdp-poc
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
  selector:
    name: canary-api-demo-gray

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

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

2 Ingress实现灰度发布

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-ingress
  namespace: xdp-poc
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /api/$2
spec:
  rules:
  - host: portal.k8s.xi-life.cn
    http:
      paths:
      - path: /api(/|$)(.*)
        backend:
          serviceName: canary-api-svc
          servicePort: 80

应用至K8s集群:

kubectl apply -f ingress-nginx.yaml

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

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress-gray
  namespace: xdp-poc
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /api/$2
    nginx.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.cn
    http:
      paths:
      - path: /api(/|$)(.*)
        backend:
          serviceName: canary-api-svc-gray
          servicePort: 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-gray
  namespace: xdp-poc
  annotations:
    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/$2
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-cookie: "xdp-v2-cookie"
spec:
  rules:
  - host: portal.k8s.xi-life.cn
    http:
      paths:
      - path: /api(/|$)(.*)
        backend:
          serviceName: canary-api-svc-gray
          servicePort: 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-gray
  namespace: xdp-poc
  annotations:
    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/$2
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "50"
spec:
  rules:
  - host: portal.k8s.xi-life.cn
    http:
      paths:
      - path: /api(/|$)(.*)
        backend:
          serviceName: canary-api-svc-gray
          servicePort: 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,《一文明白蓝绿部署、滚动部署、灰度发布、金丝雀发布》


本文作者EdisonZhou,架构师,阿里云MVP,博客园"推荐博客"博主,Scrum联盟认证CSM,爱好阅读与分享。

本文首发于EdisonZhou的公众号“恰童鞋骚年”,欢迎关注,第一时间获得更多内容分享。

点击“了解更多”,获取更多分享!

扫描二维码推送至手机访问。

版权声明:本文由AR编程网发布,如需转载请注明出处。

本文链接:http://www.arlanguage.com/post/1524.html

标签: nginx asp.net
分享给朋友:

“.NET Core on K8s学习之旅:Ingress灰度发布” 的相关文章

5分钟搞懂nginx的location匹配规则

目录概述location介绍location指令语法location配置实例解析location常用场景实战禁止访问.sh后缀的文件实例php7进阶到架构师相关阅读概述这是关于php进阶到架构之Nginx进阶学习的第一篇文章:5分钟搞懂nginx的location匹配规则第一篇:5分钟搞懂nginx...

基于一次ContentDownload变慢而进行的网站性能优化

平时运行无常的网站,突然出现了某个接口TTFB缓慢问题,于是乎开始定位和解决,先说明一下网站的技术栈: 编程语言:PHP、Javascript、Vue、Java 开发框架:Laravel、SpringBoot 中间件:Redis、Kafka、Nginx 数据库:Mysql、MongoDB 云服务:腾...

终于有人把Docker讲清楚了,Docker入门教程,原来这么简单...

Docker是一个使用Go语言开发的开源的应用容器引擎,让开发者可以打包他们的应用以及依赖到一个可移植的容器中,然后发布到任何流行的机器上。Docker的迅猛发展和全新理念,席卷了整个IT界,成为云时代的一颗新星。Docker的优势Docker相比于传统虚拟化方式具有更多的优势:docker启动快速...

配置nginx代理grafana实现域名访问

目的:通过Nginx服务器对grafana进行代理,实现通过https://域名/grafana在公网进行访问实践过程:1、修改Nginx配置(nginx.conf)文件,添加访问grafana的配置,配置时注意proxy_pass后面一定要有符号 /(目的是去掉/grafana/以匹配本身)vi...

Nginx中的root和alias指令该如何使用?

Nginx是一款流行的Web服务器软件,常被用于反向代理。在Nginx的配置文件中,经常用到root和alias指令,这两个指令有什么区别。下面是一个具体的示例,配置文件如下:server { listen 80; server_name www.aneirin.xyz;...

Nginx配置虚拟主机的三种方式

欢迎来到蓝队云小课堂,每天分享一个技术小知识。Nginx配置虚拟主机,是实际应用中最基础的操作。比如你有几台服务器都放的是展示型的网站,现在为了节省成本,想要将多个网站放到同一台服务器上,就可以考虑用Nginx配置虚拟主机。我们可以运用Nginx把一台运行在因特网上的服务器主机分成一台台 “虚拟”...