Please enable Javascript to view the contents

基于 Tekton 的 CICD 平台

 ·  ☕ 6 分钟

1.背景

1.1 目前使用 Jenkins 遇到的问题

  • 编排引擎不稳定

Jenkins 是由 Java 编写的编排引擎,在 Full GC 时会 Stop The World(STW)。在大规模构建时,STW 可能会导致 Jenkins 无法处理新的请求。

  • 大量构建卡顿

Jenkins 使用磁盘文件存储数据,每条流水线、每次构建都会占用一个文件目录,产生大量文件。通常流水线数量有限,但在构建达到 10000+ 级别时,会感受到 IO 对 Jenkins 的影响。

  • 开发插件成本高

虽然 Jenkins 已经有很多的插件,但是面对内部庞大的各种系统,CICD 系统依然有开发插件的需求。开发 Jenkins 插件,需要掌握 Java 语言,学习 Jenkins 的插件机制。开发插件就是以 Jenkins 的运行周期为切入点,对其进行扩展。首先根据需要扩展的功能,在 Jenkins Packages 文档中,找到扩展的类。然后,在插件的主类中 extends 扩展类,实现自己的业务逻辑。

  • 并发性能差

由于 Jenkins 本身的限制,在 Kubernetes 上无法运行多个副本。基于 Kubernetes 的 Jenkins 并发量,构建并发量最多达到 400 左右时会出现明显瓶颈,继续提升需要架构层面的较大优化升级。

1.2 对 CICD 的诉求

  • 跨网络

服务上云,但代码不能出公司。需要在云上组装,而在内网构建容器镜像。

  • 可大规模执行流水线

CICD 提供的是一次性运行时。CICD 是自动化系统,执行次数越多,意味着节省的人力时间越多。在未来,CICD 会承载越来越多的场景。集群安装、证书巡检…

  • 零停机运维

之前编排引擎的维护主要集中在凌晨,因为每次重启 Jenkins,都需要花费数分钟时间,在这个时间段内,CICD 系统无法提供服务。

  • 较短时间交付,持续迭代

设计一个庞大而完善的系统并不是初衷,我们希望快速验证想法,投入使用,然后不断地快速迭代,优化并完善系统。

2. 选型比较

2.1 一个好的 CICD 具备哪些特征

一个好的 CICD 工具应该具有如下特点:

  • Outer DSL 简单易掌握 - User
  • Inner DSL 高效易维护 - Developer
  • 生态,能复用的原子要多 - Ecosystem

通过 UDE 可以给一个 CICD 工具评分,下面对常见的几个 CI 进行比较:

  • Jenkins

Outer 是 Groovy 编写的 Jenkinsfile 文件,Inner 是 Java 编写的 Jenkins。UD 都不算好,Jenkins 难以维护,但插件庞大,E 大大加分。

  • GitLab CI

Outer 是 Yaml 编写的 .gitlab-ci.yml 描述文件,Inner 是 Ruby 编写的解析引擎,使用 Go 写的 Runner。U 很好,上手很快,之前也写过一些文档,GitLab。D 不算好,Ruby 性能一般,会的人越来越少。E 就比较糟糕了,虽然有类似 Jenkins share library 的 template 提供原子级别的复用,但跨团队的复用率很低,不利于构筑社区生态。

  • Tekton

Outer 是 Yaml 编写的 PipelineRun 描述,Inner 是 Go 编写的 Controller,不断地在 Kubernetes Pod 上执行编排流程。插件方面,目前 Tekton 社区提供有一百多个插件以供复用。

2.2 Tekton vs Jenkins

在最近几年的编排引擎市场份额调查中,Jenkins 连续多年超过一半的使用率,这是 Jenkins 近 20 年积累、头部虹吸效应的结果。但进入云原生时代之后,基础设施发生了变化,Jenkins 并没有很好的跟上脚步,Jenkins X 放弃 Jenkins 转而使用 Tekton 作为默认编排引擎。而自研编排引擎成本过大,因此,这里主要将 Jenkins 与 Tekton 进行对比:

功能 Jenkins Tekton
编程语言 Java Golang
开发插件语言 Java Shell、Yaml
流水线描述语言 Groovy、Shell Yaml、Shell
插件生态 很多插件,LDAP、GitLab 不足
插件数量 1500+ 100+
插件之间的兼容性 可能会有冲突,不能随便升级 完全兼容
二次开发 封装 Api 组合 Task
是否高可用 集成 Gearman、主从模式 依赖 Kuberntes 的高可用
单实例并发构建规模 几百并发 依赖 Kuberntes 的 Pod 管理能力,可以很大
数据存储 本地磁盘 Etcd
是否支持自动触发 支持 支持
是否有商业支持

3. 基于 Tekton 的解决方案

3.1 Tekton 包含哪些组件

  • Pipeline

CI/CD 工作流程的基础模块,用来创建任务、流水线。

  • Triggers

CI/CD 工作流程的事件触发器,可以用来根据事件自动触发流水线。

  • CLI

用于管理 CICD 工作流的命令行工具。

  • Dashboard

一个通用的流水线 Web 管理工具。

3.2 Tekton 流水线由什么构成

上面是一个 Pipeline 的示意图。一个 Pipeline 通常由多个 Task 组成,一个 Task 具有一个独立 Pod 运行环境。这些 Task 串、并执行。而每个 Task 中,又有若干个 Step ,Step 是串行执行的。一个 Step 具有一个独立 Container 运行环境。
下面是一个执行简单脚本的流水线示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  name: test-demo
spec:
  pipelineSpec:
    tasks:
      - name: test-1
        taskSpec:
          steps:
            - name: run
              image: alpine
              script: |
                                echo "Hello World."

3.3 支持多集群构建

支持多集群能能显著增强 CICD 的可扩展性、可维护性。Tekton 已经将所有资源 CRD 抽象,这意味着我们借助于 KubeFed v2、Karmada、Open Cluster Management 等开源组件,可以非常容易实现流水线资源在多集群下的分发。

如上图,我们将全部流水线资源创建在 host 集群,用于元数据的管理。然后通过开源的多集群管理方案,对不同集群上的资源进行分发。每个集群是一个单独的构建环境,这样能够有效地分散 CICD 流水线带来的负载压力。

按照目前的资源规划,公司内网的服务器资源非常有限,我们需要尽可能使用云上的资源进行组装。host 集群、部分 worker 集群在公网,而执行 CI 构建的集群必须在内网。

这里需要将 host 集群与 worker 集群之间能够网络打通。通过隧道打通网络是危害内网安全的操作,因此利用开源多集群组件实现不具备可行性。但我们并未就此止步,这种设计给了我们启发。

3.4 实现的架构

如上图,是一个我们目前实现、并准备继续优化的架构。主要分为三个部分:

  • web

提供用户操作界面,通过图形化的方式编辑、描述流水线。

  • apiserver

提供 web API 接口、worker 拉取任务的接口

  • worker

拉取当前集群的流水线任务、执行并推送结果

用户在 web 端创建流水线,通过 Apiserver 保存在 DB,同时产生一条同步事件。Worker 通过轮询的方式,从 Apiserver 拉取消息队列中的同步任务,接着在当前集群执行。执行完成之后,将执行的结果和相关的日志推送 Apiserver 保存至 DB 中。最终,用户在页面上可以从 DB 中直接查看执行的结果。

值得注意的是,一个集群上可以跑多个 worker 服务,对集群的要求也只是能连通 Apiserver,因此在公网、内网都可以接入 worker 集群进行构建。

4. 总结与展望

4.1 功能丰富、性能优化

好用的产品是在需求之下不断地打磨出来的。我们会继续的收集大家对 CICD 的需求,并完善 CICD 系统。

  • 审批功能

流程控制是 CICD 必备的功能之一。通过 runAfter,可以控制 task 任务之间的执行顺序和依赖,但审批功能 Tekton 社区并没有提供解决方案。我们针对审批功能提供了两种方案,正在设计和实现中。

  • 接入物理机构建

由于目前主要服务于 web和后端项目的镜像构建,暂时没有提供物理机的接入。但我们已经考虑了方案,只等用户需求。

  • 子流水线

子流水线允许将一条流水线拆分成多个,不同的子流水线可以在不同的 worker 集群执行,同时可以更好的控制流程。

  • 流水线集群管理

目前的流水线后端是支持多集群的,但是前端暂时没有提供设置入口。支持多集群构建是这次设计的亮点之一,我们也希望能够尽快提供用户自助接入、自助管理、自助使用。

4.2 承载更多功能的 CICD 系统

除了这次的具体设计实现,我还想聊一下对 CICD 系统的理解。通常,我们认为 CICD 系统只是用来做构建、发布。但实际上,CICD 提供的是一种运行时,与 Serverless 相对应。这种运行时,可以承载很多的应用场景,甚至替代一些 SaaS 。这里说两个场景:

  • 交付

在 Kubernetes 集群下,我们可以使用 Helm 进行交付应用。但是如何交付 Kubernetes 呢?面向 VM/裸金属服务器的服务如何交付呢?答案就是流水线。

服务商通过 Task 插件封装各自的服务,提供给集成商。而集成商通流水线编排各种服务,面向客户提供交付的解决方案。

  • 自动化运维

1.故障处理
2.增删节点
3.申请资源
4.服务变更


微信公众号
作者
微信公众号