Kubernetes 上的应用部署策略
在 Kubernetes 中,有几种不同的发布应用程序的方法,有必要选择正确的策略以在应用程序更新期间使基础架构可靠。
根据需要选择正确的部署过程,我们在下面列出了一些可能采用的策略:
- recreate: 终止旧版本并发布新版本
- ramped: 以滚动更新的方式发布新版本,一个又一个
- blue/green: 与旧版本一起发布新版本,然后切换流量
- canary: 向一部分用户发布新版本,然后进行全面部署
- a/b testing: 以精确的方式(HTTP 标头,Cookie,权重等)向一部分用户发布新版本。 A / B 测试实际上是一种基于统计信息做出业务决策的技术,但是我们将简要描述该过程。 Kubernetes 并不是开箱即用的,它意味着需要额外的工作来设置更高级的基础架构(Istio,Linkerd,Traefik,自定义 nginx / haproxy 等)。
您可以使用 Minikube 尝试每种策略,该存储库中说明了要遵循的清单和步骤: https://github.com/ContainerSolutions/k8s-deployment-strategies
让我们看一下每种策略,看看哪种类型的应用程序最适合它。
重新建立 - 最适合开发环境
使用 Recreate
类型的策略定义的部署将终止所有正在运行的实例,然后使用较新版本重新创建它们。
spec:
replicas: 3
strategy:
type: Recreate
可以在以下位置找到完整的示例和部署步骤: https://github.com/ContainerSolutions/k8s-deployment-strategies/tree/master/recreate
优点:
- 应用状态完全更新
缺点:
- 停机时间取决于应用程序的关闭和启动持续时间
Ramped - slow rollout
渐变部署以滚动更新方式更新 pod,使用应用程序的新版本创建辅助 ReplicaSet,然后减少旧版本的副本数,并增加新版本,直到达到正确的副本数。
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 2 # how many pods we can add at a time
maxUnavailable:
0 # maxUnavailable define how many pods can be unavailable
# during the rolling update
可以在以下位置找到完整的示例和部署步骤 https://github.com/ContainerSolutions/k8s-deployment-strategies/tree/master/ramped
与水平吊舱自动缩放一起设置时,使用基于百分比的值代替 maxSurge 和 maxUnavailable 的数字会很方便。
如果在进行现有部署时触发部署,则部署将暂停部署,并通过覆盖部署来继续进行新发行。
优点:
- 版本会在实例之间缓慢发布
- 对于可以处理数据重新平衡的有状态应用程序很方便
缺点:
- 推出/回滚可能需要一些时间
- 很难支持多个 API
- 无法控制流量
蓝/绿 发布 - 最好避免 API 版本控制问题
蓝色/绿色部署与渐变部署不同,因为应用程序的“绿色”版本与“蓝色”版本一起部署。 在测试新版本满足要求之后,我们更新 Kubernetes Service 对象,该对象扮演负载平衡器的角色,通过替换选择器字段中的版本标签将流量发送到新版本。
apiVersion: v1
kind: Service
metadata:
name: my-app
labels:
app: my-app
spec:
type: NodePort
ports:
- name: http
port: 8080
targetPort: 8080
# Note here that we match both the app and the version.
# When switching traffic, we update the label “version” with
# the appropriate value, ie: v2.0.0
selector:
app: my-app
version: v1.0.0
可以在以下位置找到完整的示例和部署步骤 https://github.com/ContainerSolutions/k8s-deployment-strategies/tree/master/blue-green
优点:
- 即时推出/回滚
- 避免版本问题,一次性更改整个群集状态
缺点:
- 需要两倍的资源
- 在发布到生产环境之前,应该对整个平台进行适当的测试
- 处理有状态的应用程序可能很困难
金丝雀 - 让用户测试
金丝雀部署包括将用户的子集路由到新功能。 在 Kubernetes 中,可以使用两个具有通用 Pod 标签的部署来完成金丝雀部署。 新版本的一个副本与旧版本一起发布。 然后,在一段时间后,如果未检测到错误,请按比例增加新版本的副本数量并删除旧的部署。
使用此 ReplicaSet 技术需要旋转尽可能多的 Pod,以获取正确百分比的流量。 就是说,如果您要将 1%的流量发送到 B 版,则需要让一个 Pod 与 B 版一起运行,而有 99 个 Pod 与 A 版一起运行。这可能非常不方便管理,因此,如果您正在寻找一种更好的管理方式, 流量分配,请查看诸如 HAProxy 之类的负载平衡器或诸如 Linkerd 之类的服务网格,它们可以提供对流量的更好控制。
在以下示例中,我们并排使用两个副本集,版本 A 具有三个副本(占流量的 75%),版本 B 具有一个副本(占流量的 25%)。
Truncated deployment manifest version A:
spec:
replicas: 3
Truncated deployment manifest version B, note that we only start one replica of the application:
spec:
replicas: 1
可以在以下位置找到完整的示例和部署步骤 https://github.com/ContainerSolutions/k8s-deployment-strategies/tree/master/canary
优点:
- 为部分用户发布的版本
- 方便错误率和性能监控
- 快速回滚
缺点:
- 缓慢推出
- 调整好的流量分配可能会很昂贵(99%A / 1%B = 99 个 Pod A,1 个 Pod B)
上面使用的过程是 Kubernetes 的本机程序,我们调整了 ReplicaSet 管理的副本数量,以在版本之间分配流量。
如果您不确定新功能的发布可能对平台的稳定性产生什么影响,建议使用金丝雀发布策略。
A/B 测试 - 最适合部分用户的功能测试
A/B 测试实际上是一种基于统计信息而不是部署策略制定业务决策的技术。 但是,它是相关的,可以使用 canary 部署来实现,因此我们将在此处简要讨论。
除了根据权重在各个版本之间分配流量外,您还可以基于一些参数(cookie,用户代理等)精确定位给定的用户群。 此技术被广泛用于测试给定功能的转换,并且仅推出转换最多的版本。
与其他服务网格一样,Istio 提供了一种更细粒度的方法,可以基于权重和/或 HTTP 标头使用动态请求路由细分服务实例。
以下是使用 Istio 设置规则的示例,因为 Istio 仍处于开发阶段,因此以下示例规则将来可能会更改:
route:
- tags:
version: v1.0.0
weight: 90
- tags:
version: v2.0.0
weight: 10
可以在以下位置找到完整的示例和部署步骤 https://github.com/ContainerSolutions/k8s-deployment-strategies/tree/master/ab-testing
其他工具(如 Linkerd,Traefik,NGINX,HAProxy)也允许您执行此操作。
优点:
- 需要智能负载均衡器
- 多个版本并行运行
- 完全控制流量分配
缺点:
- 很难解决给定会话的错误,必须进行分布式跟踪
- 不简单,您需要设置其他工具
总结
有多种方法可以部署应用程序,当发布到开发/登台环境时,重新创建或扩展的部署通常是一个不错的选择。当涉及生产时,通常最好是采用倾斜的部署或蓝绿色部署,但必须对新平台进行适当的测试。如果您对平台的稳定性以及发布新软件版本可能带来的影响不满意,那么应该选择 Canary 发布。这样,您就可以让使用者测试应用程序及其与平台的集成。最后但并非最不重要的一点是,如果您的企业需要在特定的用户群中测试新功能,例如,所有使用手机访问该应用程序的用户都发送到版本 A,那么所有通过桌面访问的用户都将转到版本 B。可能想使用 A / B 测试技术,该技术通过使用 Kubernetes 服务网格或自定义服务器配置,使您可以根据某些参数确定应将用户路由到的位置。
参考链接
Blog Kubernetes Deployment Strategy GitHub Kubernetes Deployment Strategy