作者:政采云|汪勋
近年来, 互联网极速发展,为了跟进业务快速增长的发展步伐,新的技术如雨后春笋般不断的涌现,一眼望去,漫天星光,群星争艳。以容器为核心的云原生技术成长迅速,其中 Kubernetes 作为新的基础设施,容器编排事实上的标准, 无疑是最耀眼的那颗星。
然而,Kubernetes 虽然很好的解决了大规模应用部署,资源管理及调度的问题,但是其对业务交付并不友好,Kubernetes 自身的部署也比较复杂,在不断涌现的围绕 Kubernetes 生态的应用中, 始终缺少了可以将业务、中间件、集群整合起来一体化交付的应用。
在当下,由阿里云智能云原生应用平台团队发起, 政采云、谐云科技合作共建的 sealer 开源项目补充了 Kubernetes 在一体化交付领域的短板,sealer 以非常优雅的设计方案考虑了集群 + 分布式应用的整体交付。而政采云作为政府采购行业的代表,已成功的利用 sealer 完成了大型分布式应用的整体私有化交付,交付的实践充分证明了:sealer 具备灵活,强大的一体化交付能力。
背景
政采云的私有化交付客户为政企场景,需交付业务规模较大:300+ 业务组件, 20+ 中间件,交付目标的基础设施不同构且不可控,网络限制严格,一些敏感的场景甚至是完全隔离的网络,在这种背景下,业务交付的最大痛点就是部署依赖的处理以及交付一致性的问题。虽然业务统一基于 Kubernetes 进行交付实现了运行环境的一致,但是如何解决部署过程中所依赖的所有镜像、 各种包的统一处理以及交付系统自身的一致性等一系列问题,亟需解决。
如上图所示政采云本地化交付的流程中, 主要分为:用户需求确认-> 提出资源需求给用户 -> 获得用户所提供的资源清单 -> 根据资源清单生成准备配置 -> 准备部署脚本及依赖 -> 实际交付六个步骤。前置准备和实际交付时, 需要消耗大量的人力和时间来准备和进行部署。
私有化交付的痛
云原生时代,docker 的出现解决了单个应用的环境一致性和打包问题,业务的交付不再像传统的交付那样花费大量的时间在部署环境依赖上。而后 Kubernetes 等容器编排系统的出现解决了对底层资源进行统一的调度,对应用运行时进行统一的编排的问题,然而一个复杂的业务, 其交付的本身就是一个工程浩大的问题,以政采云的场景为例:各种 helm chart、RBAC, istio gateway,cni,中间件等各种资源对象的部署和配置,再加上 300 余业务组件的交付,每一次私有化交付带来的都是大量人力和时间成本的消耗。
政采云正处于业务高速发展的时期, 私有化部署项目的需求不断新增,高成本的交付方式越来越难以支撑实际的需要,如何降低交付成本,并保障交付的一致性是运维团队最迫切的需要解决的问题。
发现 sealer
在早期, 政采云使用 ansible 来进行业务的交付,ansible 方案实现了一定程度的自动化并降低了交付成本但是存在如下几个问题:
1、ansible 只解决部署过程问题,需要单独准备部署所需的依赖,依赖的准备和可用性验证产生了额外的成本,且政采云的本地化场景基本都会严格限制外部网络。直接从外网获取依赖的方式也不可行。
2、使用 ansible 应对差异化的需求会非常累, 政采云的私有化交付场景中,各个用户的需求不一, 业务的依赖不一,每一次的交付重新编辑 ansible playbook 都要花费不少的时间进行调试。
3、涉及到复杂的控制逻辑时,ansible 的声明语言比较乏力。
4、部署交付之前需要先准备 ansible 的运行环境。无法做到交付的0依赖。
ansible 更多的是在做一些粘合的事情,更适合逻辑比较简单的运维工作。随着本地化项目不断新增, ansible 交付的弊端开始显现,每个本地化项目都需要大量的时间投入,政采云运维团队开始探索和思考交付体系的优化方向。我们调研了很多的技术方案,但是已有的 Kubernetes 的交付工具都专注于集群本身的交付而不考虑业务层交付。虽然可以基于集群部署工具进行封装,但是这种方案和使用 ansible 进行集群部署后再去部署上层业务并没有本质的区别。
比较幸运的是,我们发现了 sealer 项目, sealer 是一套分布式应用打包交付的解决方案,通过把分布式应用及其依赖一起打包以解决复杂应用的交付问题。其设计理念非常优雅,可以以容器镜像的生态来管理整个集群的打包交付。
在使用 Docker 的时候,我们通过 Dockerfile 来定义单个应用的运行环境和打包,相应的,sealer 的技术原理可以通过类比 Docker 来进行解释, 把整个集群当做一台机器, 把 Kubernetes 定义为操作系统,通过 Kubefile 来定义这个"操作系统"里面的应用并最终打包成镜像,然后像 Docker run 交付单个应用一样,sealer run 就可以将整个集群及应用交付出去。
发现 sealer 的惊喜之余,我们邀请了社区的伙伴来公司进行了交流,sealer 还是一个新项目, 年轻到只诞生了几个月的时间,在实际的体验中我们遇到了不少问题,也踩了不少的坑,落地尝试时,也发现了挺多不满足需求的地方,但是我们并没有放弃,因为我们对 sealer 的设计模式抱有很大的期望和信心, 我们选择了与社区一起协作共建,共同成长。而最终成功的落地实践也证明了,我们的选择非常正确!
社区协作
在决定与社区合作之初,我们对 sealer 进行了全面的测试评估, 结合我们的需求场景, 主要存在如下几个问题:
1、镜像缓存成本太高, 最初 sealer 只提供 cloud build 的方式,即打包 sealer 集群镜像的前提是需要先基于云资源拉起一个集群,我们认为这种方式成本太高,基于这个需求我们提案并且贡献了 lite build 的构建方式,支持通过解析 helm、资源定义 yaml、镜像清单的方式解析镜像并直接缓存。lite build 是成本最低的 build 方式,无需拉起集群, 只需一台要能够运行 sealer 的主机即可完成 build。
2、业务交付完之后,缺少 check 机制,需要手工去检查 Kubernetes 集群的各个组件状态,然后,我们贡献了集群及组件状态的 check 功能。
3、早期 sealer 的一些配置是固化在 rootfs 中的,例如 registry 的部署主机是固定在第一个 master 节点上的,在实际的场景中我们有自定义的需求,于是我们贡献了自定义 registry 配置的功能。
4、基于 sealer 部署完集群后, 还会有向集群中添加节点的需求,因此我们贡献了 sealer join 的功能。
此外,还有必要说一下我们落地时几个很实用,很强大的 sealer 特性:
1、必须提到的一点是 sealer 构建产出的集群镜像完全可以直接 push 到私有的 docker 镜像仓库例如 harbor 中。然后像 docker 镜像一样, 可以基于已有镜像的基础上扩充功能并再次 build。
2、sealer 社区优化了 registry 和 docker, 使其支持多源,多域名的代理缓存,这是一个非常实用的功能,在处理镜像依赖的时候,我们缓存一个镜像需要变动镜像的地址,例如需要把一个公共镜像缓存到私有镜像中,对应的资源对象引用的镜像地址也需要同步变更为私有镜像仓库的地址,但 sealer 内置的 registry 经过优化实现了不需要修改镜像地址也能匹配缓存的功能。此外, sealer 中内置的 registry 作为 proxy 时,可以代理多个私有化的镜像仓库,在具有多个私有仓库的场景中,是很实用的功能。
落地实践
使用 sealer 我们重新定义了交付流程,通过 Kubefile 将业务组件、容器化中间件的交付、镜像缓存等组件的交付直接使用 sealer 来完成。利用 sealer lite build 模式, 自动化的完成依赖镜像的解析及缓存内置。
利用 sealer 屏蔽了大量应用交付的复杂过程逻辑,和依赖处理逻辑,使实施难度极大的简化。实施逻辑的持续简化,使得规模化交付成为可能。在我们的实践场景中,使用新的交付系统,交付周期从 15天/人缩短至 2天/人,实现了包含 20G 业务镜像缓存, 2000G+内存 800+核心 CPU 规模集群的成功交付。下一步我们计划通过持续的简化交付过程,使一个新手只需要简单的培训即可完成整个项目的交付。
未来展望
落地的成功,收获的不仅仅是交付系统的成果, 更体现了开源的力量,探索出了与社区合作共建的新模式。在未来,政采云将继续支持并参与 sealer 社区的建设,结合实际的业务场景,为社区提供更多的贡献。
作为一个新的开源项目,sealer 的现在并不完美,还存在一些待解决和优化的问题,还有更多的需求和业务场景等待我们去实现,希望通过持续的贡献,让 sealer 可以服务于更多的用户场景, 同时也希望有更多的合作伙伴能够参与社区建设,让 sealer 这颗星,更加的璀璨夺目!