作者王炜,CODING DevOps 后端开发工程师多年研发经验,云原生、DevOps、Kubernetes 资深爱好者,Servicemesher 服务网格中文社区成员。获得 Kubernetes CKA、CKAD 认证。

1. 开篇

如果让你主导一款千万、甚至亿级用户产品的功能迭代,你会怎么做?你需要面对的挑战可能来自于:

商业战略的变化带来新的产品诉求,而产品的任何改动哪怕仅是界面调整,都将面临无数存量用户的挑战

这时候,作为产品负责人,你会选择稳定压倒一切?还是自我革新,继续追求用户和市场的价值呢?笔者通过对 Facebook、Twitter 等互联网巨头的调研,试图窥探他们在瞬息万变的市场中仍然保持“稳定”迭代的秘密 - 渐进式交付  ,并进一步探索出如何将腾讯云容器服务 [1]DevOps 相结合以实现全自动化的渐进式交付

通过本篇文章,你将收获:

  1. 什么是渐进式交付,为什么 Kubernetes、DevOps 能够天然与其结合
  2. 为什么渐进式交付能赋予大规模组织下的产品持续交付及稳定迭代的能力
  3. 腾讯云容器服务如何支撑渐进式交付全自动化进行
  4. 小项目,大项目同样适用的“腾讯云容器服务" 腾讯云容器服务 ")+CODING DevOps”最佳实践

2. 什么是渐进式交付

移动互联网时代的爆发,诞生了一大批巨型互联网企业和项目,部分大型项目的技术复杂程度和组织复杂程度甚至不亚于传统的工业项目,为了实现对这些项目的管理和迭代,我们试图将目光投向已经完成工业革命的传统工业寻找答案。

而“渐进式交付”一词最早起源于大型、复杂的工业化项目,比如:铁路、汽车和军事产业、新基建的 5G 网络产业等等。

它和 DevOps 的目标一致,试图将复杂的工程化项目进行分阶段拆解,通过持续进行小型迭代闭环,降低交付成本和节约交付时间

可查询的资料显示,“渐进式交付”流行于互联网产品是在近两年 Kubernetes 以及云原生大规模使用之后。这两项技术的出现,为“渐进式交付”在互联网的应用提供了基础设施和实现方法。

DevOps 是“渐进式交付”的实现手段,而其中的“流水线”为“渐进式交付”提供了实现途径

在产品的迭代过程,可以将“渐进式交付”的具体行为附着在“流水线”中,将整条交付“流水线”看做是产品迭代的一个过程和一次“渐进式交付”周期。

说了这么多“渐进式交付”的理论基础,在实践中又是以哪些技术方法落地呢?

  1. A/B 测试
  2. 金丝雀 / 灰度发布

以 Facebook 为例,每次发布重大功能,都会经历一次典型的“渐进式交付”过程:

  1. 迭代发布
  2. 公司全员 A/B 测试
  3. 特定用户 A/B 测试
  4. 灰度发布
  5. 全量发布

这种渐进式交付的好处是,对于新迭代正式推向市场前提供了灰度用户的数据支撑,帮助决策者充分了解用户倾向和市场诉求。

在“渐进式交付”的过程中,A/B 测试环节以及灰度发布环节都可以根据用户数据和市场反馈决定是否进入全量发布,这种方式既能够保证迭代敏捷进行,又能够保证迭代的用户和市场安全性。

2.1 A/B 测试

例如通过对用户画像中地理位置和性别组合条件进行 A/B 测试,使其访问新版本,而其他的用户则继续访问旧版。一段时间后,研究用户行为数据和用户体验报告,决定功能是否继续进入下一个发布环节。

2.2 金丝雀 / 灰度发布

使用特定分流技术使流量由新老版本共同承担,如典型的“MurmurHash”算法

3. 技术价值和商业价值

从原理上来看,这些技术并不是多么新的技术,比如 A/B 测试,我们用最原始的方式:业务代码增加逻辑判断条件也可实现,但为什么没有大规模运用呢?

原因很简单:纯业务代码的实现依赖于技术开发,需求方无法自主控制 A/B 测试的环境和条件,这种过度依赖于技术开发并不能带来规模化的运用。

我们需要的是一种完全脱离业务代码的实现方式,最好能以自动化/半自动化实现,并且尽量能把这个动作加入到已有的内部流程内

现在,有了云原生和 Kubernetes 的支持,结合 DevOps 的流水线,自动化的渐进式交付成为了可能。

我们参考 Facebook 的发布方式,设计了这个 Pipeline Demo

它主要实现了:

  1. 提交代码后自动执行单元测试,并构建 Docker 镜像
  2. 将 Docker 镜像推送到私有制品库,自动触发流水线
  3. 执行 K8S Job Migrate 数据库(如果有改动),并部署新版到预发布环境
  4. 人工确认:发布生产环境前是否进行 A/B 测试
  5. A/B 测试通过后,设置灰度发布的比例,自动灰度发布
  6. 人工确认:是否全量发布生产环境
  7. 生产环境自动配置限流和熔断策略,保证生产稳定

最终实现的效果图:

1. 提交代码后自动构建镜像、单元测试、推送到镜像仓库并触发 CD 流水线。
2. 执行 K8S Job 对预发布环境数据库自动 Migrate,并发布到预发布环境。
http://dev.coding
4. 人工确认:发布生产环境前是否进行 A/B 测试。
Header
http://pro.coding
6. 人工确认:设置期望的灰度发布比例,自动灰度发布,如选择灰度发布比例为 50%。
http://pro.coding
8. 人工确认:全量发布生产环境。
http://pro.coding
10. 自动配置限流和熔断策略,保证生产稳定性。通过压力测试可看到并发请求有一部分被限流。

HttpCode=429,代表 Too Many Requests ,拒绝服务。

对于开发人员,这种渐进式交付经过多轮的灰度、A/B 测试,最大程度减少代码 BUG 发布到生产环境 对于运维人员,这种几乎全自动的交付方式改变了手动修改 yaml 文件,手动 apply 的麻烦,最大程度减少发布产生的人为错误。通过自动触发的方式,减小了与开发的沟通成本 对于产品经理和运营人员,产品迭代不再是靠内部团队“YY”,而是基于实际用户体验数据,了解新功能对于用户和市场的反馈,最大程度减小新功能的用户和市场风险

4. 动手实践

4.1 概览

  1. 准备一个 K8S 集群,推荐使用腾讯云容器服务;
  2. K8S 集群部署 Traefik 替换 nginx-Ingress 作为 Ingress Gateway,提供更好的流量治理能力;
  3. 开通 CODING DevOps[2],提供镜像构建和流水线的部署能力;
  4. 克隆示例代码[3]并推送到自己的 CODING 代码仓库;
  5. 复制模板创建部署流水线;
  6. 尽情测试。

4.2 实践步骤

4.2.1 克隆源代码并创建构建计划
  1. 克隆源代码并推送到自己的 CODING 仓库

    git clone https://e.coding.net/wangweicoding/cd-production.gitgit remote remove origingit remote add origin 你的 CODING 仓库地址git push origin master

  2. 创建构建计划
cd-production
4.2.2 开通腾讯云容器服务
  • 登录腾讯云容器服务平台,新建一个 Kubernetes 集群,并获取该集群凭证
  • 在 CODING DevOps 绑定腾讯云账号,新建 K8s 集群凭证(如有必要,请允许集群外网访问)
4.2.3 通过 CODING DevOps 初始化 Traefik
cd-productioncoding-templates/traefik.json部署控制台

点击“Update Pipeline”后,自动创建了对应的 Pipeline。

注意请将每一个阶段的云账号修改为自己的云账号。 再点击“保存”即完成 Traefik 初始化的 Pipeline 创建,返回后,点击“立即启动”完成集群 Traefik 的初始化。

Servicetraefik-systemtraefik-ingressHost
dev.coding
4.2.4 通过 CODING DevOps 初始化 Mysql
cd-productioncoding-templates/mysql.json
4.2.5 创建渐进式交付流水线
CODING 制品库cd-productionDockerfile
cd-productioncoding-templates/devops.json
CODING 项目GitCODING 项目云账号
index.html

5. 项目说明与核心原理

5.1 项目说明

5.2 核心原理

Routerdev.codingpro.coding
5.2.1 Dev 环境架构图
dev.codingRouterHostk8s-flask-nodeportService

Traefik Router 核心配置代码为:

5.2.2 A/B 测试环境架构图
pro.codingRouterHostHeaderk8s-flask-canaryk8s-flask

A/B 测试 Traefik Router 核心配置代码为:

5.2.3 灰度发布架构图
pro.codingRouterHostWeightk8s-flask-canaryk8s-flask

例如以 1:1 的比例分配灰度比例,Traefik Router 核心配置代码为:

CanaryWeight
5.2.4 熔断和限流架构图

在生产环境,我们一般使用限流和熔断技术来应对流量激增,牺牲部分用户的体验来保证生产环境的稳定。

middlewares

Traefik Middlewares 限流核心配置:

Traefik Middlewares 熔断核心配置:

6. 小结

Kubernetes 和 Service Mesh 的出现,给 DevOps 带来了更多可能,渐进式交付只是一种借助其便利性的比较典型的发布方式。

Service MeshVirtual ServiceDestination Rule

借助 CODING DevOps 的能力,我们将“推送代码”、“构建镜像”、“触发部署流程”进行打通,实现了自动化的 DevOps 能力。

当然,还可以做到更多有价值的发布流程,比如:

Wait

7. 资源链接和参考资料

  • Demo Git 仓库地址[4]
  • CODING 持续集成(CI)[5]
  • CODING 持续部署(CD)[6]
  • Tencent TKE[7]
  • Facebook 的增长神器 —— 灰度发布 + A/B testing[8]
  • Traefik 文档[9]

参考资料

[1]

腾讯云容器服务 : https://console.cloud.tencent.com/tke2

[2]

CODING DevOps: https://coding.net/products/cd

[3]

示例代码: https://e.coding.net/wangweicoding/cd-production.git

[4]

Demo Git 仓库地址: https://e.coding.net/wangweicoding/cd-production.git

[5]

CODING 持续集成(CI): https://coding.net/products/ci

[6]

CODING 持续部署(CD): https://coding.net/products/cd

[7]

Tencent TKE: https://cloud.tencent.com/product/tke

[8]

Facebook 的增长神器 —— 灰度发布 + A/B testing: https://www.leiphone.com/news/201511/egQAOzoaf5oDikw3.html

[9]

Traefik 文档: https://docs.traefik.io/

腾讯云原生

汇聚腾讯云原生技术

最新资讯、最佳实践、最真案例、最火活动

扫描二维码 关注我们