ASP.NET Core on K8S深入学习(14)Ingress灰度发布

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

本篇已加入《.NET Core on K8S学习实践系列文章索引》,可以点击查看更多容器化技术相关系列文章。

之前一篇介绍了Ingress的基本概念和Nginx Ingress的基本配置和使用,本篇继续Ingress的使用,来看看如何使用Ingress实现灰度发布(金丝雀发布)。

一、准备工作

1.1 WebAPI项目准备

首先,我们还是准备两个版本的ASP.NET Core WebAPI项目,具体项目代码参见这里

他们之间的差别在于一个接口的返回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"
            };
        }
    }
AI 代码解读

运行结果为:

(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
AI 代码解读

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
AI 代码解读

(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
AI 代码解读

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

kubectl apply -f deploy-canary-api-svc.yml
kubectl apply -f deploy-canary-api-gray-svc.yml
AI 代码解读

二、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
AI 代码解读

应用至K8s集群:

kubectl apply -f ingress-nginx.yaml
AI 代码解读

再为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
AI 代码解读

应用至K8s集群:

kubectl apply -f ingress-nginx.yaml
AI 代码解读

快速验证:

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
AI 代码解读

应用至K8s集群:

kubectl apply -f ingress-nginx-gray.yaml
AI 代码解读

快速验证:

(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
AI 代码解读

应用至K8s集群:

kubectl apply -f ingress-nginx-gray.yaml
AI 代码解读

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

三、三种方式的对比

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

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

已知限制:

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

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

四、小结

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

此外,我也有录制一个10min+的小视频介绍蓝绿发布和金丝雀发布的基本概念,视频入口点击这里

参考资料

(1)JadePeng,《K8s基于Nginx Ingress实现灰度发布

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

(3)梁宽,《再也不踩坑的K8s实战指南

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

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

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
打赏
0
0
0
0
36
分享
相关文章
简化 ASP.NET Core 依赖注入(DI)注册-Scrutor
Scrutor 是一个简化 ASP.NET Core 应用程序中依赖注入(DI)注册过程的开源库,支持自动扫描和注册服务。通过简单的配置,开发者可以轻松地从指定程序集中筛选、注册服务,并设置其生命周期,同时支持服务装饰等高级功能。适用于大型项目,提高代码的可维护性和简洁性。仓库地址:&lt;https://github.com/khellang/Scrutor&gt;
77 5
C#/.NET/.NET Core学习路线集合,学习不迷路!
C#/.NET/.NET Core学习路线集合,学习不迷路!
228 0
k8s学习
【10月更文挑战第1天】
173 4
ASP.NET Core 中的速率限制中间件
在ASP.NET Core中,速率限制中间件用于控制客户端请求速率,防止服务器过载并提高安全性。通过`AddRateLimiter`注册服务,并配置不同策略如固定窗口、滑动窗口、令牌桶和并发限制。这些策略可在全局、控制器或动作级别应用,支持自定义响应处理。使用中间件`UseRateLimiter`启用限流功能,并可通过属性禁用特定控制器或动作的限流。这有助于有效保护API免受滥用和过载。 欢迎关注我的公众号:Net分享 (239字符)
75 1
Kubernetes Ingress:灵活的集群外部网络访问的利器
《Kubernetes Ingress:集群外部访问的利器-打造灵活的集群网络》介绍了如何通过Ingress实现Kubernetes集群的外部访问。前提条件是已拥有Kubernetes集群并安装了kubectl工具。文章详细讲解了Ingress的基本组成(Ingress Controller和资源对象),选择合适的版本,以及具体的安装步骤,如下载配置文件、部署Nginx Ingress Controller等。此外,还提供了常见问题的解决方案,例如镜像下载失败的应对措施。最后,通过部署示例应用展示了Ingress的实际使用方法。
103 2
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
80 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
GraphQL 与 ASP.NET Core 集成:从入门到精通
本文详细介绍了如何在ASP.NET Core中集成GraphQL,包括安装必要的NuGet包、创建GraphQL Schema、配置GraphQL服务等步骤。同时,文章还探讨了常见问题及其解决方法,如处理复杂查询、错误处理、性能优化和实现认证授权等,旨在帮助开发者构建灵活且高效的API。
70 3
开源且实用的C#/.NET编程技巧练习宝库(学习,工作,实践干货)
开源且实用的C#/.NET编程技巧练习宝库(学习,工作,实践干货)
350 0

热门文章

最新文章

推荐镜像

更多
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等