渐进式交付是持续交付的下一步, 它将新版本部署到用户的一个子集,并在将其滚动到全部用户之前对其正确性和性能进行评估, 如果不匹配某些关键指标,则进行回滚。
  
  这里有一些有趣的项目,使得渐进式交付在 Kubernetes 中变得更简单。 我将使用一个 Jenkins X 示例项目 对它们之中的三个进行讨论:Shipper、Istio 以及 Flagger。
  
  Shipper
  
  shipper 是来自 booking.com 的一个项目, 它对 Kubernetes 进行了扩展,添加了复杂的部署策略和多集群编排(文档)。 它支持从一个集群到多个集群的部署,允许多区域部署。
  
  Shipper 通过一个 shipperctl 命令行进行安装。 它增加不同集群的配置文件来进行管理。 请注意这个与 GKE 上下文相关的问题。
  
  Shipper 使用 Helm 包来部署,但是它们没有随着 Helm 一起安装,它们不会在 helm list 的输出显示。 同样地,deployments 的版本必须是 apps/v1 , 否则 shipper 将不能编辑 deployment 来添加正确的标签和副本数量。
  
  使用 shipper 部署都是与从旧版本(现有版本)过渡到新版本(竞争版本)相关。 这是通过创建一个新的应用对象实现的, 它定义了部署需要通过的多个阶段。例如下面 3 个步骤过程:
  
  Staging:部署新版本到一个 pod ,没有流量
  
  50 / 50:部署新版本到 50% 的 pods,50% 的流量
  
  Full on:部署新版本到全部的 pods,全部的流量
  
  strategy:
  
  steps:
  
  - name: staging
  
  capacity:
  
  contender: 1
  
  incumbent: 100
  
  traffic:
  
  contender: 0
  
  incumbent: 100
  
  - name: 50/50
  
  capacity:
  
  contender: 50
  
  incumbent: 50
  
  traffic:
  
  contender: 50
  
  incumbent: 50
  
  - name: full on
  
  capacity:
  
  contender: 100
  
  incumbent: 0
  
  traffic:
  
  contender: 100
  
  incumbent: 0
  
  如果发布的某个步骤没有将流量发送到 pods , 则可以使用 kubectl port-forward 访问它们,如:kubectl port-forward mypod 8080:8080, 这对于在用户看到新版本之前进行测试非常有用。
  
  Shipper 支持多集群的概念,但是以相同的方式对待所有集群,仅使用区域并通过 capabilities (配置在集群对象中)进行筛选, 所有对一个应用对象来说,这里没有一个 dev, staging, prod 集群的选项。 但是我们可以有两个应用对象:
  
  myapp-staging 部署到 "staging" 区域
  
  myapp 部署到其它区域
  
  在 GKE 中,你可以轻松地配置多集群 ingress , 该入口将公开在多个集群中运行的服务,并从离你所在位置最近的集群提供服务。
  
  局限性
  
  Shipper 中的主要的局限性有:
  
  Chart 限制:Chart 必须有一个部署对象。 Deployment 的名称必须使用 {{.Release.Name}} 模板化。 Deployment 对象应该有 apiVersion:apps/v1 。
  
  基于 Pod 的流量切换:这里没有细粒度的流量路由,例如:发送 1% 的流量到新版本,它基于正在运行的 Pod 数量。
  
  如果 Shipper 不工作了,新的 Pod 将获取不到流量。
  
  Istio
  
  Istio 不是一个部署工具,而是一个服务网格。 然而,它很令人感兴趣,因为它已经变得非常流行,并且允许流量管理,例如,将一定比例的流量发送到不同的服务和其他高级网络。
  
  在 GKE 中,只需在集群配置中选中复选框即可启用 Istio 。 在其它集群中,可以通过 Helm 手动安装。
  
  有了 Istio ,我们可以创建一个网关,通过 Ingress 网关处理所有外部流量,并创建虚拟服务来管理到我们服务的路由。 为此,只需找到 ingress 网关的 ip 地址并为其配置通配符 DNS 。 然后创建一个网关,通过 Ingress 网关路由所有外部流量。
  
  apiVersion: networking.istio.io/v1alpha3
  
  kind: Gateway
  
  metadata:
  
  name: public-gateway
  
  namespace: istio-system
  
  spec:
  
  selector:
  
  istio: ingressgateway
  
  servers:
  
  - port:
  
  number: 80
  
  name: http
  
  protocol: HTTP
  
  hosts:
  
  - "*"
  
  Isito 不管理应用的生命周期,只管理网络。 我们可以创建一个虚拟服务,为所有进入 ingress 网关的请求 向 pull request 或 master 分支中部署的服务发送 1% 的流量。
  
  apiVersion: networking.istio.io/v1alpha3
  
  kind: VirtualService
  
  metadata:
  
  name: croc-hunter-jenkinsx
  
  namespace: jx-production
  
  spec:
  
  gateways:
  
  - public-gateway.istio-system.svc.cluster.local
  
  - mesh
  
  hosts:
  
  - croc-hunter.istio.example.org
  
  http:
  
  - route:
  
  - destination:
  
  host: croc-hunter-jenkinsx.jx-production.svc.cluster.local
  
  port:
  
  number: 80
  
  weight: 99
  
  - destination:
  
  host: croc-hunter-www.tianscpt.com jenkinsx.jx-staging.svc.cluster.local
  
  port:
  
  number: 80
  
  weight: 1
  
  Flagger
  
  Flagger 是一个由 Weaveworks 赞助的使用了 Istio 的项目, 该项目使用 Prometheus 的指标进行自动化金丝雀发布和回滚。 它超越了 Isito 提供了基于指标的自动化渐进式发布和回滚。
  
  Flager 需要将 Istio与 Prometheus、Servicegraph 和某些系统的配置一起安装, 另外还要安装 Flager 控制器本身。 它也提供了一个 Grfana 面板来监控部署进度。
  
  部署 rollout 通过 Canary 对象定义, 它会生成主要的和金丝雀 Deployment 对象。 编辑 Deployment 时,例如要使用新的镜像版本, Flagger 控制器将负载从 0% 切换到 50% ,每分钟增加 10% ,然后它将切换到新的 deployment 或者如果响应错误和请求持续时间等指标失败则进行回滚。
  
  比较
  
  此表总结了 Shipper 和 Flagger 在几个渐进式交付特性方面的优势和劣势。
  
  Shipper Flagger
  
  流量路由 k8s 原生的按 Pods 的百分比进行均衡 基于 Istio 的高级流量路由(请求的百分比)
  
  部署进度 UI 无 Grafana 面板
  
  支持的 Deployments 具有较强限制的 Helm charts 任何 Deployment
  
  多集群部署 是 否
  
  在不同命名空间(如 jx-staging 和 jx-production )的金丝雀部署或蓝绿部署 否 否,但是要做到它可以手动编辑虚拟服务
  
  在不同集群的金丝雀部署或蓝绿部署 是,但是有点极客,使用一个新应用并将它链接到新区域 也许可以使用 Istio 多集群?
  
  自动部署 否,操作者必须手动完成这些步骤 是,每分钟增加 10% 的流量,可配置的
  
  自动回滚 否,操作者必须发现错误并手动完成这些步骤 是,基于 Prometheus 指标
  
  必需品 无 Istio,Prometheus
  
  public void run() {
  
  boolean periodic = isPeriodic(); // 是否为周期任务,period != 0
  
  if (!canRunInCurrentRunState(periodic)) // 当前状态能否继续运行,详细测试后面还会讲到
  
  cancel(false); // 取消任务
  
  else if (!periodic) // 不是周期任务时,直接运行
  
  ScheduledFutureTask.super.run();
  
  else if (ScheduledFutureTask.super.runAndReset()) { // 时周期任务
  
  setNextRunTime(); // 设置下次执行时间
  
  reExecutePeriodic(outerTask); // 重新入队
  
  }
  
  }
  
  public boolean cancel(boolean mayInterruptIfRunning) {
  
  boolean cancelled = super.cancel(mayInterruptIfRunning); // 设置中断状态
  
  if (cancelled && removeOnCancel && heapIndex >= 0) // 当设置 removeOnCancel 状态时,移除任务
  
  remove(this); // 默认为 false
  
  return cancelled;
  
  }
  
  void reExecutePeriodic(www.enzuoylp.com RunnableScheduledFuture<?> task) {
  
  if (canRunInCurrentRunState(true)) { // 如果当前状态可以执行
  
  super.getQueue().add(task); // 则重新入队
  
  if (!canRunInCurrentRunState(true) && remove(task))
  
  task.cancel(false);
  
  else ensurePrestart(); // 确保有线程执行任务
  
  }
  
  }
  
  此外还有 DelayedWorkQueue,但是这里不准备讲了,可以查看 完全二叉堆 了解实现的原理;
  
  二、scheduleAtFixedRate 与 scheduleWithFixedDelay
  
  scheduleAtFixedRate 和 scheduleWithFixedDelay 是我们最常用的两个方法,但是他们的区别可能不是很清楚,这里重点讲一下,
  
  1. scheduleAtFixedRate
  
  // 测试
  
  ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(1);
  
  pool.scheduleAtFixedRate((www.mmingyLgw.com) -> {
  
  sleep(1000); // 睡眠 1s,
  
  log.info("run task");
  
  }, 1, 2, TimeUnit.SECONDS); // 延迟 1s,周期 2s
  
  // 打印
  
  [19:41:28,489 INFO ] [pool-1-thread-1] - run task
  
  [19:41:30,482 INFO ] [pool-1-thread-1] - run task
  
  [19:41:32,483 INFO ] [pool-1-thread-1] - run task
  
  [19:41:34,480 INFO ] [pool-1-thread-1] - run task
  
  可以看到的确时固定周期 2s 执行的,但是如果任务执行时间超过周期呢?
  
  // 测试
  
  ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(1);
  
  pool.scheduleAtFixedRate(www.yunsengyule.com() -> {
  
  int i = 2000 + random.nextInt(3) * 1000;
  
  sleep(i);
  
  log.info("run task, sleep :{www.baihuiyulep.cn}", i);
  
  }, 1, 2, TimeUnit.SECONDS); // 延迟 1s,周期 2s
  
  // 打印
  
  [19:42:53,428 INFO ] [pool-1-thread-1] - run task, sleep :2000
  
  [19:42:55,430 INFO ] [pool-1-thread-1] - run task, sleep :2000
  
  [19:42:59,430 INFO ] [pool-1-thread-1] - run task, sleep :4000
  
  [19:43:02,434 INFO ] [pool-1-thread-1] - run task, sleep :3000
  
  [19:43:06,436 INFO ] [pool-1-thread-1] - run task, sleep :4000
  
  综上所述,我看到了 Shipper 在多集群管理和简单性方面的价值,它不需要 Kubernetes 以外的任何东西,但是它有一些严重的局限性。
  
  Flager 确实在自动部署和回滚以及对流量进行细粒度控制的过程中付出了额外的努力,它以更高的复杂性成本提供了所需的所有额外服务( Isito、Prometheus )。
  
  这里可以查看 Shipper、Isito 和 Flager 的示例代码。

Kubernetes 中的渐进式交付:蓝绿部署和金丝雀部署的更多相关文章

  1. 手把手教你在 TKE 集群中实现简单的蓝绿发布和灰度发布

    概述 如何在腾讯云 Kubernetes 集群实现蓝绿发布和灰度发布?通常要向集群额外部署其它开源工具来实现,比如 Nginx Ingress,Traefik 等,或者让业务上 Service Mes ...

  2. 附032.Kubernetes实现蓝绿发布

    蓝绿发布原理 蓝绿发布本质上是希望能优雅无误的迭代应用,以便于使应用平稳提供服务.通常是不停老版本的同时对新版本进行先发布,然后确认无误后进行流量切换,即并行部署. Kubernetes中可以通过de ...

  3. 持续部署入门:基于 Kubernetes 实现蓝绿发布

    前言 软件世界比以往任何时候都更快.为了保持竞争力,需要尽快推出新的软件版本,而不会中断活跃用户访问,影响用户体验.越来越多企业已将其应用迁移到 Kubernetes. 在 Kubernetes 中有 ...

  4. 使用 Flux,Helm v3,Linkerd 和 Flagger 渐进式交付 Kubernetes

    介绍 本指南将引导您在 Kubernetes 集群上设置渐进式交付 GitOps 管道. GitOps Helm 研讨会 原文地址:GitOps Progressive Deliver with Fl ...

  5. 蓝绿部署、红黑部署、AB测试、灰度发布、金丝雀发布、滚动发布的概念与区别(转)

    出处:https://www.baidu.com/link?url=QjboallwNm_jxcL3fHG57wEakiBfAs_3-TChTGu1eBXstlHEsGBc-NDA7AKTqsiroB ...

  6. Contour 学习笔记(二):使用级联功能实现蓝绿部署和金丝雀发布

    上篇文章介绍了 Contour 分布式架构的工作原理,顺便简单介绍了下 IngressRoute 的使用方式.本文将探讨 IngressRoute 更高级的用法,其中级联功能是重点. 1. Ingre ...

  7. 蓝绿部署、A/B测试以及灰度发布(金丝雀发布)

    过去的10多年里,很多大公司都在使用蓝绿部署,安全.可靠是这种部署方式的特点.蓝绿部署虽然算不上”Sliver Bullet“,但确实很实用.在有关于“微服务”.“DevOps”.“Cloud-nat ...

  8. 蓝绿部署、金丝雀发布(灰度发布)、A/B测试

    本文转载自蓝绿部署.金丝雀发布(灰度发布).A/B测试的准确定义 概述 蓝绿部署.A/B测试.金丝雀发布,以及灰度发布.流量切分等,经常被混为一谈,影响沟通效率. 根本原因是这些名词经常出现,人们耳熟 ...

  9. 蓝绿部署、滚动部署、金丝雀(Canary)发布、灰度发布、A/B测试

    最近看到Canary发布,一时没有反应过来是什么,一查才发现就是鼎鼎有名的金丝雀发布,发现经常一起出现的还有灰度发布.蓝绿部署.滚动部署.A/B测试,故一起学习一下这几个概念. 1. 蓝绿部署 目的: ...

随机推荐

  1. openlayer3相关扩展

    1 ol3扩展 http://viglino.github.io/ol-ext/ ,里面包含编辑-选择控件,字体,动画,canvas绘制等等实例 2 ol3空间拓扑关系库jsts,有jst衍生过来 h ...

  2. iOS----------使用cocoapods遇到的问题

    -bash: /usr/local/bin/pod: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby: bad ...

  3. SVN上传的时候没法显示文件名,只显示后缀名

    之前在用SVN上传android代码的时候,发现上传列表上的文件没法显示名字,只显示了后缀名,就像这样: 各种疑惑,最终发现解决方法: 右键单击操作栏的status: 然后在出现的选项里面将filen ...

  4. .NET性能优化小技巧

    .NET 性能优化小技巧 Intro 之前做了短信发送速度的提升,在大师的指导下,发送短信的速度有了极大的提升,学到了一些提升 .NET 性能的一些小技巧 HttpClient 优化 关于使用 Htt ...

  5. 如何利用Vagrant快速搭建相同配置的开发环境?

    作为一名程序猿,我们常常会遇到需要搭建开发环境的问题,特别是在新入职的时候,sublime, node, apache, mysql, php等等以及各种框架的安装.如果入职的是大公司有可能这些必要的 ...

  6. JS时间的获取及格式

    最近在做一个web聊天室,一个时间的问题挡住了进程,只好全网大搜索,将实用的方法记录下来,以备后查 <script src="/static/bootstrap/js/jquery.m ...

  7. 【公众号系列】SAP的新零售

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[公众号系列]SAP的新零售   写在前面 还是 ...

  8. access denied for user 'root'@'localhost'(using password:YES) FOR WINDOWS

    以windows为例: mysql5.5 1. 关闭正在运行的MySQL服务. 2. 打开DOS窗口,转到mysql\bin目录. 3. 输入mysqld --skip-grant-tables 回车 ...

  9. c/c++ 多线程 mutex的理解

    多线程 mutex的理解 mutex,我的理解是每个mutex对象都是一个带锁头的门,这个门有两个状态,门开着和门关着,感觉像是废话... 当想查看门的里东西,或者把东西放进门里,或者从门里拿出东西前 ...

  10. deepin 15.8桌面系统

    深度桌面环境是深度科技自主开发的美观易用.极简操作的桌面环境,主要由桌面.启动器.任务栏.控制中心.窗口管理器等组成,系统中预装了 WPS Office.搜狗输入法.有道词典.网易云音乐以及深度特色应 ...