返回文章列表

Tekton ArgoCD 自動化佈署 Kubernetes 應用

本文介紹如何利用 Tekton 建立 CI/CD 管道,並結合 ArgoCD 實作 GitOps 自動化佈署 Kubernetes 應用程式。文章涵蓋了 Tekton Pipeline 的基本架構、任務定義、使用 Kaniko 構建和推播映像檔、觸發 ArgoCD 佈署新映像檔,以及 Pipeline

CI/CD Kubernetes

本文說明如何使用 Tekton 建立 CI/CD 管道,搭配 ArgoCD 實作 GitOps 自動化佈署流程。首先,我們會定義數個 Tekton Task,包含產生映像檔標籤、使用 Kaniko 建置和推播映像檔,以及更新 Git 儲存函式庫中的佈署設定。接著,將這些 Task 組合成一個 Pipeline,並設定觸發器以便在程式碼提交時自動執行。最後,我們將使用 ArgoCD 監控 Git 儲存函式庫的變更,並自動佈署更新後的應用程式到 Kubernetes 叢集。這個流程確保了應用程式佈署的可靠性和一致性,同時簡化了操作流程,提升了開發效率。

佈署 Tekton 管道系統

Tekton 是我們平台使用的管道系統。它最初是 Knative 專案的一部分,用於在 Kubernetes 上構建函式即服務(FaaS),後來被分拆成獨立的專案。Tekton 與其他管道技術最大的不同之處在於它是原生於 Kubernetes 的。從其執行系統、定義到用於自動化的 Webhook,一切都可以在幾乎任何 Kubernetes 發行版上執行。例如,我們將在 KinD 中執行它,而紅帽(Red Hat)已經將 Tekton 作為 OpenShift 從 4.1 版本開始的主要管道技術。

佈署 Tekton 的過程非常簡單。Tekton 是一系列運算子,它們會尋找定義建置管道的自定義資源的建立。佈署本身只需要幾個 kubectl 命令:

$ kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
$ kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml

第一個命令佈署執行 Tekton 管道所需的基礎系統。第二個命令佈署構建 Webhook 所需的元件,以便在程式碼推播後立即啟動管道。一旦兩個命令都完成,並且 tekton-pipelines 名稱空間中的 Pod 正在執行,您就可以開始構建管道了。

建置 Hello World 應用程式

我們的 Hello World 應用程式非常簡單。它是一個簡單的服務,回顯必備的「hello」以及服務執行的主機名,讓我們感覺我們的服務正在做一些有趣的事情。由於該服務是用 Python 編寫的,我們不需要「建置」二進位制檔案,但我們確實想要建置一個容器。一旦容器建置完成,我們希望更新執行名稱空間的 Git 倉函式庫,並讓我們的 GitOps 系統協調變更以重新佈署我們的應用程式。我們的建置步驟如下:

  1. 簽出我們的最新程式碼。
  2. 根據時間戳記建立標籤。
  3. 建置我們的映像檔。
  4. 推播到我們的登入檔。
  5. operations 名稱空間中修補 Deployment YAML 檔案。

我們將一步一步地構建我們的管道。首先,我們需要建立一個 SSH 金鑰,Tekton 將使用它來提取我們的原始碼:

建立 SSH 金鑰對

  1. 為我們的管道建立一個 SSH 金鑰對,用於簽出我們的程式碼。在提示輸入密碼短語時,只需按 Enter 鍵跳過新增密碼短語:

    $ ssh-keygen -f ./gitlab-hello-python
    
  2. 登入到 GitLab,並導航到我們建立的 hello-python 專案。點選「Settings | Repository | Deploy Keys」,然後點選「Expand」。使用 tekton 作為標題,並將剛剛建立的 gitlab-hello-python.pub 檔案的內容貼上到「Key」部分。保持「Write access allowed」未選中,然後點選「Add Key」。

建立 Secret 物件

  1. 接下來,在 python-hello-build 名稱空間中建立以下 Secret 物件。將 ssh-privatekey 屬性替換為我們在步驟 1 中建立的 gitlab-hello-python 檔案的 Base64 編碼內容。註解告訴 Tekton 使用此金鑰的伺服器名稱:

apiVersion: v1 data: ssh-privatekey: … kind: Secret metadata: annotations: tekton.dev/git-0: gitlab-gitlab-shell.gitlab.svc.cluster.local name: git-pull namespace: python-hello-build type: kubernetes.io/ssh-auth


#### 繼續建立推播用的 SSH 金鑰對

4. 為我們的管道建立另一個 SSH 金鑰對,用於推播到 `operations` 倉函式庫。在提示輸入密碼短語時,只需按 Enter 鍵跳過新增密碼短語:
```bash
$ ssh-keygen -f ./gitlab-hello-python-operations
  1. 登入到 GitLab,並導航到我們建立的 hello-python-operations 專案。點選「Settings | Repository | Deploy Keys」,然後點選「Expand」。使用 tekton 作為標題,並將剛剛建立的 gitlab-hello-python-operations.pub 檔案的內容貼上到「Key」部分。確保選中「Write access allowed」,然後點選「Add Key」。

建立用於推播的 Secret 物件

  1. 接下來,建立以下 Secret 物件。將 ssh-privatekey 屬性替換為我們在步驟 4 中建立的 gitlab-hello-python-operations 檔案的 Base64 編碼內容。註解告訴 Tekton 使用此金鑰的伺服器名稱:

apiVersion: v1 data: ssh-privatekey: … kind: Secret metadata: name: git-write namespace: python-hello-build type: kubernetes.io/ssh-auth


#### 建立 ServiceAccount

7. 為任務執行建立一個 ServiceAccount,就像我們的 Secret 一樣:
```bash
$ kubectl create -f chapter14/tekton-serviceaccount.yaml

建置包含 git 和 kubectl 的容器

  1. 我們需要一個包含 gitkubectl 的容器。我們將建置 chapter14/docker/PatchRepoDockerfile,並將其推播到我們的內部登入檔。請務必將 192-168-2-114 替換為您的伺服器 IP 地址的主機名:
    $ docker build -f ./PatchRepoDockerfile -t docker.apps.192-168-2-114.nip.io/gitcommit/gitcommit .
    $ docker push docker.apps.192-168-2-114.nip.io/gitcommit/gitcommit
    

定義 Task 物件

每個 Task 物件都可以接受輸入並產生結果,這些結果可以與其他 Task 物件分享。Tekton 可以為執行(無論是 TaskRun 還是 PipelineRun)提供一個工作區,用於儲存和檢索狀態。透過寫入工作區,我們可以在 Task 物件之間分享資料。

在佈署我們的 Task 和 Pipeline 之前,讓我們逐步瞭解每個 Task 所做的工作。第一個 Task 生成映像標籤並取得最新提交的 SHA 雜湊值。完整的原始碼位於 chapter14/yaml/tekton-task1.yaml

- name: create-image-tag
  image: docker.apps.192-168-2-114.nip.io/gitcommit/gitcommit
  script: |-
    #!/usr/bin/env bash
    export IMAGE_TAG=$(date +"%m%d%Y%H%M%S")
    echo -n "$(resources.outputs.result-image.url):$IMAGE_TAG" > /tekton/results/image-url
    echo "'$(cat /tekton/results/image-url)'"
    cd $(resources.inputs.git-resource.path)
    RESULT_SHA="$(git rev-parse HEAD | tr -d '\n')"
    echo "Last commit : $RESULT_SHA"
    echo -n "$RESULT_SHA" > /tekton/results/commit-tag

#### 內容解密:

此 Task 名稱為 create-image-tag,它使用包含 gitkubectl 的自定義映像檔來執行指令碼。

  1. 生成映像標籤:使用 date 命令生成當前時間戳作為映像標籤,並將其寫入 /tekton/results/image-url 檔案中。
  2. 輸出映像 URL:列印預出生成的映像 URL。
  3. 取得最新提交的 SHA:進入 Git 資源目錄,使用 git rev-parse HEAD 取得最新提交的 SHA 值,並將其寫入 /tekton/results/commit-tag 檔案中。
  4. 輸出最新提交的 SHA:列印預出最新提交的 SHA 值。

此 Task 的主要目的是為映像生成唯一的標籤,並記錄最新的 Git 提交 SHA,以便後續任務使用這些資訊。

佈署 Tekton 的完整流程與實踐解析

在現代化的 DevOps 流程中,持續整合與持續佈署(CI/CD)是不可或缺的一環。Tekton 作為一個強大的開源 CI/CD 框架,提供了彈性且可擴充套件的管道(Pipeline)來自動化我們的構建、測試和佈署流程。本文將探討如何使用 Tekton 來佈署應用程式,並詳細解析相關的技術細節和實踐經驗。

Tekton 的基本架構與任務定義

Tekton 的核心概念是 Task 和 Pipeline。Task 定義了一組有序的步驟(Steps),而 Pipeline 則是由多個 Task 組成的有向無環圖(DAG)。每個 Task 可以視為一個獨立的容器化任務,這些任務可以被靈活地組合和重用。

第一個 Task:生成映像檔標籤

第一個 Task 名為 generate-image-tag,其主要功能是根據結果映像檔 URL 和時間戳記生成一個唯一的映像檔名稱。這裡使用了一個包含 kubectlgit 的容器映像檔。雖然本任務不需要 kubectl,但 git 是必需的。

steps:
  - name: generate-image-tag
    image: <your-built-image-with-kubectl-and-git>
    script: |-
      #!/bin/bash
      IMAGE_URL=$(params.imageURL)
      TIMESTAMP=$(date +%Y%m%d%H%M%S)
      IMAGE_NAME="${IMAGE_URL}:${TIMESTAMP}"
      echo -n "${IMAGE_NAME}" > $(results.image-url.path)

內容解密:

  1. IMAGE_URL=$(params.imageURL):取得引數中的映像檔 URL。
  2. TIMESTAMP=$(date +%Y%m%d%H%M%S):生成當前時間戳記,用於唯一標識映像檔。
  3. echo -n "${IMAGE_NAME}" > $(results.image-url.path):將生成的映像檔名稱寫入結果檔案中,以便後續任務使用。

使用 Kaniko 構建和推播映像檔

第二個 Task 使用 Google 的 Kaniko 專案來構建和推播 Docker 映像檔,而無需特權容器或 Docker 守護程式。

steps:
  - name: build-and-push
    image: gcr.io/kaniko-project/executor:v0.16.0
    args:
      - --dockerfile=$(params.pathToDockerFile)
      - --destination=$(params.imageURL)
      - --context=$(params.pathToContext)
      - --verbosity=debug
      - --skip-tls-verify

內容解密:

  1. --dockerfile=$(params.pathToDockerFile):指定 Dockerfile 的路徑。
  2. --destination=$(params.imageURL):指定映像檔推播的目的地。
  3. --context=$(params.pathToContext):指定構建上下文的路徑。
  4. Kaniko 使用指定的引數來構建和推播映像檔,無需 Docker 守護程式。

觸發 ArgoCD 佈署新映像檔

第三個 Task 負責更新 Git 倉函式庫中的佈署組態,並觸發 ArgoCD 自動佈署新映像檔。

steps:
  - name: patch-and-push
    image: docker.apps.192-168-2-114.nip.io/gitcommit/gitcommit
    script: |-
      #!/bin/bash
      export GIT_URL="$(params.gitURL)"
      # ... 省略其他指令碼內容 ...
      git push

內容解密:

  1. export GIT_URL="$(params.gitURL)":取得 Git 倉函式庫的 URL。
  2. SSH 金鑰組態:將 SSH 私鑰複製到指定目錄並組態 known_hosts,以便安全地存取 Git 倉函式庫。
  3. git clonekubectl patch:克隆倉函式庫、更新佈署組態並提交更改。
  4. git push:將更新後的組態推播到遠端倉函式庫,觸發 ArgoCD 自動佈署。

Pipeline 的定義與任務串聯

最後,我們將上述三個 Task 組合成一個 Pipeline,定義任務之間的依賴關係和引數傳遞。

tasks:
  - name: generate-image-tag
    taskRef:
      name: generate-image-tag
  - name: build-and-push
    taskRef:
      name: build-and-push
    params:
      - name: imageURL
        value: $(tasks.generate-image-tag.results.image-url)
  - name: update-operations-git
    taskRef:
      name: patch-deployment
    params:
      - name: imageURL
        value: $(tasks.generate-image-tag.results.image-url)

圖表翻譯:

此圖示展示了 Tekton Pipeline 中 Task 的執行順序和依賴關係。首先,generate-image-tag Task 生成映像檔標籤;接著,build-and-push Task 使用該標籤構建和推播映像檔;最後,update-operations-git Task 更新 Git 倉函式庫中的佈署組態。這些 Task 之間透過結果和引數進行資料傳遞,形成了一個完整的 CI/CD 流程。

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Tekton ArgoCD 自動化佈署 Kubernetes 應用

package "Kubernetes Cluster" {
    package "Control Plane" {
        component [API Server] as api
        component [Controller Manager] as cm
        component [Scheduler] as sched
        database [etcd] as etcd
    }

    package "Worker Nodes" {
        component [Kubelet] as kubelet
        component [Kube-proxy] as proxy
        package "Pods" {
            component [Container 1] as c1
            component [Container 2] as c2
        }
    }
}

api --> etcd : 儲存狀態
api --> cm : 控制迴圈
api --> sched : 調度決策
api --> kubelet : 指令下達
kubelet --> c1
kubelet --> c2
proxy --> c1 : 網路代理
proxy --> c2

note right of api
  核心 API 入口
  所有操作經由此處
end note

@enduml

圖表翻譯: 此圖表展示了 Tekton Pipeline 中各個 Task 之間的依賴關係。generate-image-tag Task 生成的映像檔標籤被後續的 build-and-pushupdate-operations-git Task 使用,從而實作了完整的自動化佈署流程。

自動化佈署與 GitOps 實踐

在前面的章節中,我們探討瞭如何利用 Tekton 進行 CI/CD 流程的自動化。本章節將深入介紹如何結合 GitOps 實踐,實作應用程式的自動佈署與管理。

Tekton Pipeline 的佈署與執行

為了實作自動化佈署,首先需要佈署 Tekton Pipeline。以下是佈署步驟:

  1. chapter14/yaml/tekton-source-git.yaml 檔案新增到叢集中,指定 Tekton 從哪裡取得應用程式碼。
  2. 編輯 chapter14/yaml/tekton-image-result.yaml,將 192-168-2-114 替換為伺服器 IP 地址的雜湊表示,並將其新增到叢集中。
  3. 編輯 chapter14/yaml/tekton-task1.yamlchapter14/yaml/tekton-task3.yaml,將映像主機替換為 Docker 登入檔的地址,並將檔案新增到叢集中。
  4. chapter14/yaml/tekton-task2.yamlchapter14/yaml/tekton-pipeline.yamlchapter14/yaml/tekton-pipeline-run.yaml 新增到叢集中。

Pipeline 執行進度檢視

可以使用 kubectl 或 Tekton 的 CLI 工具 tkn 檢視 Pipeline 的執行進度。例如:

tkn pipelinerun describe build-hello-pipeline-run -n python-hello-build

自動化構建

為了實作自動化構建,需要設定 Tekton Trigger。當 GitLab 接收到提交時,Trigger 將通知 Tekton 建立一個新的 PipelineRun 物件。

  1. chapter14/yaml/tekton-webhook-cr.yaml 新增到叢集中,建立一個 ClusterRole。
  2. 編輯 chapter14/yaml/tekton-webhook.yaml,將 192-168-2-114 替換為叢集 IP 地址,並將其新增到叢集中。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: gitlab-webhook
  namespace: python-hello-build
  annotations:
    cert-manager.io/cluster-issuer: ca-issuer
spec:
  rules:
  - host: "python-hello-application.build.192-168-2-114.nip.io"
    http:
      paths:
      - backend:
          serviceName: el-gitlab-listener
          servicePort: 8080
        pathType: ImplementationSpecific
  tls:
  - hosts:
    - "python-hello-application.build.192-168-2-114.nip.io"
    secretName: ingresssecret

GitLab Webhook 組態

  1. 登入 GitLab,進入 Admin Area | Network,允許 webhook 請求本地網路。
  2. hello-python 專案中,進入 Settings | Webhooks,組態 webhook URL 和 Secret Token。

ArgoCD 的佈署與使用

ArgoCD 是一個 GitOps 控制器,可以實作應用程式的自動佈署與管理。

ArgoCD 佈署步驟

  1. 使用標準 YAML 檔案佈署 ArgoCD:
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
  1. 編輯 chapter14/yaml/argocd-ingress.yaml,將 192-168-2-140 替換為 IP 地址,並將其新增到叢集中。
  2. 取得 root 密碼:
kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2
  1. 編輯 argocd-server Deployment,新增 --insecure 引數。

ArgoCD 使用

  1. 登入 ArgoCD,使用 Ingress 主機名和 root 密碼。
  2. 下載 ArgoCD CLI 工具,並使用 ./argocd login 命令登入。
  3. 建立 python-hello 名稱空間。