K8s 应用管理之道 - 升级篇(二)-阿里云开发者社区

开发者社区> 吴波bruce_wu> 正文

K8s 应用管理之道 - 升级篇(二)

简介: 我们在上一篇文章中介绍了不同部署形式下应用的升级方法,同时展示了如何配置停机发布、滚动发布这两类 k8s 原生支持的部署升级策略。本文将介绍如何通过二次开发或使用一些第三方工具在 k8s 中实现应用的蓝绿发布、金丝雀发布和 A/B 测试。
+关注继续查看

背景

我们在系列文章 K8s 应用管理之道 - 升级篇(一) 中介绍了不同部署形式下应用的升级方法,同时展示了如何配置停机发布、滚动发布这两类 k8s 原生支持的部署升级策略。本文将介绍如何通过二次开发或使用一些第三方工具在 k8s 中实现应用的蓝绿发布、金丝雀发布和 A/B 测试。

蓝绿发布

如果新老版本的应用无法共存,但又希望实现零中断升级,在系统资源充足的前提下,可以选用蓝绿发布。通过 k8s 的 label-selector 机制可以轻松实现蓝绿发布。如下图所示,您需要做的仅仅是为不同版本的应用打上对应的标签,然后通过更改 service 的 selector 实现流量切换。

blue_green

配置方法

这里和蓝绿发布相关的配置如下(完整配置参见 blue-green)。

[...]
kind: Service
spec:
  # Service 的 selector 会选择 app 标签和 version 标签都匹配的 pod
  selector:
    app: spring-boot-probes
    # 通过更改 version 的取值实现流量切换,例如 v2.0.0
    version: v1.0.0
[...]
kind: Deployment
metadata:
  name: spring-boot-probes-v1
spec:
  selector:
    matchLabels:
      app: spring-boot-probes
      version: v1.0.0
  template:
    metadata:
      labels:
          app: spring-boot-probes
        # Pod 的 version 标签
        version: v1.0.0
[...]
kind: Deployment
metadata:
  name: spring-boot-probes-v2
spec:
  selector:
    matchLabels:
      app: spring-boot-probes
      version: v2.0.0
  template:
    metadata:
      labels:
        app: spring-boot-probes
        # Pod 的 version 标签
        version: v2.0.0
[...]

操作步骤

完成上述配置后,可以通过以下步骤实现蓝绿发布:

  1. 运行命令kubectl apply -f ./spring-boot-probes-v2.yaml部署 v2 版本的应用。等到 v2 版本的 pod 全部变成就绪状态后流量并不会发往它们,这是因为 service 的 selector 只与 v1 版本 pod 的标签相匹配。
  2. 当一切准备就绪后,可以运行命令kubectl patch service spring-boot-probes-svc -p '{"spec":{"selector":{"version":"v2.0.0"}}}'更改 service 的 selector,让其指向 v2 版本的 pod。这时流量会全部发往 v2。
  3. 如果 v2 版本的应用运行一段时间后出现了问题,可以通过命令kubectl patch service spring-boot-probes-svc -p '{"spec":{"selector":{"version":"v1.0.0"}}}'进行回滚,将流量再次切回到 v1 上来。
  4. 如果 v2 版本应用的行为符合预期,可以运行命令kubectl delete deploy spring-boot-probes-v1删掉 v1 版本的 deployment 以节省资源。

金丝雀发布

金丝雀发布通过逐步切换流量的方式大大降低了升级和变更可能带来的风险,因此被广泛使用。相较于其他发布方式,其最大特点在于对流量的灵活控制。回到 k8s 的场景,实现金丝雀发布最推荐的方式是使用 istio。利用 istio 强大的流量管理功能,用户可以灵活地控制发往不同版本的流量,不论该版本部署了多少个 pod 实例。而在没有 istio 的 k8s 环境中,发往新老版本的流量和它们的 pod 实例数成正比。

下图展示了基于 istio 的金丝雀发布的关键组件,用户可以通过调节 VirtualService 的 weight 字段指定将 10% 的流量发往金丝雀版本。

istio_canary

配置方法

以下配置指定将 90% 的流量发往服务 spring-boot-probes-svc-v1,将 10% 的流量发往服务 spring-boot-probes-svc-v2。而服务 spring-boot-probes-svc-v1 绑定了当前版本的 pod,服务 spring-boot-probes-svc-v2 绑定了金丝雀版本的 pod(完整配置参见 canary)。

[...]
kind: VirtualService
metadata:
  name: spring-boot-probes
spec:
  hosts:
    - spring-boot-probes.local
  gateways:
    - spring-boot-probes
  http:
    - route:
        - destination:
            host: spring-boot-probes-svc-v1
          weight: 90
        - destination:
            host: spring-boot-probes-svc-v2
          weight: 10
[...]
kind: Service
metadata:
  name: spring-boot-probes-svc-v1
spec:
  selector:
    app: spring-boot-probes
    version: v1.0.0
[...]
kind: Service
metadata:
  name: spring-boot-probes-svc-v2
spec:
  selector:
    app: spring-boot-probes
    version: v2.0.0
[...]

操作步骤

完成上述配置后,可以通过以下步骤实现金丝雀发布:

  1. 运行命令kubectl apply -f ./spring-boot-probes-v2.yaml部署 v2 版本的 service 和少量的 pod 实例。由于此时 VirtualService 的路由目标只有 v1,流量并不会被发到 v2 上。
  2. 当 v2 版的 pod 就绪后,运行命令kubectl apply -f ./virtualservice-weight.yaml更改 VirtualService 的路由规则,让少量流量能够发往 v2。
  3. 如果 v2 版本应用的行为符合预期,可以通过调整权重继续扩大发往 v2 的流量比例。同时,v1 和 v2 的 pod 实例数也可以根据实际情况进一步调整,甚至可以为它们配置 Horizontal Pod Autoscaler
  4. 如果 v2 版本在运行过程中出现了问题,可以更改 VirtualService 的路由规则将流量重新切回到 v1 上来。
  5. 待全部流量都落在 v2 上后,运行命令kubectl delete -f ./spring-boot-probes-v1删除 v1 版应用的资源。

A/B 测试

如果您网站的 UI 作了改版,但并不确定新版本是否会获得用户青睐,这时可以通过 A/B 测试收集用户意见,并根据实际效果确定最佳方案。A/B 测试实施的关键在于根据不同条件将访问流量分发到不同的版本。实际使用中,往往会根据具体情况选用不同的条件。常用的条件包括用户位置信息、user-agent、自定义 header、请求参数、语言等。得益于强大的流量管理功能,istio 是 k8s 场景下实现 A/B 测试的最佳方案。下图展示了如何根据 user-agent 分发访问流量。

istio_abtesting

配置方法

以下配置指定将来自 Andriod 的访问流量发往服务 spring-boot-probes-svc-v1,将来自 iPhone 的访问流量发往服务 spring-boot-probes-svc-v2。而 spring-boot-probes-svc-v1 和 spring-boot-probes-svc-v2 分别绑定了不同版本的 pod
(完整配置参见 ab-testing)。

[...]
kind: VirtualService
metadata:
  name: spring-boot-probes
spec:
  hosts:
    - spring-boot-probes.local
  gateways:
    - spring-boot-probes
  http:
    - route:
        - destination:
            host: spring-boot-probes-svc-v1
      match:
        - headers:
            user-agent:
              exact: Andriod
    - route:
        - destination:
            host: spring-boot-probes-svc-v2
      match:
        - headers:
            user-agent:
              exact: iPhone
[...]
kind: Service
metadata:
  name: spring-boot-probes-svc-v1
spec:
  selector:
    app: spring-boot-probes
    version: v1.0.0
[...]
kind: Service
metadata:
  name: spring-boot-probes-svc-v2
spec:
  selector:
    app: spring-boot-probes
    version: v2.0.0
[...]

操作步骤

完成上述配置后,可以通过以下步骤实施 A/B 测试:

  1. 运行命令kubectl apply -f ./spring-boot-probes-v2.yaml部署 v2 版本的 service 和对应的 pod 实例。
  2. 当 v2 版的 pod 就绪后,运行命令kubectl apply -f ./virtualservice-match.yaml更改 VirtualService 的路由规则,让来自 Andriod 的流量发往 v1,来自 iPhone 的流量发往 v2。
  3. 让两个版本的应用同时运行一段时间并不断收集用户反馈。
  4. 如果发现使用 user-agent 作为条件并不能达到很好的测试效果,可以更改 VirtualService 的路由规则,根据其他条件进行测试。
  5. 经综合分析后,如果发现 v1 更受青睐,则更改 VirtualService 的路由规则,让流量只发往 v1,然后删除 v2 版应用的资源。反之亦然。

总结

本文带您探索了在 k8s 中进行蓝绿发布、金丝雀发布和 A/B 测试的最佳实践。可以看到,运用好 istio 强大的流量管理功能可以简化复杂发布的实施流程,大大降低实现成本。

参考资料

扩展阅读

阿里云日志服务针对容器场景提供了一站式日志解决方案,想了解相关内容可参考下列文章:

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
灵活、高效的云原生集群管理经验:用 K8s 管理 K8s
单 K8s 集群为用户提供了 Namespace 级别的隔离能力,理论上支持不超过 5K Node、15W Pod。多 K8s 集群则解决了单集群的资源隔离、故障隔离难题,打破可支持节点数、Pod 数的限制,但与此同时也带来了集群管理复杂度的上升;尤其在专有云场景中,K8s 工程师不可能像在公有云中一样快速触达客户环境,运维成本被进一步放大。因此如何低成本、高效率、自动化低管理多套 K8s 集群,成为业内普遍难题。
894 0
K8s 应用管理之道 - 有状态服务
用户通过 Deployment、ReplicationController 可以方便地在 kubernetes 中部署一套高可用、可扩展的分布式无状态服务。这类应用不在本地存储数据,通过简单的负载均衡策略可实现请求分发。
7770 0
六大举措建云管理模式助力企业转型升级
本文讲的是六大举措建云管理模式助力企业转型升级,“我们处在一个令人兴奋的,崭新的云管理时代。云管理也许是中国企业的管理能够跻身世界管理之林的一个重大机会。
1090 0
Serverless 微服务实践-移动应用包分发服务(Fun 3.0 升级版)
Serverless 微服务实践-移动应用包分发服务 背景 阿里云函数计算是事件驱动的全托管计算服务。通过函数计算,您无需管理服务器等基础设施,只需编写代码并上传。函数计算会为您准备好计算资源,以弹性、可靠的方式运行您的代码,并提供日志查询、性能监控、报警等功能。
2202 0
ASP.NET Core on K8S深入学习(8)数据管理
本文探索了K8S的数据管理方案Volume,其中普通类型的Volume如emptyDir和hostPath虽然使用方便,但是可持久性不强,而外部云存储Volume Provider则提供了更好的持久化存储。
1467 0
+关注
吴波bruce_wu
关注日志处理与分析 、容器、微服务、云原生计算等领域
19
文章
0
问答
来源圈子
更多
阿里云存储基于飞天盘古2.0分布式存储系统,产品包括对象存储OSS、块存储Block Storage、共享文件存储NAS、表格存储、日志存储与分析、归档存储及混合云存储等,充分满足用户数据存储和迁移上云需求,连续三年跻身全球云存储魔力象限四强。
+ 订阅
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载