開源 CI/CD 構建框架 TekTon 的深刻剖析

簡介html


Tekton 是一個功能強大且靈活的Kubernetes 原生開源框架,用於建立持續集成和交付(CI/CD)系統。 關於Tekton, 網上能夠搜到不少不少介紹文檔,本文主要闡述我對Tekton的實現原理和背後的技術邏輯的一點理解。 tekton.devgit

Tekton定義了Task, TaskRun, Pipeline, PipelineRun, PipelineResource 五類核心對象。Tekton經過對Task和Pipeline的抽象,咱們能夠定義出任意組合的pipeline模板來完成各類各樣的CICD任務。經過TaskRun,PipelineRun,PipelineResource能夠將這些模板套用到各個實際的項目中。github

實現原理web


高度抽象的結構化設計使得Tekton具備很是靈活的特性。那麼Tekton是如何實現workflow的流轉的呢。spring

Tekton利用Kubernetes的List-Watch機制,在啓動時初始化了2個Controller, PipelineRunController和TaskRunController。docker

PipelineRunController監聽PipelineRun對象的變化。在它的reconcile邏輯中,將pipeline中全部的Task構建爲一張有向無環圖(DAG),經過遍歷DAG找到當前可被調度的Task節點建立對應的TaskRun對象。api

TaskRunController監聽TaskRun對象的變化。在它的reconcile邏輯中將TaskRun和對應Task轉化爲可執行的Pod,由kubernetes調度執行。利用Kubernetes的OwnerReference機制,pipelinerun own taskrun, taskrun own pod。pod狀態變動時觸發taskrun的reconcile邏輯,taskrun狀態變動時觸發pipelinerun的reconcile邏輯。性能優化

DAG支持架構

Tekton對DAG的支持相對比較簡單。在Tekton中一個Pipeline就是一張DAG,Pipeline中的多個Task但是DAG中的節點。Task默認併發執行,能夠經過 RunAfterFrom 關鍵字控制執行順序。併發

示例:

- name: lint-repo
taskRef:

name: pylint

resources:

inputs:
  - name: workspace
    resource: my-repo
  • name: test-app
    taskRef:
    name: make-test
    resources:
    inputs:

    - name: workspace
      resource: my-repo
  • name: build-app
    taskRef:
    name: kaniko-build-app
    runAfter:

    • test-app

resources:

inputs:
  - name: workspace
    resource: my-repo
outputs:
  - name: image
    resource: my-app-image
  • name: build-frontend
    taskRef:
    name: kaniko-build-frontend
    runAfter:

    • test-app

resources:

inputs:
  - name: workspace
    resource: my-repo
outputs:
  - name: image
    resource: my-frontend-image
  • name: deploy-all
    taskRef:
    name: deploy-kubectl
    resources:
    inputs:

    - name: my-app-image
      resource: my-app-image
      from:
        - build-app
    - name: my-frontend-image
      resource: my-frontend-image
      from:
        - build-frontend

渲染出的執行順序爲:

| |

v            v
 test-app    lint-repo
/        \\

v v
build-app build-frontend
\ /

v        v
deploy-all

相比於Argo等專一在workflow的項目而言,Tekton支持的任務編排方式是很是有限的。常見的循環,遞歸,重試,超時等待等策略都是沒有的。

  • 條件判斷

Tekton支持 condition 關鍵字來進行條件判斷。Condtion只支持判斷當前Task是否執行,不能做爲DAG的分支條件來進行動態DAG的渲染。

* condition檢查失敗(exitCode != 0),task不會被執行,pipelineRun狀態不會由於condition檢查失敗而失敗。
* 多個條件之間 「與」 邏輯關係

PipelineResource在Task間數據交換

做爲CICD的工具,代碼在何時Clone到WorkSpace中,如何實現的? Tekton中抽象了PipelineResource進行任務之間的數據交換,GitResource是其中最基礎的一種。用法以下。

  • 聲明一個Git類型的PipelineResource:

kind: PipelineResource
metadata:
name: skaffold-git-build-push-kaniko
spec:
type: git
params:

    • 在Task中引用這個Resource作爲輸入:

    kind: Task
    metadata:
    name: build-push-kaniko
    spec:
    inputs:

    resources:
    - name: workspace
      type: git

    steps:

    • name: build-and-push
      image: registry.cn-shanghai.aliyuncs.com/kaniko-project-edas/executor:v0.17.1
    • 代碼會被clone在/workspace目錄。

    Tekton是如何處理這些PipelineResource的呢,這就要從Taskrun Controller如何建立Pod提及。

    Tekton中一個TaskRun對應一個Pod,每一個Pod有一系列init-containers和step-containers組成。init-container中完成認證信息初始化,workspace目錄初始化等初始化工做。

    在處理step-container時,會根據這個Task引用的資源 Append或者Insert一個step-container來處理對應的輸和輸出,以下圖所示。

    Task中Step執行順序控制

    Tekton源自Knative Build,在Knative Build中使用Init-container來串聯Steps保證Steps順序執行,在上面的分析中咱們知道Tekton是用Containers來執行Steps,Pod的Containers是並行執行的,Tekton是如何保證Steps執行順序呢?

    這是一個TaskRun建立的Pod的部分描述信息,能夠看到全部的Step都是被/tekton/tools/entrypoints封裝起來執行的。 -wait_file指定一個文件,經過監聽文件句柄,在探測到文件存在時執行被封裝的Step任務。 -post_file指定一個文件,在Step任務完成後建立這個文件。經過文件序列/tekton/tools/${index}來對Step進行排序。

    - args:

    - -wait\_file
    - /tekton/tools/0
    - -post\_file
    - /tekton/tools/1
    - -termination\_path
    - /tekton/termination
    - -entrypoint
    - /ko-app/git-init
    - --
    - -url
    - https://github.com/GoogleContainerTools/skaffold
    - -revision
    - v0.32.0
    - -path
    - /workspace/workspace
    command:
    - /tekton/tools/entrypoint
    image: registry.cn-shanghai.aliyuncs.com/kaniko-project-edas/git-init:v0.10.2
    name: step-git-source-skaffold-git-build-push-kaniko-rz765
    • args:

      • -wait_file
      • /tekton/tools/1
      • -post_file
      • /tekton/tools/2
      • -termination_path
      • /tekton/termination
      • -entrypoint
      • /kaniko/executor
      • --
      • --dockerfile=Dockerfile
      • --destination=localhost:5000/leeroy-web
      • --context=/workspace/workspace/examples/microservices/leeroy-web
      • --oci-layout-path=$(inputs.resources.builtImage.path)
    command:
    - /tekton/tools/entrypoint
    image: registry.cn-shanghai.aliyuncs.com/kaniko-project-edas/executor@sha256:565d31516f9bb91763dcf8e23ee161144fd4e27624b257674136c71559ce4493
    name: step-build-and-push
    • args:

      • -wait_file
      • /tekton/tools/2
      • -post_file
      • /tekton/tools/3
      • -termination_path
      • /tekton/termination
      • -entrypoint
      • /ko-app/imagedigestexporter
      • --
      • -images
      • '[{"name":"skaffold-image-leeroy-web-build-push-kaniko","type":"image","url":"localhost:5000/leeroy-web","digest":"","OutputImageDir":"/workspace/output/builtImage"}]'
    command:
    - /tekton/tools/entrypoint
    image: registry.cn-shanghai.aliyuncs.com/kaniko-project-edas/imagedigestexporter:v0.10.2
    name: step-image-digest-exporter-lvlj9

    實踐


    使用Tekton構建代碼並部署到SAE

    Serverless 應用引擎( SAE ) 是阿里雲上一款面向應用的 Serverless PaaS 平臺,幫助 PaaS 層用戶免運維 IaaS,按需使用,按量計費,實現低門檻微服務應用上雲,有效解決成本及效率問題。支持 Spring Cloud、Dubbo 和 HSF 等流行的開發框架,真正實現了 Serverless 架構和微服務架構的完美融合。

    接下來將使用Tekton部署一個Spring Cloud微服務應用到SAE平臺。

    示例中的演示代碼地址:https://github.com/alicloud-d...

    • 前置條件
    1. 在Kubernetes集羣上安裝Tekton
    2. 建立一個SAE應用
    • 定義一個Git資源

    apiVersion: tekton.dev/v1alpha1
    kind: PipelineResource
    metadata:
    name: spring-cloud-demo
    spec:
    type: git
    params:

    • 定義構建和部署Task

    根據SAE官方文檔進行部署。

    apiVersion: tekton.dev/v1alpha1
    kind: Task
    metadata:
    name: build-deploy-sae
    spec:
    inputs:

    resources:
    - name: source
      type: git

    steps:

    • name: build-and-deploy
      image: maven:3.3-jdk-8
      command: ["mvn", "clean", "package", "-f", "source", "toolkit:deploy", "-Dtoolkit_profile=toolkit_profile.yaml", "-Dtoolkit_package=toolkit_package.yaml", "-Dtoolkit_deploy=toolkit_deploy.yaml"]
      securityContext:
      runAsUser: 0
    • 定義TaskRun運行任務

    apiVersion: tekton.dev/v1alpha1
    kind: TaskRun
    metadata:
    name: build-deploy-sae
    spec:
    taskRef:

    name: build-deploy-sae

    inputs:

    resources:
    - name: source
      resourceRef:
        name: spring-cloud-demo
    • 導入到kubernetes中運行

    kubectl apply -f source-2-service-taskrun.yaml

    • 查看日誌

    kubectl logs build-deploy-sae-pod-85xdk step-build-and-deploy

    構建日誌:

    部署日誌:

    [INFO] Start to upload [provider3-1.0-SNAPSHOT.jar] using [Sae uploader].
    [INFO] [##################################################] 100.0%
    [INFO] Upload finished in 3341 ms, download url: [https://edas-hz.oss-cn-hangzh..._APP_ID/37adb12b-5f0c-4711-98ec-1f1e91e6b043/provider3-1.0-SNAPSHOT.jar]
    [INFO] Begin to trace change order: e2499b9a-6a51-4904-819c-1838c1dd62cb
    [INFO] PipelineName: Batch: 1, PipelineId:f029314a-88bb-450b-aa35-7cc550ff1329
    [INFO] Waiting...
    [INFO] Waiting...
    [INFO] Waiting...
    [INFO] Waiting...
    [INFO] Waiting...
    [INFO] Waiting...
    [INFO] Waiting...
    [INFO] Waiting...
    [INFO] Deploy application successfully!
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 32:41 min
    [INFO] Finished at: 2020-04-15T10:09:39+00:00
    [INFO] Final Memory: 47M/190M
    [INFO] ------------------------------------------------------------------------

    • 驗證部署結果

    在SAE控制檯查看變動記錄:

    驗證應用訪問:

    總結


    區別於傳統的CICD工具(Jenkins),Tekton是一套構建CICD系統的框架。Tekton不能使你當即得到CICD的能力。可是基於Tekton能夠設計出各類花式的構建部署流水線。得益於Tekton良好的抽象,這些設計出的流水線能夠做爲模板在多個組織,項目間共享。 Tekton源自Knative的Build-Template項目,設計之初的一個重要目標就是令人們可以共享和重用構成pipeline的組件,以及Pipeline自己。在Tekton的RoadMap中Tekton Catelog就是爲了實現這一目標而提出的。

    區別於Argo這種基於Kubernetes的Workflow工具,Tekton在工做流控制上的支持是比較弱的。一些複雜的場景好比循環,遞歸等都是不支持的。更不用說Argo在高併發和大集羣調度下的性能優化。這和Tekton的定位有關,Tekton定位於實現CICD的框架,對於CICD不須要過於複雜的流程控制。大部分的研發流程能夠被若干個最佳實踐來覆蓋。而這些最佳實踐應該也必須能夠在不一樣的組織間共享,爲此Tekton設計了PipelineResource的概念。PipelineResource是Task間交互的接口,也是跨平臺跨組織共享重用的組件,在PipelineResource上還能夠有不少想象空間。

    做者信息:九辯,阿里巴巴高級開發工程師,負責阿里雲EDAS(企業級分佈式應用服務)應用生命週期研發工做,長期關注雲時代微服務的部署和治理工做。

    相關文章
    相關標籤/搜索