天天看點

Tekton入門Tekton入門

Tekton入門

什麼是流水線

流水線是把一個重複的過程分解為若幹個子過程,使每個子過程與其他子過程并行進行的技術,也叫 Pipeline。以“建構鏡像更新應用”為例:

Tekton入門Tekton入門

當一次代碼變更之後,jenkins都需要拉取最新的代碼,進行代碼編譯,建構鏡像,推送鏡像到鏡像倉庫,最後更新k8s資源對象。而且每次代碼變更,此過程都是不變的。是以使用流水線工具可以極大的提升這一過程的效率,隻需要進行簡單的配置便可以輕松的完成重複性的工作,這樣的過程也被稱之為 CI。

什麼是Tekton

Tekton 是一個基于 Kubernetes 的雲原生 CI/CD 開源架構,屬于 CD 基金會的項目之一。Tekton 通過定義 CRD 的方式,讓使用者以靈活的自定義流水線以滿足自身 CI/CD 需求。

Tekton使用人員

  • 為組織中的開發人員建構 CI/CD 系統的平台工程師。
  • 使用這些 CI/CD 系統完成工作的開發人員。

Tekton優點

  • 可定制Tekton 實體是完全可定制的,具有高度的靈活性。平台工程師可以定義高度詳細的建構塊目錄,供開發人員在各種場景中使用。
  • 可重複使用的Tekton 實體是完全可移植的,是以一旦定義,組織内的任何人都可以使用給定的管道并重用其建構塊。這使開發人員無需“重新發明輪子”即可快速建構複雜的管道。
  • 可擴充Tekton Catalog 是社群驅動的 Tekton 建構塊存儲庫。您可以使用 Tekton Catalog 中的預制元件快速建立新管道并擴充現有管道。
  • 标準化Tekton 在您的 Kubernetes 叢集上作為擴充安裝和運作,并使用完善的 Kubernetes 資源模型。Tekton 工作負載在 Kubernetes 容器内執行。

Tekton組成

Tekton 由以下元件組成:

  • **Tekton Pipelines是Tekton**的基礎。它定義了一組 Kubernetes自定義資源 ,用作建構塊,您可以從中組裝 CI/CD 管道。
  • **Tekton Triggers**允許您根據事件執行個體化管道。例如,您可以在每次将 PR 合并到 GitHub 存儲庫時觸發管道的執行個體化和執行。您還可以建構啟動特定 Tekton 觸發器的使用者界面。
  • **Tekton CLI**提供了一個名為 的指令行界面

    tkn

    ,它建構在 Kubernetes CLI 之上,允許您與 Tekton 進行互動。
  • **Tekton Dashboard**是 Tekton Pipelines 的基于 Web 的圖形界面,可顯示有關管道執行的資訊。它目前正在進行中。
  • **Tekton Catalog**是一個由社群貢獻的高品質 Tekton 建構塊的存儲庫 -

    Tasks

    Pipelines

    ,等等 - 可以在您自己的管道中使用。
  • **Tekton Hub**是一個基于 Web 的圖形界面,用于通路 Tekton Catalog。
  • **Tekton Operator**是一種 Kubernetes Operator 模式 ,允許您在 Kubernetes 叢集上安裝、更新和删除 Tekton 項目。

Tekton Pipelines基本概念

Tekton入門Tekton入門
  • Tekton Pipelines最基本的四個概念:Task、TaskRun、Pipeline、PipelineRun。
    • Task: Task 為建構任務,是 Tekton 中不可分割的最小機關,正如同 Pod 在 Kubernetes 中的概念一樣。在 Task 中,可以有多個 Step,每個 Step 由一個 Container 按照順序來執行。
    • Pipeline: Pipeline 由一個或多個 Task 組成。在 Pipeline 中,使用者可以定義這些 Task 的執行順序以及依賴關系來組成 DAG(有向無環圖)。
    • PipelineRun: PipelineRun 是 Pipeline 的實際執行産物,當使用者定義好 Pipeline 後,可以通過建立 PipelineRun 的方式來執行流水線,并生成一條流水線記錄。
    • TaskRun: PipelineRun 被建立出來後,會對應 Pipeline 裡面的 Task 建立各自的 TaskRun。一個 TaskRun 控制一個 Pod,Task 中的 Step 對應 Pod 中的 Container。當然,TaskRun 也可以單獨被建立。
  • PipelineResource概念
    Tekton入門Tekton入門
    PipelineResource 代表着一系列的資源,主要承擔作為 Task 的輸入或者輸出的作用。它有以下幾種類型:
    • git:代表一個 git 倉庫,包含了需要被建構的源代碼。将 git 資源作為 Task 的 Input,會自動 clone 此 git 倉庫。
    • pullRequest:表示來自配置的 url(通常是一個 git 倉庫)的 pull request 事件。将 pull request 資源作為 Task 的 Input,将自動下載下傳 pull request 相關中繼資料的檔案,如 base/head commit、comments 以及 labels。
    • image:代表鏡像倉庫中的鏡像,通常作為 Task 的 Output,用于生成鏡像。
    • cluster:表示一個除了目前叢集外的 Kubernetes 叢集。可以使用 Cluster 資源在不同的叢集上部署應用。
    • storage:表示 blob 存儲,它包含一個對象或目錄。将 Storage 資源作為 Task 的 Input 将自動下載下傳存儲内容,并允許 Task 執行操作。目前僅支援 GCS。
    • cloud event:會在 TaskRun 執行完成後發送事件資訊(包含整個 TaskRun) 到指定的 URI 位址,在與第三方通信的時候十分有用。

Tekton Triggers基本概念

Tekton入門Tekton入門

Tekton Triggers是一個基于事件的觸發器,它可以檢測到事件的發生,并能提取事件中的資訊,

TaskRuns

PipelineRuns

可以根據該資訊進行執行個體化和執行。

Tekton Triggers最基本的四個概念:TriggerTemplate、TriggerBinding、EventListener、Interceptor。

TriggerTemplate:指定要在檢測到事件時執行個體化和執行的資源,如

TaskRuns

PipelineRuns

TriggerBinding:指定要從事件資訊中提取的字段,并将字段資訊傳遞給

TriggerTemplate

,這樣字段就可以在

TaskRuns

PipelineRuns

中使用。

EventListener:在Kubernetes叢集啟動一個事件監聽服務、并暴露服務,将

TriggerTemplate

TriggerBinding

綁定。

Interceptor:事件攔截器,用于過濾事件,運作在

TriggerBinding

之前。

建構流水線

下邊以接收gitlab pr merged事件自動從gitlab拉取代碼、建構鏡像、推送鏡像到harbor倉庫、更新k8s叢集資源為例,示範tekton建構流水線。

定義PipelineResource

  • git-input表示Task的輸入,type=git表示使用git倉庫類型,url表示gitlab的位址,revision表示分支。
    apiVersion: tekton.dev/v1alpha1
    kind: PipelineResource
    metadata:
      name: git-input
      namespace: test-tekton
    spec:
      type: git
      params:
        - name: url
          value: https://xxxx.git
        - name: revision
          value: dev
               
  • image-output表示Task的輸出,type=image表示使用鏡像倉庫類型,url表示倉庫位址。
    apiVersion: tekton.dev/v1alpha1
    kind: PipelineResource
    metadata:
      name: image-output
      namespace: test-tekton
    spec:
      type: image
      params:
        - name: url
          value: xxxx/xxxx
               

配置認證資訊

由于使用了私有gitlab和鏡像倉庫,是以需要配置倉庫的認證資訊。

  • git-basic-user-pass表示gitlab的認證資訊,

    annotations

    tekton.dev/git-tekton.dev/git-

    開頭的key表示git類型的secret,value則是gitlab的位址,

    type

    表示認證類型,支援

    kubernetes.io/basic-auth

    kubernetes.io/ssh-auth

    apiVersion: v1
    kind: Secret
    metadata:
      name: git-basic-user-pass
      namespace: test-tekton
      annotations:
        tekton.dev/git-0: https://xxxx.git
    type: kubernetes.io/basic-auth
    stringData:
      username: xxxx
      password: xxxx
               
  • repo-basic-user-pass表示harbor的認證資訊,

    annotations

    tekton.dev/docker-

    開頭的key表示docker倉庫類型的secret,value則是harbor的位址,

    type

    表示認證類型,支援

    kubernetes.io/basic-auth

    kubernetes.io/dockercfg

    kubernetes.io/dockerconfigjson

    apiVersion: v1
    kind: Secret
    metadata:
      name: repo-basic-user-pass
      namespace: test-tekton
      annotations:
        tekton.dev/docker-0: xxxx
    type: kubernetes.io/basic-auth
    stringData:
      username: xxxx
      password: xxxx
               
  • build-bot表示PipelineRun、TaskRun使用的ServiceAccount,build-bot綁定git-basic-user-pass、repo-basic-user-pass,這樣PipelineRun、TaskRun就能使用相應認證資訊。
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: build-bot
      namespace: test-tekton
    secrets:
      - name: git-basic-user-pass
      - name: repo-basic-user-pass
               
    由于部署應用時使用kubectl、triggers,是以build-bot需要叢集權限,這裡給了一個cluster-admin的權限。
    kubectl create clusterrolebinding build-bot-cluster-admin --clusterrole=cluster-admin --serviceaccount=test-tekton:build-bot
               

定義Task

  • build-push表示建構、推送鏡像任務,

    params

    下表示表示定義變量并設定了預設值,

    $()

    表示引用某個變量,

    workspaces

    類似于k8s中volume,用于存儲、共享資料,支援pvc、configmap、secret,本例由于需要在task之間共享部署的yaml,是以在pipelineRun中指定使用pvc作為存儲實作。
    apiVersion: tekton.dev/v1beta1
    kind: Task
    metadata:
      name: build-push
      namespace: test-tekton
    spec:
      workspaces:
        - name: ws
      resources:
        inputs:
        - name: docker-source
          type: git
        outputs:
        - name: build-image
          type: image
      params:
        - name: pathToDockerfile
          type: string
          default: $(resources.inputs.docker-source.path)/Dockerfile
        - name: pathToContext
          type: string
          default: $(resources.inputs.docker-source.path)
        - name: commitID
          type: string
          default: latest
      steps:
      - name: build-push
        image: registry.cn-hangzhou.aliyuncs.com/tanber_rp/gcr.io.kaniko-project.executor:v0.16.0
        env:
        - name: "DOCKER_CONFIG"
          value: "tekton/home/.docker/"
        command:
          - /kaniko/executor
        args:
          - --dockerfile=$(params.pathToDockerfile)
          - --destination=$(resources.outputs.build-image.url):$(params.commitID)
          - --context=$(params.pathToContext)
      - name: store-image-url
        image: busybox
        script: |  #這裡代碼目錄下deploy為部署檔案,可根據實際情況修改
          cp -r $(resources.inputs.docker-source.path)/deploy/ $(workspaces.ws.path)/
        	url='$(resources.outputs.build-image.url):$(params.commitID)'
          url=${url//\//\\/}
          sed -i "s/image: tanber\/saml_idp:v1/image: ${url}/" $(workspaces.ws.path)/deploy/deploy.yaml
    
               
  • deploy表示部署應用。
    apiVersion: tekton.dev/v1beta1
    kind: Task
    metadata:
      name: deploy
      namespace: test-tekton
    spec:
      workspaces:
        - name: ws
      params:
        - name: pathToDeploy
          type: string
          default: $(workspaces.ws.path)/deploy/
      steps:
      - name: deploy
        image: docker.io/bitnami/kubectl:1.22.1
        securityContext:
          runAsUser: 0
        securityContext:
          runAsUser: 0
        command:
          - kubectl
        args:
          - apply
          - -f
          - $(params.pathToDeploy)
               

定義Pipeline

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: pipeline
  namespace: test-tekton
spec:
  workspaces:
    - name: ws
  resources:
  - name: docker-source
    type: git
  - name: build-image
    type: image
  params:
    - name: mrState
      type: string
    - name: targetBranch
      type: string
    - name: commitID
      type: string
    - name: pathToDockerfile
      type: string
      default: $(resources.inputs.docker-source.path)/Dockerfile
    - name: pathToContext
      type: string
      default: $(resources.inputs.docker-source.path)
    - name: pathToDeploy
      type: string
      default: $(workspaces.ws.path)/deploy
  tasks:
    - name: build-push
      when:
      - input: "$(params.mrState)"
        operator: in
        values: ["merged"]
      - input: "$(params.targetBranch)"
        operator: in
        values: ["dev"]
      taskRef:
        name: build-push
      workspaces:
        - name: ws
          workspace: ws
      params: 
       - name: commitID
         value: $(params.commitID)
       - name: pathToDockerfile
         value: $(params.pathToDockerfile)
       - name: pathToContext
         value: $(params.pathToContext)
      resources:
        inputs:
          - name: docker-source
            resource: docker-source
        outputs:
          - name: build-image
            resource: build-image
    - name: deploy
      when:
      - input: "$(params.mrState)"
        operator: in
        values: ["merged"]
      - input: "$(params.targetBranch)"
        operator: in
        values: ["dev"]
      runAfter:
      - build-push
      taskRef:
        name: deploy
      workspaces:
        - name: ws
          workspace: ws
      params:
       - name: pathToDeploy
         value: $(params.pathToDeploy)
           

定義TriggerTemplate

apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
  name: triggertemplate
  namespace: test-tekton
spec:
  params:
    - name: mrState
    - name: targetBranch
    - name: commitID
  resourcetemplates:
    - apiVersion: tekton.dev/v1beta1
      kind: PipelineRun
      metadata:
        generateName: pipelinerun-
        namespace: test-tekton
      spec:
        serviceAccountName: build-bot
        pipelineRef:
          name: pipeline
        workspaces:
          - name: ws
            volumeClaimTemplate:
              spec:
                accessModes:
                  - ReadWriteOnce
                resources:
                  requests:
                    storage: 1Gi
        params: 
          - name: pathToDockerfile
            value: $(resources.inputs.docker-source.path)/Dockerfile
          - name: pathToContext
            value: $(resources.inputs.docker-source.path)
          - name: pathToDeploy
            value: $(workspaces.ws.path)/deploy
          - name: mrState
            value: $(tt.params.mrState)
          - name: targetBranch
            value: $(tt.params.targetBranch)
          - name: commitID
            value: $(tt.params.commitID)
        resources:
          - name: docker-source
            resourceRef:
              name: git-input
          - name: build-image
            resourceRef:
              name: image-output
           

定義TriggerBinding

apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
  name: triggerbinding
  namespace: test-tekton
spec:
  params:
    - name: mrState
      value: $(body.object_attributes.state)
    - name: targetBranch
      value: $(body.object_attributes.target_branch)
    - name: commitID
      value: $(body.object_attributes.merge_commit_sha)
           

定義EventListener

apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
  name: eventlistener
  namespace: test-tekton
spec:
  serviceAccountName: build-bot
  triggers:
    - bindings:
        - ref: triggerbinding
      template:
        ref: triggertemplate
           

gitlab設定

在Settings–>Webhooks下添加一個webhook,其中URL為建立Eventlistener時自動為你建立的svc,此svc預設是clusterIP,可自行建立一個NodePort類型svc。

Tekton入門Tekton入門

測試

在gitlab上提一個pr到dev分支,并合并就會觸發流水線,檢視生成的流水線記錄。

$ kubectl -n test-tekton get pipelineruns.tekton.dev 
NAME                SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
pipelinerun-mxlbw   True        Completed   8d          8d
pipelinerun-ngj6h   True        Succeeded   8d          7d23h

$ kubectl -n test-tekton get pod
NAME                                           READY   STATUS      RESTARTS   AGE
el-eventlistener-67464796fd-5k62t              1/1     Running     0          8d
pipelinerun-ngj6h-build-push-qjbcz-pod-vltrq   0/5     Completed   0          7d23h
pipelinerun-ngj6h-deploy-rxmd9-pod-hnzps       0/1     Completed   0          7d23h
           

繼續閱讀