其他分享
首页 > 其他分享> > 私有化场景下大规模云原生应用的交付实践

私有化场景下大规模云原生应用的交付实践

作者:互联网

本文根据作者在 CSDN 云原生 Meetup 深圳站的演讲内容整理,分享云原生趋势下网易数帆在私有化场景下大规模应用的交付实践,包括在实践过程中遇到的问题,如何实现标准化、高效率且高质量的交付方案,以及取得效果。

背景介绍

软件私有化交付部署是建立在企业自有基础设施的基础之上的,是为一个企业客户单独使用而构建的硬件/软件运行环境;因而能够提供对数据安全、合规审计和服务质量的有效控制。

软件的私有化是由市场供需关系决定的。也分为甲方和乙方,甲乙双方各取所需从而使面向企业的私有化市场正常运转,例如以下双方的一些诉求:

甲方(资金提供方)诉求

乙方(产品提供方)诉求

通过以上甲乙方的诉求可以知道,如果乙方刚好可以满足甲方的一个或多个需求,那么就有了合作和软件私有化交付的场景出现。

是否有遇到过如下场景?

测试环境与生产环境隔离。一些企业由于内部的流程或安全规范的要求,测试环境与生产环境是隔离的状态。例如运行节点间隔离或网络策略的隔离,甚至是物理上的隔离需要更换设备才能访问生产环境,这时在测试环境测试验证的服务如何上线到生产环境?

生产环境禁止访问 Git 执行流水线。代码是企业的核心资产之一,保障源代码的安全是企业重点保障的资产;生产环境一般有自己的机房,或者一些第三方的公有云环境,企业一般不会允许将核心源代码暴露到公网上的,这些情况下生产环境是禁止访问内网的 Git 代码托管平台的。而且,在生产环境重新执行CI流水线构建的镜像,并不是 QA 团队在测试环境测试回归验证过的镜像,即使他们的源码相同,但本质上是两个镜像。

在 Kubernetes 中部署应用时涉及较多类型资源管理问题。在 Kubernetes 集群中部署服务并不是简单的将 Image 镜像运行起来就可以了,实际上还会涉及一些其他相关的 Kubernetes 的资源,例如常见的资源有 Deployment、Service、Ingress、Secret、ConfigMap、PV/PVC、ServiceAccount、RBAC等等以及其他扩展服务的相关资源,如 Prometheus-operator 的 ServiceMonitor。这么多类型的文件该如何维护管理才能高效且不出错呢?

应用上线需要符合公司规范。为了保障上线的顺利,符合上线的质量、安全等要求,企业都会对业务上线制定一些流程或者规范。同时,在多人协作的团队中,如果没有一定的规范参考指导,会因为信息不一致导致应用管理混乱。比如最常见的就是镜像的命名规范,同一个服务可能会出现 myapp:v20211129、myapp:v1.3.11、myapp:1.3.11、myapp:v1.3.11-20211129、my_app:v1.3.11 、my-app:v1.3.11 甚至是 yourapp:v1.3.11 。这些镜像 tag 实际上是指同一个 Git Release v1.13.11 的代码版本,但由于没有规范约束导致管理难,而且容易出错。

多部门或子公司开发的产品复用。在企业内部一个部门开发了好的一款优秀的应用,其他部门也希望能够使用这个应用,特别是大型企业有多个子公司时尤为明显。这类应用例如:日报周报系统、设备日志系统、发票管理系统、ERP系统等等。这时如何将这些应用分享给其他部门会成为一个挑战,如果交付过程太过复杂就会导致推广受限,进而在集团层面产生资源的浪费。

软件私有化交付到客户环境。如前文提到的 ERP 系统、网易数帆轻舟平台等,这些 toB 私有化产品在交付时会有很多的困难,如何高效高质量的将交付软件到客户环境成为这类企业核心关注的重点之一。

本文主要探讨的就是网易数帆轻舟团队在私有化场景下大规模应用的交付实践,在实践过程中同样会涉及到上述的这些问题,通过本文提供的实践给上述的场景提供一些参考。

软件私有化交付的痛难点

软件私有化交付时一般都不会太顺利,在不同的阶段,不同的角色或维度会有各种各样问题,这些问题有些可能会决定整个项目是否延期,有些问题甚至影响项目能否成功。

在项目早期,如果能评估到一些痛难点,提前准备相关的应对策略,将会给产品的私有化交付提供很大的帮助。

站在交付方,以私有化交付全局的维度来分析项目交付前后的痛难点,可以分三大类,分别是用户侧、交付侧和工程售后侧。

用户侧痛难点

交付侧痛难点

工程售后侧痛难点

由于上述的一些原因导致软件在私有化交付时交付周期长,交付质量差、交付成本高。如果成本太高,这个项目可能就由于投入太多而亏损。

为了保障软件私有化的正常交付,在进行架构设计和技术选型时应该结合当前主流技术体系,选择合适的解决方案。

基于 Helm 的应用封装、交付、升级与环境维护

软件应用交付现状

软件的交付部署有多种方式,按照交付方式可以分为传统基础交付、自动化交付和云原生交付三种。

传统基础交付。传统的应用交付是应用交付的基础方式,比如常用的 rpm 软件包或者直接二进制的方式安装运行,比较适合场景相对固定的基础设施。如果有较多的软件包依赖,一般还会搭建一些 YUM 或 DEB 的软件源来快速安装依赖。这类服务的运行一般可以通过 systemd 或者 supervisor 的方式来管理。自动化交付和云原生交付也是在这种方式之上构建的。

自动化交付。如果软件数量较多,安装部署过程有着复杂的逻辑时,使用手动 rpm/yum 安装会比较繁琐且易出错。一般都会使用自动化的方式封装,如 shell 和 Ansible 就是主流的自动化工具。

云原生交付。由于云原生的概念兴起,加上早期的 DevOps 理念的长期熏陶,应用又有了新的交付模式。在云原生的场景下,使用基于流水线的 CI/CD(持续集成与持续交付)模式成为了新的主流,提供了快速高效的应用迭代节奏。云原生交付运行的环境基本上都是基于 Kubernetes 平台,所以也有一些工具可以直接管理和部署应用,比如 KubeVela 。但是,目前真正在企业内生产环境使用的,并且已经属于 CNCF 毕业的项目只有 Helm 。

按照交付部署时是否能够联通各个系统,可分为在线交付和离线交付。

在线交付。在线交付是指在交付部署过程中全部或者部分材料运行在其他服务器上,在安装部署时可以通过网络的方式获取到这些数据。比如常见的基于Nginx 的 YUM 软件源,或者企业内部的 Harbor 镜像仓库,内部的 Gitlab 代码参考,或者公网的 Maven 仓库等。在线交付的好处是不需要提前准备准备这些资源,需要什么资源就到对应的服务器上获取即可。

离线交付。离线交付和在线交付刚好相反,部署时依赖的资源无法外部获取,需要单独准备依赖的资源。没有 YUM 软件源就本地临时搭建一套或者把离线的软件包以及依赖的软件包都下载下来准备好一起安装。在离线场景下有很多服务需要部署时搭建,这也给项目的交付增加了很多的困难。

复杂的客户基础设施带来了复杂的交付场景。如果基于传统和自动化的方式交付,会有一个长长的适配支持兼容清单,例如硬件设备、CPU架构、操作系统等等,这无疑是给企业带来了大量的人力成本消耗。

但是,如果选择了云原生的方式交付应用,就有机会将这种差异的场景人力消耗降到最低。

轻舟应用交付工具选型

基于容器化的交付。面对用户环境的多样,基于 Docker 容器化的方式封装应用能够屏蔽底层基础设施的差异,使交付的制品根据有普适性。

基于 Kubernetes 的运行平台。容器的运行调度、故障的发现与自动处理、弹性的扩缩容、简单的网络环境等环境比较薄弱,而 Kubernetes 刚好解决这些痛点问题。使用 Kubernetes 作为容器的运行环境,能大大降低交付和运维的复杂度。

基于 Helm 的应用构建与交付部署。Helm 能够管理应用的多个不同的 Kubernetes 资源,按照一定的策略来使其在集群中生效。同时,和 rpm/deb 类似也能标准化定义应用,有 Helm 定义的标准化应用就是 Chart。

Helm 的版本选择

首选 Helm3 。在已经有Kubernetes 集群的情况下,只需要一个 kubeconfig 就可以完成环境的交付部署。

Helm 的版本选择有 Helm2 和 Helm3 两种。如果您是新手,当看到这篇文章时,强烈建议您直接选择 Helm3;如果您已经使用了 Helm2,也同样建议您尽快升级到 Helm3。Helm3 不仅在架构上简单了很多,在功能上,使用和易用上都有了很大的优化。

Helm3 于2019 年 11 月 13 日发布。Helm3 公开发布 12 个月后,对 Helm 2 的支持正式结束。

云原生应用的定义与标准化

当使用 Helm Chart 来定义云原生应用时,应该也很希望类似 RPM/DEB 软件包一样可以定义一定的规范标准。幸运的是 Helm 也是支持的,Helm 定义标准分两种,强制标准和推荐标准。

强制标准是指在 Helm Chart 的目录结构上,有一些文件名称放置的位置,内置的函数或变量,模板的渲染方式和资源的优先级等是必须准守的,否则 Helm 无法正常的工作。比如 values.yaml 是默认的参数配置文件,templates 目录是 Kubernetes 的资源模板目录等。

推荐标准是指在强制标准基础之上,企业根据业务需求和管理规范来定义的 Chart 标准。例如应用的命名规范、Kubernetes 资源文件命名规范、环境变了的命名规范、安装升级的逻辑规范等。

对于强制规范是必须遵守的,否则 Chart 无法正常工作。而对于推荐标准是通过人为约束或定义脚手架的方式来管理。新应用使用脚手架的方式创建手,就已经是符合标准的应用。

1.定义变量:export XDG_DATA_HOME=/root/.helm
2.脚手架路径:/root/.helm/helm/starters/chartstarter
3.新建应用:helm create --starter chartstarter myapp

即使在后续的迭代的过程中,应用的一些配置和标准偏移了,也同样可以使用自动化的 Check 的方式来扫描是否违反了标准。

制品的管理

在云原生场景下的软件包制品常见的有 code 源码、编译或打包的可执行文件、构建的系统软件包(可选,如RPM包)、构建的镜像、以及 Helm Chart 包。

最小原子化。在制作 Chart 包时,根据业务的场景特性决定一个 Chart 中包含的业务服务数量。轻舟的 Helm Chart 是基于应用代码仓库作为最小单元,即一个 Chart 中只有一个功能性程序镜像。如果业务系统不是很大,只有几个应用的话,也可以考虑使用子Chart的方式来管理多个服务,如 WordPress Helm Chart。

版本可追溯。最小原子化后,在结合一定的内部规范就可以做到 GitRelease,镜像 Tag,ChartAppVersion 一致,部署或运行时可根据环境 Chart 版本快速溯源代码版本。

例如:

1.Git Release:myapp  Rlease/v1.23.6
2.Image:   myapp:v1.23.6
3.Chart:    myapp-v1.23.6.tgz

Helm Chart 中变量的复用与默认

Helm Chart 的安装时可以指定多个 values.yaml 文件,命令行参数右边的 values.yaml 内容会覆盖左边 values.yaml 的内容。

Chart 中默认的 values.yaml 。values.yaml 只有 myapp 自己 Chart 会用到的配置项 ,配置项尽量以默认的方式配置在values.yaml 中,如默认:

1.global.imagePullSecret
2.global.clusterDnsDomain
3.myapp.resources
4.myapp.mysql.dbname

values-global.yaml 。支持所有的配置项,但并不需要所有配置,如环境差异配置:

1.global.imageRegistry.addr(project,user,passwd)
2.global.mysql.host(port,user,passwd)

values-myapp.yaml。在 values-global.yaml 定义了该字段,但是因为某些原因需要调整的内容。比如有 10 个应用使用到了 MySQL ,但是其中有9个使用一套 MySQL 集群,另外一个应用单独使用一套独立的 MySQL,这时可以单独给这个应用定义一个差异化的 Values-myapp.yaml 来覆盖 values-global.yaml 中的 MySQL 字段即可。如

global.mysql.host(port,user,passwd)

例如 myapp-v1.23.6.tgz Chart 安装命令

helm install -n ns1  myapp  -f values-global.yaml -f values-myapp.yaml ./myapp-v1.23.6.tgz

安装时文件的优先级顺序Chart 中默认的 values.yaml < values-global.yaml < values-myapp.yaml

安装和依赖的管理

在单个 Helm Chart 安装时可以使用 helm install 的方式安装,但是如果 Chart 数量非常多,而且有顺序依赖时手动安装并不合适,这时推荐编写一个自动化的工具来管理和安装,可以是 shell 脚本或者安装部署平台。

轻舟部署使用的 Sail 系统就是一套自研的私有化交付系统,它能够提供环境的部署规划、配置的渲染、安装逻辑的处理、部署任务的执行以及环境信息的统一管理等功能。

Helm 升级应用

软件交付无论是早期的自动化交付还是当今的 Helm 云原生应用交付,带有结构化数据的应用升级都不是一件容易的事情。经常会因为升级时涉及到表字段的更新增大了升级的风险。

在云原生应用交付场景下,Kubernetes 资源文件声明式支持,一般不需要特殊处理,Kubernetes 的滚动更新与 Helm 的差异内容更新可以很好的解决。

但对于 SQL 的处理,由于涉及到业务本身的逻辑,Helm 作为工具也是无能为力。但 Helm 为我们提供了 Hook 的功能,可以让我在安装或升级的某个阶段中插入一定的任务。对于这个任务可以由业务方来决定如何处理 SQL。

对于 SQL 的处理一种思路如下:

SQL文件按照如下规则定义逻辑,Job 使用 pre-upgrade hook 作为升级依据:

SQL 维护方法

那么在升级时就可以通过如下命令来自动升级到目标的版本

$ helm upgrade -n ns1 -f values-global.yaml -f values-myapp.yaml   -set release.chartVersion=v1.23.1 myapp ./myapp-v1.23.7.tgz

环境管理

在基于 Helm Chart 的云原生应用交付的模式下,业务环境的定义可以简单理解为就是 Chart列表和部署时的 Values.yaml 文件。

按照规范定义的 Chart 列表能够说明环境中部署的产品和组件都有哪些以及使用的版本是什么。

Values.yaml 中保存了当前环境中所有的差异性配置,结合 Chart 中默认的配置,就可以还原该环境运行的服务所有的配置信息。

在私有化场景下,环境信息维护尤为重要。在无法实时访问客户环境时,部署时维护的 Chart 列表和 Values 文件能够帮助售后快速的定位和解决问题,在进行 bug 修复或版本升级时也能快速的输出升级材料。

基于 Helm 实践的效果与收益

网易数帆轻舟使用 Helm 的现状

由于早期 Helm3 还未发布前,轻舟私有化交付是基于 Ansible 的方式来交付的,在越来越多的项目交付起来后,场景的差异也越来越多,兼容适配的成本也越来越高。

在 Helm3 发布后,轻舟所有的服务全部进行 Helm 化的改造,以当前的状态和之前相比有很大的进步:

交付的产品能力涵盖云原生的容器云、微服务、服务网格、CICD、API 网关、分布式事务、APM 以及 PaaS 中间件等产品。

基于这套私有化交付工程,支持了公司内外大量的私有化客户项目,保障了项目的顺利交付。

 

总结

商业私有化交付时客户环境基础设施种类繁多、场景复杂,基于容器和 Kubernetes 能极大的降低场景适配和后期运维的工作量。

非在线场景下 Helm 是当前云原生应用的打包和交付的最佳选择之一。

优秀的 Helm Chart 实践经验需要案例积累,并能够传承,推荐基于代码的方式传承经验。

 

作者简介:赵文宇,网易数帆轻舟交付解决方案专家。负责网易数帆轻舟项目交付和解决方案相关的工作,从0到1构建了轻舟私有化交付体系,给客户提供从项目规划到交付落地的技术支撑。对云原生场景下组件高可用方案与应用打包交付有着丰富经验,对轻舟生态技术体系有着深入的理解,熟悉云原生场景下软件私有化交付模式。

标签:原生,场景,myapp,私有化,Chart,yaml,交付,Helm
来源: https://www.cnblogs.com/163yun/p/15668421.html