當我們建立雲原生應用時,自動化是提升開發效率的關鍵。在現代DevOps實踐中,能夠自動回應程式碼變更的CI/CD流程已成為標準。Tekton作為Kubernetes原生的CI/CD框架,透過其Triggers元件提供了強大的自動化能力。

事件驅動的工作流程自動化

在雲原生環境中實作自動化CI/CD流程時,我常發現許多團隊仍在使用手動觸發或定時執行的策略。這些方法不僅缺乏即時性,還會導致資源浪費。Tekton Triggers正是為解決這一問題而設計,它能夠回應外部事件,特別是來自Git儲存函式庫更事件。

當開發者推播程式碼或建立提取請求時,Git伺服器可以透過webhook呼叫Tekton提供的API端點,從而自動觸發構建管道。這種事件驅動的方式實作了真正的自動化CI/CD流程,使開發團隊能夠專注於程式碼開發,而不必擔心佈署流程。

Tekton Triggers核心元件解析

Tekton Triggers由三個主要元件組成,這些元件協同工作,實作從接收事件到觸發流程的完整鏈路:

  1. TriggerTemplate - 定義當事件發生時要建立的資源範本,支援引數化以生成特定的PipelineRun。

  2. TriggerBinding - 負責驗證事件並從事件負載中提取關鍵欄位,這些欄位將作為引數傳遞給TriggerTemplate。

  3. EventListener - 作為可定址的端點(事件接收器),將TriggerBinding和TriggerTemplate連線起來。它使用從每個TriggerBinding提取的事件引數來建立TriggerTemplate中指定的資源。

這三個元件之間的關係可以理解為:EventListener接收事件,TriggerBinding從事件中提取資料,TriggerTemplate使用這些資料建立新的Pipeline執行例項。

建立Git變更自動編譯封裝流程

要實作自動化CI/CD流程,首先需要為Tekton Triggers設定適當的許可權。Tekton Triggers需要能夠建立和管理Pipeline和Task資源。

定義TriggerTemplate

TriggerTemplate定義了當事件觸發時要建立的資源範本:

apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerTemplate
metadata:
  name: tekton-greeter-triggertemplate
spec:
  params:
  - name: git-revision
  - name: git-commit-message
  - name: git-repo-url
  - name: git-repo-name
  - name: content-type
  - name: pusher-name
  resourcetemplates:
  - apiVersion: tekton.dev/v1beta1
    kind: PipelineRun
    metadata:
      labels:
        tekton.dev/pipeline: tekton-greeter-pipeline-hub
      name: tekton-greeter-pipeline-webhook-$(uid)
    spec:
      params:
      - name: GIT_REPO
        value: $(tt.params.git-repo-url)
      - name: GIT_REF
        value: $(tt.params.git-revision)
      serviceAccountName: tekton-triggers-example-sa
      pipelineRef:
        name: tekton-greeter-pipeline-hub
      workspaces:
      - name: app-source
        persistentVolumeClaim:
          claimName: app-source-pvc
      - name: maven-settings
        emptyDir: {}

這個TriggerTemplate定義了事件觸發時要建立的PipelineRun資源。它接受多個引數,其中最關鍵的是git-repo-urlgit-revision,分別用於指定程式碼倉函式庫L和要簽出的Git修訂版本。當事件觸發時,這些引數會從事件負載中提取並傳遞給PipelineRun。

PipelineRun會使用名為tekton-greeter-pipeline-hub的Pipeline,並將工作空間掛載到永續性儲存區和臨時目錄中。每次觸發都會生成一個帶有唯一ID的新PipelineRun例項(使用$(uid)動態生成)。

定義TriggerBinding

TriggerBinding負責從事件負載中提取關鍵欄位:

apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerBinding
metadata:
  name: tekton-greeter-triggerbinding
spec:
  params:
  - name: git-repo-url
    value: $(body.repository.clone_url)
  - name: git-revision
    value: $(body.after)

這個TriggerBinding從webhook的JSON負載中提取兩個關鍵欄位:程式碼倉函式庫隆URL(body.repository.clone_url)和提交的修訂版本hash(body.after)。這裡使用的欄位名稱是根據GitHub的webhook格式,若使用其他Git服務如GitLab,可能需要調整欄位路徑。

TriggerBinding的主要任務是將事件資料對映到TriggerTemplate中定義的引數,從而實作事件與Pipeline執行之間的資料傳遞。

定義EventListener

EventListener作為webhook的接收端點:

apiVersion: triggers.tekton.dev/v1alpha1
kind: EventListener
metadata:
  name: tekton-greeter-eventlistener
spec:
  serviceAccountName: tekton-triggers-example-sa
  triggers:
  - bindings:
    - ref: tekton-greeter-triggerbinding
    template:
      ref: tekton-greeter-triggertemplate

EventListener定義了一個伺服器端點,用於接收webhook請求。它使用tekton-triggers-example-sa服務帳號來建立和管理資源,並將tekton-greeter-triggerbindingtekton-greeter-triggertemplate關聯起來。

當webhook請求到達時,EventListener會使用TriggerBinding從請求中提取資料,然後用這些資料填充TriggerTemplate以建立新的PipelineRun。

佈署與測試Triggers

建立這些資源後,Kubernetes會自動佈署一個EventListener Pod和相應的Service:

kubectl create -f tekton-greeter-triggertemplate.yaml
kubectl create -f tekton-greeter-triggerbinding.yaml
kubectl create -f tekton-greeter-eventlistener.yaml

可以透過以下命令檢視建立的Pod:

kubectl get pods

輸出應該顯示一個執行中的EventListener Pod:

NAME                                                READY   STATUS    RESTARTS   AGE
el-tekton-greeter-eventlistener-5db7b9fcf9-6nrgx   1/1     Running   0          10s

EventListener會建立一個Kubernetes Service,用於接收webhook請求:

kubectl get svc

輸出類別似於:

NAME                             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
el-tekton-greeter-eventlistener  ClusterIP   10.100.36.199   <none>        8080/TCP,9000/TCP   10s

模擬Git Webhook觸發Pipeline

如果Git伺服器在叢集外部(如GitHub或GitLab),需要透過Ingress暴露EventListener Service。在開發環境中,可以使用port-forward直接測試:

kubectl port-forward svc/el-tekton-greeter-eventlistener 8080

然後使用curl模擬webhook請求:

curl -X POST \
  http://localhost:8080 \
  -H 'Content-Type: application/json' \
  -d '{ "after": "d9291c456db1ce29177b77ffeaa9b71ad80a50e6", "repository": { "clone_url" : "https://github.com/gitops-cookbook/tekton-tutorial-greeter.git" } }'

成功觸發後,會看到類別似如下的輸出:

{
  "eventListener": "tekton-greeter-eventlistener",
  "namespace": "default",
  "eventListenerUID": "c00567eb-d798-4c4a-946d-f1732fdfc313",
  "eventID": "17dd25bb-a1fe-4f84-8422-c3abc5f10066"
}

此時,一個新的Pipeline已經被觸發,可以透過以下命令檢視:

tkn pipelinerun ls

輸出顯示正在執行的Pipeline:

NAME                                                           AGE              STATUS
tekton-greeter-pipeline-webhook-3244b67f-31d3-4597-af1c-3c1aa6693719   4 seconds ago   Running

使用Kustomize和Tekton更新Kubernetes資源

在GitOps實踐中,程式碼變更後自動更新Kubernetes資源是一個關鍵環節。Kustomize作為Kubernetes原生的組態管理工具,可以無需分叉原始YAML檔案就能修改設定。結合Tekton,我們可以實作程式碼變更後自動更新Kubernetes資源並將變更推播回Git儲存函式庫

GitOps中的設定自動化

在實施GitOps時,通常會有兩類別程式碼儲存函式庫用程式碼儲存函式庫ubernetes資源清單儲存函式庫應用程式碼變更並生成新的容器映像後,需要自動更新Kubernetes資源清單中的映像標籤或雜湊值。

Kustomize可以透過kustomize edit set image命令輕鬆實作這一目標。我們可以建立一個Tekton Task,接收Kubernetes資源清單儲存函式庫引數,並更新容器映像參照。

建立Git更新佈署的Task

以下是一個可以更新Kubernetes佈署映像的Tekton Task:

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  annotations:
    tekton.dev/pipelines.minVersion: 0.12.1
    tekton.dev/tags: git
  name: git-update-deployment
  labels:
    app.kubernetes.io/version: '0.2'
    operator.tekton.dev/provider-type: community
spec:
  description: >-
    此Task用於更新Kubernetes佈署中的容器映像並將變更推播回Git儲存函式庫``



這個Task的定義開始部分包含了中繼資料和標籤,指明它與Git操作相關,並且是由社群提供的。`description`欄位簡要說明瞭任務的用途:更新Kubernetes佈署中的容器映像並將變更推播回Git儲存函式庫
在GitOps流程中,這個Task扮演著關鍵角色:它將CI流程生成的新容器映像自動更新到設定儲存函式庫從而觸發CD流程進行實際佈署。

### 結合Triggers和Kustomize的自動化佈署流程

將Tekton Triggers與Kustomize結合使用,可以實作一個完整的GitOps自動化流程:

1. 開發者提交程式碼到應用程式儲存函式庫. Git webhook觸發Tekton Pipeline
3. Pipeline構建並推播新的容器映像
4. Pipeline使用Kustomize更新Kubernetes資源清單中的映像參照
5. 更新後的資源清單被推播回Git儲存函式庫. GitOps工具(如Argo CD)檢測到設定變更並同步到叢集

這種方法實作了從程式碼提交到應用佈署的完全自動化,同時保持了GitOps的核心原則:以Git為單一事實來源。

在實際專案中,我發現這種自動化流程可以顯著減少人為錯誤,並加快從開發到佈署的週期。特別是對於微服務架構,當需要管理數十甚至上百個服務時,自動化變得尤為重要。

## 實踐心得與最佳實踐

在實施Tekton Triggers和Kustomize的過程中,我積累了一些實用的經驗和最佳實踐:

### 安全考量

EventListener暴露了一個公共端點,因此需要考慮安全性。建議:

1. 使用HTTPS並設定TLS
2. 實施webhook金鑰驗證
3. 使用Tekton Triggers的Interceptor機制進行請求驗證和過濾
4. 限制EventListener服務帳號的許可權範圍

### 擴充套件性設計

對於大型專案,可能需要處理多種不同的事件和多個儲存函式庫了保持可維護性:

1. 為不同類別的應用或環境建立專用的TriggerTemplate
2. 使用標籤和註解保持資源的可發現性
3. 實施結構化的命名約定
4. 考慮使用Tekton的Condition資源進行條件執行

## Tekton 與 Kubernetes 的自動化設定更新

在現代的 DevOps 實踐中,自動化應用佈署和設定更新是提高效率的關鍵。透過 CI/CD 管道自動更新 Kubernetes 設定不僅可以減少手動錯誤,還能確保應用的快速佈署和一致性。在這篇文章中,我將分享如何使用 Tekton 任務來自動更新 Kubernetes 設定以及如何透過 Helm 自動佈署應用。

### 使用 Tekton 任務更新 Git 儲存函式庫設定

當談到 GitOps 工作流程時,我們通常會將應用程式碼和設定分開存放。應用程式碼產生容器映像,而設定則定義了這些映像在 Kubernetes 上的佈署方式。讓我們來看如何使用 Tekton 任務自動更新這些設定。

## Git 更新佈署任務解析

以下是一個用於更新 Git 儲存函式庫Kubernetes 設定的 Tekton 任務:

```yaml
params:
- name: GIT_REPOSITORY
  type: string
- name: GIT_REF
  type: string
- name: NEW_IMAGE
  type: string
- name: NEW_DIGEST
  type: string
- name: KUSTOMIZATION_PATH
  type: string
results:
- description: The commit SHA
  name: commit
steps:
- image: 'docker.io/alpine/git:v2.26.2'
  name: git-clone
  resources: {}
  script: >
    rm -rf git-update-digest-workdir
    git clone $(params.GIT_REPOSITORY) -b $(params.GIT_REF)
    git-update-digest-workdir
  workingDir: $(workspaces.workspace.path)
- image: 'quay.io/wpernath/kustomize-ubi:latest'
  name: update-digest
  resources: {}
  script: >
    cd git-update-digest-workdir/$(params.KUSTOMIZATION_PATH)
    kustomize edit set image $(params.NEW_IMAGE)@$(params.NEW_DIGEST)
    echo "##########################"
    echo "### kustomization.yaml ###"
    echo "##########################"
    cat kustomization.yaml
  workingDir: $(workspaces.workspace.path)
- image: 'docker.io/alpine/git:v2.26.2'
  name: git-commit
  resources: {}
  script: |
    cd git-update-digest-workdir
    git config user.email "tektonbot@redhat.com"
    git config user.name "My Tekton Bot"
    
    git status
    git add $(params.KUSTOMIZATION_PATH)/kustomization.yaml
    git commit -m "[ci] Image digest updated"
    git push
    RESULT_SHA="$(git rev-parse HEAD | tr -d '\n')"
    EXIT_CODE="$?"
    if [ "$EXIT_CODE" != 0 ]
    then
      exit $EXIT_CODE
    fi
    # Make sure we don't add a trailing newline to the result!
    echo -n "$RESULT_SHA" > $(results.commit.path)
  workingDir: $(workspaces.workspace.path)
workspaces:
- description: The workspace consisting of maven project.
  name: workspace

這個任務由三個主要步驟組成:

  1. git-clone - 克隆包含 Kubernetes 設定的 Git 儲存函式庫一步使用 alpine/git 映像,將目標儲存函式庫到工作區中。

  2. update-digest - 使用 Kustomize 更新佈署設定中的容器映像摘要。這一步會進入指定的 Kustomization 路徑,然後使用 kustomize edit set image 命令更新映像摘要,最後顯示更新後的 kustomization.yaml 檔案內容。

  3. git-commit - 將變更提交並推播回 Git 儲存函式庫一步設定 Git 使用者資訊,增加修改的檔案,提交變更並推播到遠端儲存函式庫後,它將提交的 SHA 儲存在結果路徑中,以便管道的其他任務可以使用。

要使用這個任務,可以使用以下命令建立:

kubectl create -f git-update-deployment-task.yaml

執行後應該會看到:

task.tekton.dev/git-update-deployment created

將任務整合到管道中

下面是一個完整的 Tekton 管道,它包含了從克隆程式碼函式庫構映像再到更新設定的整個流程:

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: pacman-pipeline
spec:
  params:
  - default: https://github.com/gitops-cookbook/pacman-kikd.git
    name: GIT_REPO
    type: string
  - default: master
    name: GIT_REVISION
    type: string
  - default: quay.io/gitops-cookbook/pacman-kikd
    name: DESTINATION_IMAGE
    type: string
  - default: .
    name: CONTEXT_DIR
    type: string
  - default: 'https://github.com/gitops-cookbook/pacman-kikd-manifests.git'
    name: CONFIG_GIT_REPO
    type: string
  - default: main
    name: CONFIG_GIT_REVISION
    type: string
  tasks:
  - name: fetch-repo
    params:
    - name: url
      value: $(params.GIT_REPO)
    - name: revision
      value: $(params.GIT_REVISION)
    - name: deleteExisting
      value: "true"
    taskRef:
      name: git-clone
    workspaces:
    - name: output
      workspace: app-source
  - name: build-app
    taskRef:
      name: maven
    params:
    - name: GOALS
      value:
      - -DskipTests
      - clean
      - package
    - name: CONTEXT_DIR
      value: "$(params.CONTEXT_DIR)"
    workspaces:
    - name: maven-settings
      workspace: maven-settings
    - name: source
      workspace: app-source
    runAfter:
    - fetch-repo
  - name: build-push-image
    taskRef:
      name: buildah
    params:
    - name: IMAGE
      value: "$(params.DESTINATION_IMAGE)"
    workspaces:
    - name: source
      workspace: app-source
    runAfter:
    - build-app
  - name: git-update-deployment
    params:
    - name: GIT_REPOSITORY
      value: $(params.CONFIG_GIT_REPO)
    - name: NEW_IMAGE
      value: $(params.DESTINATION_IMAGE)
    - name: NEW_DIGEST
      value: $(tasks.build-push-image.results.IMAGE_DIGEST)
    - name: KUSTOMIZATION_PATH
      value: env/dev
    - name: GIT_REF
      value: $(params.CONFIG_GIT_REVISION)
    runAfter:
    - build-push-image
    taskRef:
      kind: Task
      name: git-update-deployment
    workspaces:
    - name: workspace
      workspace: app-source
  workspaces:
  - name: app-source
  - name: maven-settings

這個管道包含四個任務:

  1. fetch-repo - 使用 git-clone 任務從指定的 Git 儲存函式庫應用程式碼。
  2. build-app - 使用 Maven 任務建構應用程式。
  3. build-push-image - 使用 buildah 任務建構並推播容器映像。
  4. git-update-deployment - 使用我們之前定義的任務更新 Kubernetes 設定。

特別值得注意的是,管道使用 $(tasks.build-push-image.results.IMAGE_DIGEST) 將之前任務的結果作為輸入傳遞給後續任務,這展示了 Tekton 任務之間資料傳遞的強大功能。

要建立這個管道,可以執行:

kubectl create -f pacman-pipeline.yaml

認證與許可權設定

由於 git-commit 步驟需要向 Git 伺服器進行身份驗證以推播更新,因此需要設定適當的許可權。對於 GitHub,可以使用個人存取令牌(Personal Access Token)並將其附加到 ServiceAccount:

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

確保已經按照需求建立了永續性儲存區宣告(PVC)。然後可以使用以下命令啟動管道:

tkn pipeline start pacman-pipeline \
  --serviceaccount='tekton-bot-sa' \
  --param GIT_REPO='https://github.com/gitops-cookbook/pacman-kikd.git' \
  --param GIT_REVISION='main' \
  --param DESTINATION_IMAGE='quay.io/gitops-cookbook/pacman-kikd:latest' \
  --param CONFIG_GIT_REPO='https://github.com/gitops-cookbook/pacman-kikd-manifests.git' \
  --param CONFIG_GIT_REVISION='main' \
  --workspace name=app-source,claimName=app-source-pvc \
  --workspace name=maven-settings,emptyDir="" \
  --use-param-defaults \
  --showlog

使用 Helm 和 Tekton 自動佈署應用

除了更新 Kubernetes 設定外,玄貓還經常使用 Helm 來管理應用佈署。Helm 作為 Kubernetes 的套件管理器,提供了強大的範本化和版本化功能。

問題與解決方案

在實際工作中,我常需要自動化 Helm 套件的佈署過程。透過 Tekton 管道,我們可以實作這一目標,使得應用的安裝或更新變得簡單與一致。

安裝 Helm 升級任務

首先,從 Tekton Hub 安裝 helm-upgrade-from-repo 任務:

tkn hub install task helm-upgrade-from-repo

這個任務可以從 Helm 儲存函式庫 Helm 圖表。在這個例子中,我們使用本章儲存函式庫供的 Helm 儲存函式庫

helm repo add gitops-cookbook https://gitops-cookbook.github.io/helm-charts/

執行後應該會看到:

"gitops-cookbook" has been added to your repositories

使用 Helm 佈署應用

現在可以使用以下命令安裝 Helm

helm install pacman gitops-cookbook/pacman

執行後應該會看到類別似以下的輸出:

NAME: pacman
LAST DEPLOYED: Mon Aug 15 17:02:21 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}

應用現在應該已佈署並在 Kubernetes 上執行:

kubectl get pods -l=app.kubernetes.io/name=pacman

輸出應該類別似於:

NAME                     READY   STATUS    RESTARTS   AGE
pacman-6798d65d84-9mt8p   1/1     Running   0          30s

使用 Tekton 任務更新 Helm 佈署

現在讓我們使用 Tekton 任務執行 helm upgrade 來更新佈署:

apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  generateName: helm-pacman-run-
spec:
  serviceAccountName: tekton-deployer-sa
  taskRef:
    name: helm-upgrade-from-repo
  params:
  - name: helm_repo
    value: https://gitops-cookbook.github.io/helm-charts/
  - name: chart_name
    value: gitops-cookbook/pacman
  - name: release_version
    value: 0.1.0
  - name: release_name
    value: pacman
  - name: overwrite_values
    value: replicaCount=2

這個 TaskRun 使用 helm-upgrade-from-repo 任務從指定的 Helm 儲存函式庫 Pacman 應用。它指定了 Helm 儲存函式庫RL、圖表 名稱、版本和釋出名稱。特別值得注意的是,它透過 overwrite_values 引數將副本數設定為 2,這會覆寫 圖表 的預設值。

需要注意的是,helm-upgrade-from-repo 任務需要在工作名稱空間中列出物件的許可權,因此需要使用具有特殊許可權的 ServiceAccount,如之前所述。

使用以下命令執行任務:

kubectl create -f helm-pacman-taskrun.yaml

執行後應該會看到類別似以下的輸出:

taskrun.tekton.dev/helm-pacman-run-qghx8 created

使用 tkn CLI 檢查日誌:

tkn taskrun logs -f

應該會看到類別似以下的輸出,表明 Helm 升級已成功執行:

[upgrade-from-repo] current installed helm releases
[upgrade-from-repo] NAME     NAMESPACE  REVISION  UPDATED                                 STATUS    CHART         APP VERSION
[upgrade-from-repo] pacman   default    1         2022-08-15 17:02:21.633934129 +0200 +0200 deployed  pacman-0.1.0  1.0.0

自動化 Helm 佈署的最

使用Helm和CI/CD工具管理Kubernetes應用程式

從Helm儲存函式庫應用程式

當我們使用GitOps進行Kubernetes應用程式管理時,從Helm儲存函式庫應用程式是一個常見需求。從前面的日誌中,我們可以看到一個成功的Helm升級過程:

[upgrade-from-repo] Release "pacman" has been upgraded. Happy Helming!
[upgrade-from-repo] NAME: pacman
[upgrade-from-repo] LAST DEPLOYED: Mon Aug 15 15:23:31 2022
[upgrade-from-repo] NAMESPACE: default
[upgrade-from-repo] STATUS: deployed
[upgrade-from-repo] REVISION: 2

這個升級過程首先增加了一個名為"gitops-cookbook"的Helm儲存函式庫後從該儲存函式庫了pacman應用程式。值得注意的是,這次升級將副本數量從原來的設定增加到了2個,這可以從replicaCount: 2的設定中看出。升級過程中,Helm顯示了詳細的佈署狀態,包括等待新的Pod就緒,以及最終的設定值和資源清單。

使用Drone建立Kubernetes的CI/CD管道

Drone是一個雲原生的持續整合(CI)開放原始碼專案,它使用YAML設定檔來定義和執行容器內的建置管道。

Drone的核心元件

  1. Server - 與GitHub、GitLab或Gitea等SCM工具整合
  2. Runner - 作為在特定平台上執行的代理

設定Drone CI/CD管道的步驟

  1. 安裝Drone CLI

    brew tap drone/drone && brew install drone
    
  2. 設定Drone認證

    export DRONE_TOKEN="<YOUR-TOKEN>"
    
  3. **啟用儲存函式庫:

    drone repo enable https://github.com/gitops-cookbook/pacman-kikd.git
    
  4. 增加容器登入檔認證

    drone secret add --name image_registry --data quay.io https://github.com/gitops-cookbook/pacman-kikd.git
    drone secret add --name image_registry_user --data YOUR_REGISTRY_USER https://github.com/gitops-cookbook/pacman-kikd.git
    drone secret add --name image_registry_password --data YOUR_REGISTRY_PASS https://github.com/gitops-cookbook/pacman-kikd.git
    drone secret add --name destination_image --data quay.io/YOUR_REGISTRY_USER>/pacman-kikd.git https://github.com/gitops-cookbook/pacman-kikd.git
    
  5. 建立管道設定檔 (.drone.yaml):

kind: pipeline
type: docker
name: java-pipeline
platform:
  os: linux
  arch: arm64
trigger:
  branch:
    - main
clone:
  disable: true
steps:
  - name: clone sources
    image: alpine/git
    pull: if-not-exists
    commands:
      - git clone https://github.com/gitops-cookbook/pacman-kikd.git .
      - git checkout $DRONE_COMMIT
  - name: maven-build
    image: maven:3-jdk-11
    commands:
      - mvn install -DskipTests=true -B
      - mvn test -B
  - name: publish
    image: plugins/docker:20.13
    pull: if-not-exists
    settings:
      tags: "latest"
      dockerfile: Dockerfile
      insecure: true
      mtu: 1400
      username:
        from_secret: image_registry_user
      password:
        from_secret: image_registry_password
      registry:
        from_secret: image_registry
      repo:
        from_secret: destination_image

這個Drone管道設定義了一個名為java-pipeline的Docker類別管道,針對Linux ARM64平台。當main分支有變更時觸發執行。管道停用了自動克隆功能,而是在第一個步驟中手動進行克隆。

管道包含三個主要步驟:

  1. 克隆原始碼 - 使用alpine/git映象克隆pacman-kikd儲存函式庫. Maven建置 - 使用maven:3-jdk-11映象進行Java應用程式的編譯和測試
  2. 釋出 - 使用plugins/docker映象建立並推播Docker容器到設定的容器登入檔

最後,可以透過以下命令手動執行管道:

drone exec --pipeline=java-pipeline

使用GitHub Actions進行CI

GitHub Actions是GitHub儲存函式庫用的事件驅動自動化任務。當特定事件發生時,會自動觸發工作流程,執行任務,如軟體建置、測試和佈署。

設定GitHub Actions工作流程

在儲存函式庫.github/workflows/pacman-ci-action.yml`路徑建立以下工作流程檔案:

name: pacman-ci-action
env:
  IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }}
  REGISTRY_USER: ${{ github.actor }}
  REGISTRY_PASSWORD: ${{ github.token }}
  APP_NAME: pacman
  IMAGE_TAGS: 1.0.0 ${{ github.sha }}

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]
  workflow_dispatch:

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up JDK 11
        uses: actions/setup-java@v3
        with:
          java-version: '11'
          distribution: 'adopt'
          cache: maven
      - name: Build with Maven
        run: mvn --batch-mode package
      - name: Buildah Action
        id: build-image
        uses: redhat-actions/buildah-build@v2
        with:
          image: ${{ env.IMAGE_REGISTRY }}/${{ env.APP_NAME }}
          tags: ${{ env.IMAGE_TAGS }}
          containerfiles: |
            ./Dockerfile
      - name: Push to Registry
        id: push-to-registry
        uses: redhat-actions/push-to-registry@v2
        with:
          image: ${{ steps.build-image.outputs.image }}
          tags: ${{ steps.build-image.outputs.tags }}
          registry: ${{ env.IMAGE_REGISTRY }}
          username: ${{ env.REGISTRY_USER }}
          password: ${{ env.REGISTRY_PASSWORD }}

這個GitHub Actions工作流程命名為pacman-ci-action,設定了幾個環境變數,包括容器映像登入檔、使用者認證和應用程式名稱。工作流程在main分支的推播或提取請求時觸發,也可以手動觸發。

工作流程包含一個名為build-and-push的作業,執行在ubuntu-latest環境中,包含以下步驟:

  1. 簽出程式碼 - 使用actions/checkout動作取得儲存函式庫碼
  2. 設定JDK - 使用actions/setup-java設定Java 11環境
  3. Maven建置 - 執行Maven包裝命令編譯應用程式
  4. 建立容器映像 - 使用redhat-actions/buildah-build建立容器映像
  5. 推播到登入檔 - 使用redhat-actions/push-to-registry將映像推播到GitHub容器登入檔

CI/CD工具選擇的考量因素

在選擇CI/CD工具時,我經常考慮以下幾點:

  1. 整合能力 - 工具需要與現有系統和工作流程無縫整合
  2. 易用性 - 設定和維護的複雜度
  3. 社群支援 - 活躍的社群和良好的檔案
  4. 擴充套件性 - 能否滿足未來的需求和規模
  5. 安全性 - 提供的安全功能和實踐

Drone適合較小的團隊和專案,具有簡單直觀的設定。而GitHub Actions則與GitHub儲存函式庫整合,對於已經使用GitHub的團隊來說是個不錯的選擇。

在實際應用中,我發現這些工具的選擇往往取決於團隊的具體需求和現有技術堆積積疊。無論選擇哪種工具,關鍵是建立一個可靠、可重複的自動化流程,確保應用程式能夠一致地佈署到Kubernetes環境中。

現代的CI/CD實踐已經成為DevOps文化的核心部分,它不僅提高了佈署效率,還透過自動化測試和驗證提升了應用程式的品質。透過將這些工具與Kubernetes和Helm結合使用,我們可以建立一個強大的GitOps工作流程,使應用程式的佈署和管理變得更加簡單和可靠。