Please enable Javascript to view the contents

Tekton 概念篇 - 好大一盘棋

 ·  ☕ 5 分钟

1. 谈谈对 CICD 工具的审美

我在文档 软件产品是团队能力的输出 中提到,软件产品是解决方案的交付承载物,其优劣取决于团队对核心问题的理解。对领域有深入理解,交付的产品才有好的可能。CICD 是一个应用很广泛的领域,在不同的场景下,总有人在琢磨重复造轮子,难以统一。

虽然没有具体的数据,但是我相信这些工具的 Contributor(包括 User、Committer 等)都存在交叉。因为他们关注的都是一类问题,任务编排。

任务编排类的工具可以抽象成下面这张图。

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

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

通过 UDE 可以给一个 CICD 工具评分。

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,接着看下去,相信你会找到答案。

2. 什么是 Tekton

Tekton 的前身是 Knative 的子项目 build-pipeline,主要用来给 Kantive 的 build 模块增加 pipeline 功能。之后独立出来,Tekton 的目标是一个通用的 CI/CD 工具。这是一种常见的产品孵化机制。

目前,私有云市场占有率比较高的 CICD 工具对 Kubernetes 都有所支持,比如 Jenkins、GitLab CI。但是,这些工具只是将 Kubernetes 作为其扩展的一个方面,Kubernetes 作为新的基础设施,需要原生的 CICD 方案。

另一方面,Jenkins 的子项目 JenkinsX 也开始默认使用 Tekton 作为 CI 引擎。使用云原生一等公民 CRD + Controller 实现的 Tekton ,无疑有机会成为云原生的主流编排引擎。

3. 组成及原理

3.1 相关组成

  • Tekton Pipelines

定义 Tekton 的 CRD 资源。下面会详细介绍,Task、TaskRun、Pipeline 等,用来定义数据结构。

  • Tekton Operator

采用 Operator 模式,使用 Controller 监听 CR 数据,执行相关的动作,是编排引擎的核心。

  • Trigger Trigger

pipeline 触发器,可以在 GitHub 推送或者合并 PR 后,触发流水线。

  • Tekton CLI

Tekton CLI 是一个与 Tekton 交互的命令行工具。

  • Tekton Dashboard

Tekton Pipelines 的 Web 图形界面。

  • Tekton Catalog

社区维护的 Tasks 、Pipelines 库,降低用户使用门槛、提高复用率。

  • Tekton Hub

Tekton 的 Web 图形界面。

3.2 核心对象

  • Task

Task 定义任务模板,包含一系列的 Step 步骤。每个 Step 表示一个动作,比如执行命令、推送镜像等。下面是一个示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: task-with-parameters
spec:
  params:
    - name: flags
      type: array
    - name: someURL
      type: string
  steps:
    - name: build
      image: my-builder
      args: ["build", "$(params.flags[*])", "url=$(params.someURL)"]
  • TaskRun

TaskRun 是 Task 的执行实例。通过 taskRef 引用一个 Task,描述执行参数。下面是一个示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  name: run-with-parameters
spec:
  taskRef:
    name: task-with-parameters
  params:
    - name: flags
      value:
        - "--set"
        - "arg1=foo"
        - "--randomflag"
        - "--someotherflag"
    - name: someURL
      value: "http://google.com"
  • Pipeline

Pipeline 完整定义了一个流水线,可以包含一系列的 Task 。下面是一个示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: pipeline-with-parameters
spec:
  params:
    - name: context
      type: string
      description: Path to context
      default: /some/where/or/other
  tasks:
    - name: build-skaffold-web
      taskRef:
        name: build-push
      params:
        - name: pathToDockerFile
          value: Dockerfile
        - name: pathToContext
          value: "$(params.context)"
  • PipelineRun

PipelineRun 是 Pipeline 的执行实例。通过 pipelineRef 引用 Pipeline ,描述执行参数。下面是一个示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  name: pipelinerun-with-parameters
spec:
  pipelineRef:
    name: pipeline-with-parameters
  params:
    - name: "context"
      value: "/workspace/examples/microservices/leeroy-web"
  • PipelineResource,文档中描述未进入 Beta 阶段,目前处于 Alpha

PipelineResource 定义 Task 的输入输出,包括 Git、Pull Request、Image、Cluster、Storage 等类型。下面是一个示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: test-cluster
spec:
  type: cluster
  params:
    - name: url
      value: https://10.10.10.10
    - name: username
      value: admin

在 Task 中可以使用这些自定义变量,下面是一个使用 $(resources.inputs.test-cluster.name) 的示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: deploy-image
  namespace: default
spec:
  resources:
    inputs:
      - name: test-cluster
        type: cluster
  steps:
    - name: deploy
      image: image-with-kubectl
      command: ["bash"]
      args:
        - "-c"
        - kubectl --kubeconfig
          /workspace/$(resources.inputs.test-cluster.name)/kubeconfig --context
          $(resources.inputs.test-cluster.name) apply -f /workspace/service.yaml'
  • Run,目前处于 Alpha
1
2
3
4
5
6
7
8
9
apiVersion: tekton.dev/v1alpha1
kind: Run
metadata:
  name: my-example-run
spec:
  ref:
    apiVersion: example.dev/v1alpha1
    kind: Example
    name: my-example-task

支持用户自己实现 Controller ,读取 Yaml 中的配置,执行相关的动作。这里 Controller 监听的就是 Example 类型 CR 的变动。

3.3 工作原理

上面是一个 Pipeline 的示意图。一个 Pipeline 通常由多个 Task 组成,这些 Task 串、并执行。而每个 Task 中,又有若干个 Step ,Step 是串行执行的。

同时 Pipeline 还定义了输入、输出,通常输入 Git 仓库,输出镜像。在运行时,Pipeline 对象作为一个模板,被 PipelineRun 引用,创建运行实例。如下图:

PipelineRunController 监听 PipelineRun 对象,将 PipelineRun 中所有的 Task 构建为一张有向无环图,创建 TaskRun 。而 TaskRunController 监听 TaskRun 对象的变化,根据 TaskRun 引用的 Task ,创建 Pod 运行 Step 。

4. 好大一盘大棋

我关注 Tekton 有一段时间了,刚开始只是觉得编排几个 Pod,传递一下参数,最后得到一个结果就完事。没什么新意,需要写很多 Yaml 挺麻烦。

最近想通了几个问题,才开始写 Tekton 。下面一起看看,我想了啥吧。

4.1 task - 构建开发者生态

task 是构成 Tekton Pipeline 的原子,编排这些原子,可以用来快速创建流程。

这些 task 并不需要用户自己写,而是可以由其他个人开发者或者厂商提供。类似 GitHub 的 Actions 市场,通过 task 市场,厂商可以推广产品,而用户可以直接拿到可复用的 Task。比如,Cloud Native Buildpacks 就提供了 Task。

4.2 pipeline - 构建用户生态

pipeline 的应用场景不能仅停留在串流程。pipeline 是可以承载解决方案的。如果你了解过基础设施即代码(简称,Iac),那么理解起来会很容易。

通过编排 Task ,解决方案工程师编写 Yaml 得到 Pipeline ,直接拿到 Kubernetes 集群上执行 kubectl apply 命令,然后填写参数创建 PipelineRun ,就可以完成很多事情了。简单列举几项:

  • 搭建购物系统
  • 清理存储
  • 备份 Etcd
  • 部署 Wordpress
  • 重启服务
  • 弹性扩容

pipeline 可以做的事情很多,而且非常好交付。对于某些纳管的集群,在产品体验上会更佳,选中 pipeline 之后,就能一键处理事务。

5. 参考


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