来也科技做为一家 ToB 企业,我们致力于帮助更多的客户实现智能时代的人机协同。在我们服务的客户中,有许多因所在行业管制严格,是不能将服务部署在公有云上的。

所以我们必须要为客户提供本地化部署的解决方案,通常简称为:私有部署
从 2018 年我们私有部署了第一家客户,到今天,来也科技共部署、维护了数百个客户环境,支持了上千家客户的本地化 PoC 。

从第一次私有部署交付耗费 70 人天,到现在,每次部署平均消耗不超过 1 人天,我们是如何一步步完善和进化的?

图片

来也科技私有部署架构的演变
手工部署阶段
第一次接到本地化部署需求时,我们还没有私有部署的概念。理所当然的认为可以将 SaaS 平台整个复制过去。

但当我们初步与研发团队沟通技术细节时,就发现存在大量的问题。

首先描述下当时我们的SaaS基础环境:主要是基于虚拟机 + Docker + 一系列云服务(数据库、负载均衡等)。服务采用的是微服务架构,私有部署场景大概有80+个进程。

此时适配私有部署的问题:

  • 服务打包:需要跟研发沟通,确认每个服务要部署的版本,手动导出镜像到服务器,再生成私有化部署的服务包。
  • 配置文件内容修改:由于每个环境都是独立存在的,服务器、中间件的地址以及账号密码等信息在每个环境中都不一致,当时通过 sed、awk 命令批量替换配置文件内容操作不规范,导致错误频发,反复调试。
  • Nginx代理调整:服务进程会拆分到多个服务器节点,路由全靠手动配置。
  • 服务器环境初始化脚本:在客户环境中安装Docker + 各种中间件,由于客户系统版本不同,而且大部分客户不提供外网环境,每个包都要定制化。
  • 部署后的验证:因为自动化测试覆盖不完全,部署后需要测试同学到客户现场配合验收。


应用程序适配阶段
手工部署阶段大概持续了 1 年左右的时间,后由于客户对私有化部署场景的需求量激增,之前的模式无法满足需求。

我们针对前期积累的问题在做一系列内部讨论,进行了第一次优化:

  • 半自动打包:在发布前,提供一个Excel,让研发将测试通过的代码版本填到表格中,由程序读取tag后自动生成私有化部署包。
  • 配置文件模板化:每个后端服务的配置文件均使用 Jinja2 语法来进行编写,模板中的 key 和 value 由运维同学负责维护。针对不同的环境,在部署时通过模板渲染的方式生成配置文件。
  • 增加对服务器及环境的限制:针对客户提供的服务器系统、硬件等约定了一个支持的范围,并针对支持的系统开发了一系列的自动化脚本,可以批量初始化环境。
  • 完善的自动化测试:使用 golang 开发了一套覆盖全部 api 的自动化集成测试工具(siber),减少了90%的人工测试时间。


上述工作完成后,基本满足了当时的部署需求。可接下来,随着公司产品线的扩张,更多的问题又逐渐暴露了出来:

  • 多产品线的组合部署以及按业务功能的拆分部署
  • 支持的场景比较单一,无法适配客户对于poc场景快速部署的需求


标准化阶段
考虑到后期产品线还会持续增加,为了避免反复对部署脚本添加功能,又做了第二次优化:

  • 全面拥抱 k8s 。
  • 把所有业务线下能独立的功能全部拆分成单独的模块,并独立维护模块之间的依赖关系。
  • 按部署场景,把支持的部署范围缩小成单机部署、高可用部署两种场景。单机采用 docker-compos 编排,高可用使用 k8s 。
  • 开发一套系统,可以在系统上选择要部署的模块、场景来进行自动化打包。


但很快,我们又迎来了新的挑战:

  • SaaS 迭代速度太快,私有化部署的发版完全跟不上节奏。
  • 已部署客户的环境版本太多,维护成本超出预期,急需快速升级。
  • 一些早期部署的客户,由于运行时间过长,导致磁盘使用率过高,影响业务。
  • 高可用的中间件宕机一台节点,外部并不会有感知。这就导致再次发生问题时,高可用机制变成了空壳。
  • AI 能力模型定制化场景较多。


自动化阶段
在吸取了以上的经验教训后,我们很快分析出了问题:标准化做的不到位,我们被客户的环境限制住了脚步。

满足大部分客户的需求以及市场对于产品新功能的需求,让私有化部署的版本迭代更快成了我们的新目标。

根据以往的经验,并参考售前同学提供的一线建议(如客户经常会提出哪些要求及限制等),我们开始了第三轮优化:

  • 完全放弃 docker-compose 编排的单机部署,改为单机 k8s、高可用 k8s 两种部署方式。这个做法当时收到了很多反对的意见,比如部署过程问题较多、维护复杂等等。不过好处也很明显,就是发版速度提高了很多,从原来的1、2个月变成了现在的1、2周。
  • 在内部 CI 流程中记录 SaaS 发版的服务的 tag、配置文件模板、路由、模型之间的关系,并在私有部署发版时通过选择指定的 tag 来进行发版。
  • 让研发同学配合,提供可回滚的数据库迁移工具,并针对已有客户的部署场景,产出定制化升级方案。推动客户升级。
  • 部署监控工具、在售后服务中增加巡检的服务。


同时,我们还在内部定义了一些标准:

  • 环境标准化:统一使用 k8s 环境作为底层,istio 作为代理层,服务通过 helm 管理。
  • 服务标准化:统一端口号、配置文件路径、日志路径。统一使用无状态模式运行。
  • 外部依赖标准化:支持客户自己提供的中间件,并对客户的中间件进行检查,判断是否满足部署要求。支持客户自己提供的 k8s 集群,只要提供集群 api 的访问权限,我们就能部署。


现阶段做法
我们在今年上半年,大概花了4个月的时间,产出了三个标准产品:

  • 私有部署前置检查工具:验证客户环境是否满足私有化部署要求,并承担初始化环境的角色。工具运行完成后,会在本地记录环境信息,如服务器信息、中间件信息、端口信息、代理信息等等。
  • 私有部署自动化打包工具:基于 SaaS 发版时记录的服务、配置、路由、模型之间的关系,根据指定的 tag 生成私有化部署包。
  • 自动化部署工具:基于前置检查工具生成的结果和客户选择的功能来进行自动化的私有化部署。


这三个产品从最开始的手工部署阶段,到应用程序适配阶段,再到标准化阶段,经过了多次重构,现在已能覆盖到 90% 以上的企业客户,60% 以上的政府、金融客户。

但我们仍然整理出一些需要注意和持续改进的地方:

私有部署的技术挑战

  1. 现存问题
    1. 产品组件多,客户量多。
    2. 服务没有完全标准化。比如 UiBot Commander 的定制化部署、IDP 产品的第三方模块。
    3. 客户环境多样性:不同的安全限制,各种修改配置。
  2. 适配性做的不好
    1. 当前只支持标准的 Centos/Red Hat 7.x 系统。但如 Ubuntu、CentOS 8.x 甚至 Windows 都有适配需求。
    2. 对于政府行业国产化操作系统、硬件的适配。
    3. 服务层面对中间件的选型、版本的要求,范围比较小。
    4. 当前无法对客户提供的容器云进行适配。


我们会针对所有收集到的、设想到的问题点持续优化,更快、更好的为客户完成私有化部署需求。


本文作者:李烨
本文编辑:刘桐烔