蓝/绿部署 VS 金丝雀部署

蓝/绿部署 VS 金丝雀部署_第1张图片

在云端或数据中心部署新版本的最佳方式

在生产环境中更新和配置应用程序通常是件令人望而生畏的事。面对如此多的可用选项,应如何选择最适合你的用例的部署策略?

部署策略用于升级或配置正在运行的应用程序。在下文中,我们将讨论三种部署策略:

  • 重建部署:在部署新版本之前,终止当前版本。
  • 蓝/绿部署:当前版本和新版本并行运行,然后将所有流量切换到新版本。
  • 金丝雀部署:新版本逐步向一小部分用户推出,之后发布供所有用户使用。

值得注意的是,还可通过许多其他方式来发布应用程序的新版本。你可点击此处,查看针对其中一部分方式进行的讨论。

在整篇文章中,我们将使用本地 Kubernetes 环境来演示所讨论的各种部署策略。

如果可以的话,你也可以使用云环境。

下文提到了演示所需的所有文件和命令,也可以在该项目的 Github 存储库中找到。

顺带一提,Ori Hoch 撰写的一篇博文已探讨了使用 Kubernetes 来支持 CI 构建(见第 1 部分和第 2 部分)。在这篇文章中,我们将更多地关注 CI/CD 的 CD 部分,也就是部署。

来看看我们的 Kubernetes YAML 文件:

version1-deployment.yml
——部署 6 个副本,运行一个简单的 Web 应用程序,呈现“版本 1

# version2-deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-2
spec:
  selector:
      matchLabels:
      app: nginx 
      version: 'v1.1'
  replicas: 6
  template:
      metadata:
      labels:
      app: nginx
      version: 'v1.1'
      spec:
      containers:
      - name: nginx
      image: my_project/web-app:version2
      ports:
      - containerPort: 80

version2-deployment.yml
部署
——部署 6 个副本,运行一个简单的 Web 应用程序,呈现“版本 2”

# version2-deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-2
spec:
  selector:
      matchLabels:
      app: nginx 
      version: 'v1.1'
  replicas: 6
  template:
      metadata:
      labels:
      app: nginx
      version: 'v1.1'
      spec:
      containers:
      - name: nginx
      image: my_project/web-app:version2
      ports:
      - containerPort: 80

production-service.yml
——我们应用程序的生产服务。用户将使用该服务访问应用程序的第一版本(version1)。

# production-service.yml

apiVersion: v1
kind: Service
metadata:
  name: production-service
spec:
  type: LoadBalancer
  selector:
      app: nginx
      version: 'v1.0'
  ports:
      - protocol: TCP
      port: 80
      targetPort: 80

重建部署(基本部署)

你有没有问过自己:“要部署我的应用程序,最糟糕的方式是什么?”

如果有,那么答案就是重建部署。

玩笑归玩笑,针对这种方法也有一些有效的用例。
例如,在并行运行多个版本的同时,升级基于微服务的复杂应用程序,可能会导致数据丢失或引发严重的网络问题。

采用这种方法后,在部署新版本之前必须完全关闭当前版本。在关闭当前版本直至完全部署好新版本期间,用户将经历停机时间。

在我们所讨论的所有部署策略中,重建部署是最易实现且成本最低的,但也是风险最大的。万一新版本出现严重 bug,所有用户都会注意到它,而且任何必要的回滚都将导致停机时间变得更长。

为何要使用这种部署策略?

  • 我的应用程序的数据很重要,我无法承担数据丢失或严重的网络问题后果
  • 我必须在启动新的应用程序之前运行迁移
  • 我的应用程序不支持多个版本并行运行
  • 我正在一个测试环境中工作
  • 用户只在特定时间段内使用我的应用程序(比如工作时间为 9:00-17:00 的客户服务应用程序)
  • 我的预算很低

优点:

  • 价格低廉
  • 易于实现
  • 增加用例

缺点:

  • 将发生停机
  • 生产风险高
  • 回滚速度慢

蓝/绿部署 VS 金丝雀部署_第2张图片
如需实现重建部署:

1.部署应用程序的第一版本

kubectl apply -f version1-deployment.yml && kubectl rollout status -f version1-deployment.yml

2.应用生产服务

kubectl apply -f production-service.yml

3.删除应用程序的第一版本

kubectl delete -f version1-deployment.yml

4.彻底删除第一版本后,部署应用程序的新版本

kubectl apply -f version2-deployment.yml && kubectl rollout status -f version2-deployment.yml

5.现在,剩下的工作就是更改服务以指向新版本

kubectl patch service production-service --patch '{"spec": {"selector": {"version": "v1.1"}}}'

如果你最大的担忧是停机时间,则考虑使用下一种方法。

蓝/绿部署

蓝绿部署,也称为“红黑部署”(如果你猜到是谁嵌入了这个术语,加一分*),是一种零停机时间部署策略,应用程序的当前版本(“蓝色”实例)和新版本(“绿色”实例)在生产环境中并行运行。两个版本同时运行,但公开的应用程序的服务仅指向当前版本。

在用户可以访问新版本之前,需要在环境中对其进行测试。当确定其满足所有要求后,剩下的工作就是更改应用程序的服务以指向绿色实例。

*(还没有猜到吗?答案是 Netflix!你可以点击此处查看更多相关信息。)

从此时起,旧版本作为新版本的备份,与其一起运行。万一发生故障,回滚很容易——只需将流量从绿色实例切换到蓝色实例。

部署成功并删除蓝色实例后,绿色实例将在下一次更新中充当蓝色实例。

蓝/绿部署 VS 金丝雀部署_第3张图片
应该何时使用这种部署策略?

  • 我不希望我的用户经历任何停机时间
  • 我可以快速、轻松地回滚到之前的版本
  • 我的基础设施是可扩展的,而且我可以把握同时运行两个应用程序的成本
  • 我想保存之前的版本,以供今后进行开发时使用

优点:

  • 零停机时间
  • 轻松、快速地回滚
  • 所有用户都体验同一版本(防止出现版本控制问题)
  • 允许对新、旧版本进行对比测试

缺点:

  • 基础设施成本可能会增加,因其需要两倍的资源
  • 可能不适合小的版本变更
  • 在将绿色实例发布到生产之前,需要对其进行测试和监控

如需实现蓝绿部署:

1.应用蓝色实例的部署

kubectl apply -f version1-deployment.yml && kubectl rollout status -f version1-deployment.yml

2.应用绿色实例的部署

kubectl apply -f version2-deployment.yml && kubectl rollout status -f version2-deployment.yml

3.应用生产服务

kubectl apply -f production-service.yml

4.就绿色实例运行测试

1.如果测试期间在新版本中发现了问题,删除新版本的部署,

kubectl delete -f version2-deployment.yml

并在重新部署之前修复应用程序的代码。

2.如果新版本测试成功,且该版本已准备就绪可用于生产,则更改服务以指向绿色实例

kubectl patch service production-service --patch '{"spec": {"selector": {"version": "v1.1"}}}' 

即可!

金丝雀部署

若采用金丝雀部署这种方法,在将应用程序新版本发布给所有用户之前,逐步向一小部分用户推出,以进行初始测试。此方法的目的是针对少量用户收集性能度量指标,并预测对用户的影响,以便进行全面部署。在这组用户使用了应用程序的新版本后,将收集和分析度量指标,以确定该版本是否已准备就绪可用于生产,是否需要推广到环境的其他部分(或到下一阶段),或者是否需要回滚以进一步排除故障。
这种策略最适用于测试结果不明确、不可靠或流量大小可能影响应用程序性能的情况。

蓝/绿部署 VS 金丝雀部署_第4张图片
金丝雀部署可以分两步或小阶段实现(例如,5% 的用户,到 25%,再到 50%……),当部署一个新的应用程序代码后,它将公开给多个用户。

与其他策略相比,这种方法带来的风险最低,因为它提供了控制。

你可以定义在每个阶段将转发到新版本的请求的确切百分比,因此,如果发生错误,只有少数用户会受到影响,并且你可以快速、毫不费力地执行回滚。

为了成功实现金丝雀部署,性能度量指标应该是明确的,并且两个版本应该在相同的条件下部署在同一环境中。

采用这种方法,可以选择针对自定义客户群部署新版本。你可以按用户的应用程序体验层级、所处地理位置或使用频率对用户进行排序。

做一个更好的应用程序,这一目标始终不变,但重要的是要考虑你希望通过金丝雀部署获得哪些信息,比如选择一个信任度高的子网,还是丧失客户信任的影响很小的子网。

使用金丝雀部署的一个缺点是,你必须同时管理应用程序的多个版本。甚至还可以在生产中同时运行两个以上的版本。但是,最好将同时运行的版本数量控制在最低限度。

你可以读一读 LaunchDarkly(一家专注于部署解决方案的公司)撰写的这篇博文,了解更多关于针对不同客户群推出不同版本这一做法的信息。

为何要使用这种部署策略?

  • 我不希望我的用户经历任何停机时间
  • 在我看来,用户的体验极其重要,我希望将他们在使用应用程序期间遇到 bug 的可能性降到最低。即使发现了 bug,也只有少数用户会受到影响
  • 应用程序的流量可能会影响应用程序的性能
  • 我当前的基础设施成本很高,无法使用更多资源
  • 我需要一些时间来监测新版本的效果

优点:

  • 零停机时间
  • 快速回滚
  • 基于真实的用户和用例进行测试
  • Bug 只会影响到少数用户
  • 无需额外的基础设施成本

缺点:

  • 推出速度慢
  • 需要对每个阶段进行测试和监控
  • 不易实现
  • 并非所有用户都能立即体验到新版本的功能

如需实现金丝雀部署:

实现金丝雀部署可采用的方法和工具有很多。下文提供了最简单的一种,无需任何附加工具即可使用。

1.部署应用程序第一版本的三个实例

kubectl apply -f version1-deployment.yml && kubectl rollout status -f version1-deployment.yml

2.应用生产服务

kubectl apply -f production-service.yml

3.将当前版本的实例数减少到 3

kubectl scale --replicas=3 -f version1-deployment.yml && kubectl rollout status -f version1-deployment.yml

4.就 3 个实例部署应用程序的新版本

kubectl apply -f version2-deployment.yml && kubectl scale --replicas=3 -f version2-deployment.yml && kubectl rollout status -f version2-deployment.yml

5.当 3 个实例为当前版本,3 个实例为新版本时,更改服务以指向两个版本。换言之,50% 的用户将访问新版本,50% 的用户将访问当前版本

kubectl patch service production-service --patch '{"spec": {"selector": {"version": null}}}'

6.对新版本的实例运行测试

1.如果在测试过程中发现新版本有问题,则回滚到之前的版本(删除新版本的部署,并将之前版本的实例数增加到原来的数目)

kubectl delete -f version2-deployment.yml && kubectl scale --replicas=6 -f version1-deployment.yml && kubectl rollout status -f version1-deployment.yml

2.如果该版本运行良好,则删除当前版本的部署,并将新版本的实例数增加到原来的数目,从而完成推出

kubectl delete -f version1-deployment.yml && kubectl scale --replicas=6 -f version2-deployment.yml && kubectl rollout status -f version2-deployment.yml 

金丝雀部署也带来了挑战。最大的障碍之一是管理服务和不同版本的组件之间的依赖关系。在某些情况下,有些旧版本组件仍然是应用程序的一部分,但新版本组件无法与此类组件很好地交互,反之亦然。因此,实现新旧版本间通信兼容并非易事。针对这一挑战,有几个不错的解决方案,但我们不会在此进行讨论,因为这将超出本文的范围。

结语

无论你是想在本地 Kubernetes 集群还是云环境中部署应用程序的新版本,都有多种部署方式可供选择,而最佳方式取决于你的需求和基础设施成本。

在将某个版本发布到开发/模拟环境时,或者当并行运行多个版本期间可能会出现应用程序性能问题时,重建部署是一个不错的选择。

对于生产环境,若基础设施成本不成问题(因为要求具备可提供双倍资源的能力),蓝/绿部署可能是你的最佳解决方案,但需要针对新应用程序运行适当的测试。

如果对软件的影响/稳定性没什么信心,对用户体验感到担忧,或者你的应用程序需要在某个可进行筛选(例如地理位置或体验层级)的特定客户群中测试某项新功能,那么你可能要使用金丝雀部署。

相关文章:

软件发布管理流程技巧

如何成功实现功能发布控制

点击了解 Incredibuild 的 CI/CD 加速的解决方案!
同时,Incredibuild 还有纯云 / 混合云的编译加速解决方案!

点击获取Incredibuild试用!
蓝/绿部署 VS 金丝雀部署_第5张图片

你可能感兴趣的:(DevOps,C++,CI,devops,ci,c++)