理解Tekton的核心概念對於有效利用這個雲原生CI/CD平台至關重要。讓我們探討Tekton的工作原理和它與傳統CI/CD系統的不同之處。

宣告式設定與Kubernetes原生設計

Tekton的一個關鍵特點是它的宣告式設定方法。不像傳統CI/CD系統,Tekton使用Kubernetes自定義資源來定義整個管道過程。這意味著你可以像管理其他Kubernetes資源一樣管理你的CI/CD管道—透過YAML檔案、版本控制,甚至使用GitOps方法。

在實務中,這種設計帶來了幾個顯著優勢:

  1. 一致性 - 使用相同的工具和模式管理應用和CI/CD管道
  2. 可移植性 - 管道定義可以在任何Kubernetes叢集上執行
  3. 可擴充套件性 - 利用Kubernetes的彈性資源管理能力
  4. 版本控制 - 管道定義可以像程式碼一樣被版本控制和審查

關於任務與步驟的設計理念

Tekton的Task由一系列Steps組成,每個Step都在自己的容器中執行。這種設計帶來了極大的靈活性,因為每個Step可以使用不同的基礎映像和工具,同時仍然能夠分享工作區和結果。

在設計Task時,我發現遵循單一職責原則特別重要—每個Task應專注於一個明確的功能,比如編譯程式碼、執行測試或構建容器映像。這種方法使Tasks更容易重用和維護。

資源分享與工作區

Tekton中的資源分享是透過工作區(Workspaces)實作的。工作區可以看作是Tasks之間的分享儲存,可以用於傳遞構件、設定檔或其他資料。工作區可以對映到多種儲存類別,包括:

  • PersistentVolumeClaims (PVCs)
  • ConfigMaps
  • Secrets
  • emptyDir

這種靈活的資源分享機制使Tekton能夠處理各種複雜的工作流程,同時保持每個Task的獨立性和可重用性。

觸發器與事件驅動架構

Tekton的Triggers元件實作了事件驅動的工作流程,允許你根據外部事件(如Git push、Pull Request或其他系統的webhook)自動啟動管道。這使得Tekton成為實作GitOps工作流程的理想選

Tekton補充元件:擴充套件CI/CD能力

在現代DevOps環境中,僅有基本的管道功能往往不足以應對複雜的自動化需求。Tekton生態系統提供了多種補充元件,能夠顯著增強其功能。在上一篇文章中,我們已經介紹了Tekton Pipelines的基本安裝和使用。現在,讓我們繼續探討Tekton Triggers和Dashboard等擴充套件功能,這些元件能讓你的CI/CD系統更加強大和易於管理。

安裝Tekton Triggers:實作事件驅動自動化

Tekton Triggers是Tekton生態系統中的關鍵元件,它允許你根據外部事件(如Git提交、Webhook或其他系統事件)自動觸發管道執行。這實作了真正的事件驅動自動化,是GitOps工作流程的重要組成部分。

執行以下命令安裝Tekton Triggers(此處使用v0.20.1版本):

kubectl apply \
-f https://storage.googleapis.com/tekton-releases/triggers/previous/v0.20.1/release.yaml

這個指令會從Google Cloud Storage下載並應用Tekton Triggers的Kubernetes資源定義檔案。安裝過程中,系統會建立多個Kubernetes資源,包括:

  • 各種RBAC角色和角色繫結,用於許可權控制
  • 自定義資源定義(CRD),如EventListeners、TriggerBindings和TriggerTemplates
  • 控制器和Webhook佈署,用於管理Triggers功能
  • 攔截器(Interceptors),用於處理來自不同來源的事件(如GitHub、GitLab等)

安裝完成後,你可以透過以下命令監控並驗證安裝狀態:

kubectl get pods -w -n tekton-pipelines

成功安裝後,你應該會看到三個新的Pod執行起來:

  • tekton-triggers-controller:管理Triggers資源的控制器
  • tekton-triggers-core-interceptors:處理各種來源事件的核心攔截器
  • tekton-triggers-webhook:處理API驗證和轉換的Webhook服務

安裝Tekton Dashboard:視覺化你的CI/CD流程

雖然命令列工具強大而靈活,但圖形化介面能夠提供更直觀的操作體驗,特別是在監控和排錯管道時。Tekton Dashboard提供了一個簡潔的Web介面,讓你可以視覺化管理Tasks、Pipelines及檢視執行日誌。

執行以下命令安裝Tekton Dashboard(此處使用v0.28.0版本):

kubectl apply \
-f https://storage.googleapis.com/tekton-releases/dashboard/previous/v0.28.0/tekton-dashboard-release.yaml

這個指令會從Google Cloud Storage下載並應用Tekton Dashboard的Kubernetes資源定義。安裝過程中會建立:

  • Dashboard服務帳號和相關的RBAC許可權
  • Dashboard的Deployment和Service
  • 設定訊息和擴充套件點

安裝完成後,同樣可以透過以下命令監控安裝狀態:

kubectl get pods -w -n tekton-pipelines

這時你應該能看到一個新的Pod:tekton-dashboard已經執行起來。

存取Tekton Dashboard

預設情況下,Dashboard服務只在Kubernetes叢集內部可存取。要從本地存取它,你可以使用port-forward功能:

kubectl port-forward svc/tekton-dashboard 9097:9097 -n tekton-pipelines

這個命令將Kubernetes叢集中的tekton-dashboard服務的9097連線埠轉發到本地機器的9097連線埠,讓你能夠透過瀏覽器存取Dashboard。這是開發和測試環境中常用的方法,但在生產環境中,你可能會想使用Ingress或LoadBalancer等方式來暴露服務。

現在,你可以透過瀏覽器存取http://localhost:9097來開啟Dashboard。

安裝Tekton CLI工具

除了Web介面外,Tekton CLI工具(tkn)提供了更靈活的命令列體驗。建議安裝它來輔助日常操作。安裝完成後,可以透過以下命令驗證安裝和設定:

tkn version

如果一切正常,你應該能看到類別似以下的輸出:

Client version: 0.25.0
Pipeline version: v0.37.0
Triggers version: v0.20.1
Dashboard version: v0.28.0

建立第一個Tekton任務:Hello World

理解了Tekton的基礎架構後,現在讓我們建立一個簡單的Hello World任務,來熟悉Tekton的基本工作原理。

什麼是Tekton任務?

在Tekton中,Task是最基本的執行單元,它定義了一系列按順序執行的步驟(Steps)。每個Task在Kubernetes叢集中執行為一個Pod,而Task中的每個步驟則在Pod中的不同容器中執行。雖然Task內部的步驟是按順序執行的,但多個Task可以在Pipeline中平行執行,這使得Tekton能夠高效地處理複雜的工作流程。

建立Hello World任務

讓我們建立一個簡單的Hello World任務。首先,建立一個名為helloworld-task.yaml的檔案,內容如下:

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: hello
spec:
  steps:
    - name: say-hello
      image: registry.access.redhat.com/ubi8/ubi
      command:
        - /bin/bash
      args: ['-c', 'echo Hello GitOps Cookbook reader!']

這個YAML檔案定義了一個簡單的Tekton Task:

  • apiVersionkind:宣告這是一個Tekton Task資源
  • metadata.name:定義Task的名稱為"hello"
  • spec.steps:包含Task要執行的步驟列表
  • 在這個例子中,我們只有一個步驟say-hello,它使用Red Hat Universal Base Image (UBI)作為容器映像
  • commandargs:定義要執行的命令,這裡是一個簡單的echo命令

佈署和執行任務

現在,讓我們將這個Task佈署到Kubernetes叢集中:

kubectl create -f helloworld-task.yaml

你應該會看到確認訊息:task.tekton.dev/hello created

你可以驗證Task是否已經成功建立:

kubectl get tasks

最後,使用Tekton CLI來執行這個Task:

tkn task start --showlog hello

--showlog引數讓tkn直接顯示任務執行的日誌輸出,這對於簡單任務來說非常方便。執行後,你應該能看到Task執行的結果,包括"Hello GitOps Cookbook reader!“的輸出。

Tekton架構深入理解

透過上述步驟,我們已經完成了Tekton核心元件的安裝和一個簡單Task的建立與執行。這些基礎工作為我們後續探索更複雜的CI/CD流程奠定了基礎。讓我們來深入理解一下Tekton的架構特點:

宣告式設計

Tekton採用宣告式API設計,這與Kubernetes的設計理念一致。你只需描述"想要什麼”,而不是"怎麼做"。控制器會負責確保系統狀態與你的宣告相符。

模組化元件

Tekton的核心優勢在於其模組化設計:

  • Tasks:最小的執行單元,定義一系列步驟
  • Pipelines:組合多個Tasks形成工作流程
  • Triggers:根據事件觸發Pipelines
  • Resources:定義Pipeline輸入輸出(在新版本中逐漸被Parameters和Workspaces取代)

Kubernetes原生

作為Kubernetes原生的CI/CD解決方案,Tekton充分利用了Kubernetes的特性:

  • 容器化執行環境
  • 宣告式API和控制器模式
  • 可擴充套件性和可移植性
  • 強大的排程和資源管理能力

事件驅動自動化

透過Triggers元件,Tekton能夠實作真正的事件驅動自動化,這是實作GitOps工作流程的關鍵。例如,當開發者推播程式碼到Git儲存函式庫可以自動觸發相應的CI/CD管道。

實務應用考量

在實際應用Tekton構建CI/CD系統時,有些關鍵點值得注意:

  1. 資源隔離:考慮使用Kubernetes名稱空間來隔離不同團隊或專案的Tekton資源

  2. 安全性:Tekton執行在Kubernetes叢集中,需要考慮容器安全、RBAC許可權控制等問題

  3. 持久化:使用Workspaces管理持久化需求,確保任務間能夠分享資料

  4. 擴充套件性:對於複雜場景,考慮使用自定義任務(Custom Tasks)和攔截器(Interceptors)

  5. 監控與日誌:建立完善的監控和日誌系統,以便於問題排查

從我在多個專案中的實踐經驗來看,Tekton的確提供了極大的靈活性,但這也意味著你需要做更多的架構設計工作。相比一些開箱即用的CI/CD工具,Tekton更像是一套強大的構建模組,你可以用它來開發完全符合你需求的自動化系統。

Tekton的學習曲線可能比傳統CI/CD工具稍陡,但一旦掌握了它的核心概念,你就能夠構建出更加靈活、可擴充套件與強大的自動化管道。隨著越來越多的組織採用Kubernetes作為其基礎設施,Tekton這類別Kubernetes原生的CI/CD解決方案將會變得越來越重要。

在接下來的文章中,我們將進一步探討如何建立複雜的Pipeline、如何使用Triggers實作自動化觸發,以及如何將Tekton整合到你的GitOps工作流程中。這些進階主題將幫助你充分發揮Tekton的潛力,構建真正現代化的CI/CD系統。

Tekton生態系統正在快速發展,建議定期關注官方檔案和社群動態,以瞭解最新的功能和最佳實踐。透過不斷學習和實踐,你將能夠掌握這個強大工具,為你的組織帶來更高效的軟體交付流程。

Tekton:現代化的Kubernetes原生CI/CD工具

在當今雲原生時代,持續整合與持續交付(CI/CD)已成為開發團隊的標準實踐。而在Kubernetes環境中,Tekton作為一款原生CI/CD解決方案,提供了強大與靈活的自動化流程能力。在我多年的雲原生技術實踐中,發現Tekton不僅能夠無縫整合到Kubernetes生態系統,更能夠大幅簡化複雜工作流程的協調難度。

Tekton核心概念:TaskRun

在探討Tekton的實際應用前,我們需要先了解TaskRun這個關鍵概念。TaskRun是Task執行時的API表示,它記錄了Task執行的所有細節,包括狀態、日誌和結果。

當我們建立Task後,可以透過直接建立TaskRun或使用Tekton CLI來執行它。TaskRun負責追蹤Task的執行狀態,並在完成時提供詳細的執行結果和日誌。

從Git自動化編譯與封裝應用程式

設計靈活的Tekton Task

Tekton的Task設計理念是將自動化流程拆分為可重用的獨立單元,這些單元可以組合成更複雜的Pipeline。每個Task可以包含一系列步驟(steps),執行特定的操作。

在實際開發中,我發現Task的核心價值在於它的組合性和重用性。一個設計良好的Task應該聚焦於單一職責,並能夠與其他Task輕鬆整合。

Task可以包含以下關鍵元素:

  • inputs:Task輸入的資源
  • outputs:Task產生的資源
  • params:Task步驟中使用的引數
  • results:Task執行結果的輸出
  • workspaces:Task需要的卷路徑
  • volumes:Task可以掛載的外部卷

構建應用程式的Task例項

以下是一個名為build-app的Task範例,它從Git儲存函式庫原始碼並編譯封裝應用:

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: build-app
spec:
  workspaces:
  - name: source
    description: The git repo will be cloned onto the volume backing this workspace
  params:
  - name: contextDir
    description: the context dir within source
    default: quarkus
  - name: tlsVerify
    description: tls verify
    type: string
    default: "false"
  - name: url
    default: https://github.com/gitops-cookbook/tekton-tutorial-greeter.git
  - name: revision
    default: master
  - name: subdirectory
    default: ""
  - name: sslVerify
    description: defines if http.sslVerify should be set to true or false in the global git config
    type: string
    default: "false"
  steps:
  - image: 'gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.21.0'
    name: clone
    resources: {}
    script: |
      CHECKOUT_DIR="$(workspaces.source.path)/$(params.subdirectory)"
      cleandir() {
        # Delete any existing contents of the repo directory if it exists.
        # We don't just "rm -rf $CHECKOUT_DIR" because $CHECKOUT_DIR might be "/"
        # or the root of a mounted volume.
        if [[ -d "$CHECKOUT_DIR" ]] ; then
          # Delete non-hidden files and directories
          rm -rf "$CHECKOUT_DIR"/*
          # Delete files and directories starting with . but excluding ..
          rm -rf "$CHECKOUT_DIR"/.[!.]*
          # Delete files and directories starting with .. plus any other character
          rm -rf "$CHECKOUT_DIR"/..?*
        fi
      }
      /ko-app/git-init \
        -url "$(params.url)" \
        -revision "$(params.revision)" \
        -path "$CHECKOUT_DIR" \
        -sslVerify="$(params.sslVerify)"
      cd "$CHECKOUT_DIR"
      RESULT_SHA="$(git rev-parse HEAD)"
  - name: build-sources
    image: gcr.io/cloud-builders/mvn
    command:
    - mvn
    args:
    - -DskipTests
    - clean
    - install
    env:
    - name: user.home
      value: /home/tekton
    workingDir: "/workspace/source/$(params.contextDir)"

這個Task檔案定義了兩個主要步驟:

  1. 克隆步驟:使用git-init容器從指定的Git儲存函式庫原始碼。這裡有幾個關鍵點:

    • 使用workspaces來掛載儲存卷,這樣不同步驟可以分享檔案系統
    • cleandir()函式確保目標目錄乾淨,避免之前執行留下的殘餘檔案
    • 透過引數化的方式指定Git儲存函式庫L和分支,增加了靈活性
  2. 構建步驟:使用Maven容器編譯並封裝應用。這個步驟:

    • 設定了必要的環境變數
    • 指定工作目錄為克隆步驟輸出的原始碼位置
    • 執行Maven命令進行構建,並跳過測試以加速構建過程

在實際使用中,我發現透過引數化的方式定義Task可以大增加其靈活性和可重用性。例如,這個Task可以透過修改引數來構建不同的專案或不同的分支。

理解Workspace的作用

在Tekton中,Workspace是Task和Pipeline分享檔案系統的機制。它可以由以下幾種後端支援:

  • PersistentVolumeClaim (PVC):提供持久化儲存
  • ConfigMap:適用於小型設定檔
  • emptyDir:臨時儲存,Task完成後會被刪除

在我的實踐中,針對不同場景選擇合適的Workspace類別非常重要:

  • 對於需要在多個Task間分享大量資料的場景,PVC是最佳選擇
  • 對於只在單個Task執行期間需要臨時儲存的場景,emptyDir足夠了
  • 對於需要分享設定訊息的場景,ConfigMap更為適合

執行Task並檢視結果

建立Task定義後,我們可以透過多種方式執行它。

使用Tekton CLI啟動Task

最直接的方式是使用tkn命令列工具:

tkn task start build-app \
  --param contextDir='quarkus' \
  --workspace name=source,emptyDir="" \
  --showlog

執行此命令後,Tekton會提示我們確認或修改引數值,然後建立一個TaskRun物件並執行它。這種互動式的方式在開發和測試階段特別有用。

如果希望直接使用Task定義中的預設引數值而不進行提示,可以增加--use-param-defaults選項。

手動建立TaskRun物件

另一種方式是直接建立TaskRun YAML檔案:

apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  generateName: build-app-run-
  labels:
    app.kubernetes.io/managed-by: tekton-pipelines
    tekton.dev/task: build-app
spec:
  params:
  - name: contextDir
    value: quarkus
  - name: revision
    value: master
  - name: sslVerify
    value: "false"
  - name: subdirectory
    value: ""
  - name: tlsVerify
    value: "false"
  - name: url
    value: https://github.com/gitops-cookbook/tekton-tutorial-greeter.git
  taskRef:
    kind: Task
    name: build-app
  workspaces:
  - emptyDir: {}
    name: source

這個TaskRun定義有幾個值得注意的點:

  1. generateName:使用generateName而不是name,這樣Kubernetes會自動為每次執行生成唯一的名稱字尾,避免命名衝突。

  2. params:明確指定了所有引數值,這些值會覆寫Task定義中的預設值。

  3. taskRef:參照了我們之前建立的build-app Task。

  4. workspaces:為Task提供了一個臨時的emptyDir儲存空間。

我在實踐中發現,直接建立TaskRun檔案的方式在自動化流程中更為常用,而使用CLI的互動式方式則在開發和除錯階段更為方便。

檢視執行狀態和日誌

無論使用哪種方式建立TaskRun,都可以透過以下命令檢視執行狀態:

tkn taskrun ls

這會列出所有的TaskRun及其狀態、開始時間和持續時間等訊息。

要檢視特定TaskRun的日誌,可以使用:

tkn taskrun logs build-app-run-65vmh -f

其中-f引數可以持續跟蹤日誌輸出,類別似於tail -f命令。

處理私有Git儲存函式庫戰

在實際企業環境中,大多數程式碼都儲存在私有Git儲存函式庫這就引入了一個新的挑戰:如何在Tekton Task中安全地存取這些私有倉函式庫 處理私有Git儲存函式庫需要以下步驟:

  1. 建立包含Git憑證的Secret

    • 對於根據使用者名/密碼的認證,建立basic-auth類別的Secret
    • 對於SSH金鑰認證,建立ssh-auth類別的Secret
  2. 在Task中使用該Secret

    • 透過ServiceAccount將Secret掛載到Task中
    • 在Git克隆步驟中使用這些憑證

在下一篇文章中,我將詳細介紹如何在Tekton中安全地處理私有Git儲存函式庫問,包括不同類別的認證方式和最佳實踐。

Tekton管道的擴充套件性

從單個Task到完整的Pipeline,Tekton提供了強大的擴充套件性。透過組合多個Task,我們可以構建出符合團隊需求的複雜CI/CD管道。

例如,一個完整的應用發布管道可能包括:

  • 從Git克隆原始碼
  • 編譯和封裝應用
  • 執行單元測試和整合測試
  • 構建容器映像
  • 推播映像到容器倉函式庫 更新Kubernetes佈署

Tekton的設計理念使得這些步驟可以被模組化地定義和重用,從而提高團隊的效率和一致性。

實踐心得

在實際使用Tekton構建CI/CD管道的過程中,我總結了幾點心得:

  1. 保持Task的單一職責:每個Task應該聚焦於一個明確的任務,這樣可以提高重用性。

  2. 合理使用引數和預設值:透過引數化,可以使Task更加通用和靈活。

  3. 選擇合適的Workspace類別:根據資料持久化需求和效能考慮,選擇合適的Workspace後端。

  4. 使用Results進行Task間通訊:Task可以透過Results輸出訊息,供後續Task使用。

  5. 建立規範的命名和標記策略:隨著Task和Pipeline數量的增長,良好的命名和標記策略變得尤為重要。

Tekton作為Kubernetes原生的CI/CD解決方案,不僅提供了強大的功能,還與Kubernetes生態系統緊密整合。透過本文介紹的方法,你可以開始在Kubernetes環境中構建自動化的應用編譯和封裝流程,為持續交付奠定基礎。

在雲原生時代,自動化是提升團隊效率和產品品質的關鍵。Tekton透過提供靈活、可組合的構建模組,使得建立符合團隊需求的自動化管道變得更加簡單和高效。隨著技術的不斷發展,持續最佳化和改進CI/CD流程將成為技術團隊的常態工作。

Kubernetes中的Tekton私有倉函式庫機制

在雲端原生的開發環境中,持續整合與持續佈署(CI/CD)已成為標準實踐。在前面的文章中,我們探討過如何使用公開的Git儲存函式庫應用程式的編譯和封裝。然而,在企業環境中,私有倉函式庫日常工作的主角。今天,我將探討如何在Tekton中整合私有Git儲存函式庫實作應用程式的容器化流程。

私有Git儲存函式庫證方式選擇

Tekton支援兩種主要的Git認證機制:

  1. 基本認證(Basic-auth):使用者名和密碼
  2. SSH認證:使用SSH金鑰對

這兩種方式都需要透過Kubernetes Secret來儲存認證資訊,並將其附加到執行Tekton Tasks或Pipelines的ServiceAccount上。

在實務中,我發現基本認證因其設定簡單而被廣泛採用,尤其是與GitHub等服務整合時。不過,從安全形度考量,SSH認證通常是更好的選擇,特別是在生產環境中。

設定GitHub的基本認證

GitHub現在推薦使用個人存取令牌(Personal Access Tokens, PATs)代替明文密碼進行認證。這是一種更安全的方式,我也強烈建議採用。

首先,我們需要建立一個包含認證資訊的Secret:

apiVersion: v1
kind: Secret
metadata:
  name: github-secret
  annotations:
    tekton.dev/git-0: https://github.com
type: kubernetes.io/basic-auth
stringData:
  username: YOUR_USERNAME
  password: YOUR_PASSWORD
  • annotations中的tekton.dev/git-0指定了這個Secret將用於哪個URL,這裡是GitHub
  • type: kubernetes.io/basic-auth表明這是一個基本認證類別的Secret
  • username是你的GitHub使用者名稱
  • password則是你的GitHub個人存取令牌(PAT)

我們也可以使用kubectl命令直接建立Secret,避免編寫YAML:

kubectl create secret generic github-secret \
  --type=kubernetes.io/basic-auth \
  --from-literal=username=YOUR_USERNAME \
  --from-literal=password=YOUR_PASSWORD

然後為這個Secret增加註解:

kubectl annotate secret github-secret "tekton.dev/git-0=https://github.com"

設定服務帳號(ServiceAccount)

建立並註解Secret後,我們需要將其附加到執行Tekton Tasks或Pipelines的ServiceAccount上。讓我們建立一個專用的ServiceAccount:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: tekton-bot-sa
secrets:
  - name: github-secret

使用kubectl建立這個ServiceAccount:

kubectl create -f tekton-bot-sa.yaml

或者直接使用kubectl命令:

kubectl create serviceaccount tekton-bot-sa
kubectl patch serviceaccount tekton-bot-sa -p '{"secrets": [{"name": "github-secret"}]}'

使用設定的服務帳號執行Tekton Task

現在我們已經設定好了認證機制,可以使用這個ServiceAccount來執行Tekton任務。以之前的例子為基礎,我們只需增加--serviceaccount引數:

tkn task start build-app \
  --serviceaccount='tekton-bot-sa' \
  --param url='https://github.com/gitops-cookbook/tekton-greeter-private.git' \
  --param contextDir='quarkus' \
  --workspace name=source,emptyDir="" \
  --showlog

當執行成功時,你會看到類別似以下的輸出,表示已成功克隆私有倉函式庫

[clone] {"level":"info","ts":1659354692.1365478,"caller":"git/git.go:169","msg":"Successfully cloned https://github.com/gitops-cookbook/tekton-greeter-private.git @ 5250e1fa185805373e620d1c04a0c48129efd2ee (grafted, HEAD, origin/master) in path /workspace/source/"}