如何藉助 Tekton 實現微服務的 Pipeline

作者 | Alex Soto

譯者 | 張衛濱

策劃 | 丁曉昀

在微服務架構中,應用程序是由多個相互連接的服務組成的,這些服務協同工作以實現所需的業務功能。所以,一個典型的企業級微服務架構如下所示:

最初,我們可能認爲使用微服務架構實現一個應用程序是很容易的事情。但是,要恰當地完成這一點並不容易,因爲我們會面臨一些新的挑戰,而這些挑戰是單體架構所未曾遇到的。舉例來講,這樣的挑戰包括容錯、服務發現、擴展性、日誌和跟蹤等。

爲了應對這些挑戰,每個微服務都需要實現在 Red Hat 被稱爲 “微服務特性(microservicility)” 的內容。這個術語指的是除了業務邏輯之外,服務必須要實現的一個橫切性關注點的列表。

這些關注點總結起來如下圖所示:

在本系列的第一部分和第二部分中,我們分別討論瞭如何使用 Quarkus 和 Istio 實現這些微服務特性。但是,還有一個微服務特性是我們在這兩篇文章中都沒有涉及到的,那就是 Pipeline

在微服務架構中,我們應該能夠獨立地部署服務,而不需要任何的部署編排(orchestration)。在服務間沒有任何的編排意味着沒有必要在每次部署的時候都部署和發佈整個應用程序,只需要其中的很小一部分就可以了。

如果我們能夠發佈應用中各個小的組成部分的話,那麼這會帶來一些好處:

出於這樣的原因,每個服務應該都有自己部署 Pipeline,這樣的話,我們就可以隨時部署它,只需要遵循它自己的規則或流程即可。

但是,爲每個服務都創建一個部署 Pipeline 會帶來一些挑戰,這是我們需要解決的:

大多數問題的答案就是 Pipeline 即代碼(pipeline-as-code)。這種技術能夠允許我們以代碼或可視爲代碼的文件(YAML)的形式創建持續交付 Pipeline。

因爲 Pipeline 是以代碼的形式定義的,所以它們應該置於源碼控制之下,這意味着它們是可以重用、可以建立分支也可以創建 tag。更重要的是,我們能夠將服務代碼和交付 Pipeline 添加到相同的倉庫中。

Kubernetes 正在成爲部署微服務的事實標準工具。它是一個開源的系統,用來自動化、編排、擴展和管理容器。

正如我們在前面的兩篇文章中所講到的那樣,在我們提到的十個微服務特性中,通過使用 Kubernetes 能夠覆蓋其中的三個。

如果我們使用 Istio,可以實現另外五個微服務特性,即服務發現、回彈性、認證、監控和跟蹤。

使用 Kubernetes 和 Istio 是個好主意,但是 Pipeline 該怎麼實現呢?我們該如何實現一個 Kubernetes 原生的持續交付 Pipeline 呢?引入 Tekton 是一個可行的解決方案。

1 Tekton

Tekton 是一個 Kubernetes 原生的構建 CI/CD Pipeline 的解決方案,能夠以 Kubernetes 擴展的方式安裝和運行。它提供了一組 Kubernetes 自定義資源(custom resource),藉助這些自定義資源,我們可以爲 Pipeline 創建和重用構建塊。

實體

Tekton 定義瞭如下的基本 Kubernetes 自定義資源定義(Kubernetes Custom Resource Definition,CRD)來構建 Pipeline:

PipelineResource能夠定義可引用的資源,比如源碼倉庫或容器鏡像。

Task定義了一個按順序執行的 step 列表。每個 step 會在容器中執行命令。每個 task 都是一個 Kubernetes Pod,Pod 中包含了與 step 同等數量的容器。

TaskRun會實例化一個要執行的Task,並且會帶有具體的輸入、輸出和參數。

Pipeline會定義一個 task 的列表,這些 task 會按照特定的順序來執行。

PipelineRun會實例化一個要執行的Pipeline,並且會帶有具體的輸入、輸出和參數。它會自動爲每個Task創建TaskRun實例。

Task可以通過創建TaskRun對象單獨運行,也可以作爲Pipeline的一部分運行。

安裝

執行如下的命令來啓動集羣:

minikube start -p tekton --kubernetes-version='v1.19.0' --vm-driver='virtualbox' --memory=4096
  [istio] minikube v1.17.1 on Darwin 11.3
  Kubernetes 1.20.2 is now available. If you would like to upgrade, specify: --kubernetes-version=v1.20.2
  minikube 1.19.0 is available! Download it: https://github.com/kubernetes/minikube/releases/tag/v1.19.0
  To disable this notice, run: 'minikube config set WantUpdateNotification false'
  Using the virtualbox driver based on existing profile
  You cannot change the memory size for an exiting minikube cluster. Please first delete the cluster.
  Starting control plane node istio in cluster istio
  Restarting existing virtualbox VM for "istio" ...
  Preparing Kubernetes v1.19.0 on Docker 19.03.12 ...
  Verifying Kubernetes components...
  Enabled addons: storage-provisioner, default-storageclass
  Done! kubectl is now configured to use "tekton" cluster and "" namespace by default

Kubernetes 啓動就緒之後,我們可以下載tkn CLI 工具來與 Tekton Pipeline 進行交互。在本例中,我們從發佈頁面下載tkn 0.18.0。

現在,我們通過執行如下的命令安裝 Tekton 控制器:

kubectl apply -f 
https://storage.googleapis.com/tekton-releases/pipeline/previous/v0.24.0/release.yaml
namespace/tekton-pipelines created
podsecuritypolicy.policy/tekton-pipelines created
clusterrole.rbac.authorization.k8s.io/tekton-pipelines-controller-cluster-access created
clusterrole.rbac.authorization.k8s.io/tekton-pipelines-controller-tenant-access created
clusterrole.rbac.authorization.k8s.io/tekton-pipelines-webhook-cluster-access created
role.rbac.authorization.k8s.io/tekton-pipelines-controller created
…
deployment.apps/tekton-pipelines-controller created
service/tekton-pipelines-controller created
horizontalpodautoscaler.autoscaling/tekton-pipelines-webhook created
deployment.apps/tekton-pipelines-webhook created
service/tekton-pipelines-webhook created

2 定義 Pipeline

接下來,我們看一下該如何在 Tekton 中定義持續交付的 Pipeline。這個 pipeline 由兩個 task 組成。第一個 task 從 GitHub 上 clone 項目,使用 Maven(可以是其他任意的構建工具甚至是不同的語言)構建 Java 項目,創建容器鏡像並將其推送至一個容器 registry。第二個任務會將服務部署至一個 Kubernetes 集羣。

但是,在開發 pipeline 之前,我們先通過一個簡單的 “Hello World” 來理解 Tekton 的概念。

第一個 Task

我們創建一個只包含單個 step 的 task,該 task 會啓動一個busybox容器並在容器中執行echo命令。創建名爲hello-world-task.yml的文件:

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
 name: helloworld
spec:
 steps:
   - name: sayhello
     image: busybox
     command:
       - echo
     args: ['Hello World']
kubectl apply -f src/main/tekton/hello-world-task.yml -n default
task.tekton.dev/helloworld created

使用tkn列出當前註冊的所有 task:

tkn task list
NAME         DESCRIPTION   AGE
helloworld                 1 minute ago

此時只是註冊了這個 task,現在我們需要初始化一個 task 來執行它。我們可以通過使用tkn CLI 或應用一個TaskRun來實現這一點。在這裏,我們創建一個名爲 hello-world-taskrun.ymlTaskRun文件,它會在name字段中註冊前文所述的task

apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
 name: helloworld-run
spec:
 taskRef:
   name: helloworld

然後,我們應用這個文件,task 就會被觸發。

kubectl apply -f src/main/tekton/hello-world-taskrun.yml
taskrun.tekton.dev/helloworld-run created

我們可以使用tkn列出當前所有的 task:

tkn tr list
NAME             STARTED         DURATION   STATUS
helloworld-run   8 seconds ago   ---        Running(Pending)

歸根到底,Task只是運行在 Kubernetes 集羣中的一個 Kubernetes Pod,而每個 step 則是 Pod 中的一個容器。執行如下的命令獲取當前的 Pod:

kubectl get pods
NAME                       READY   STATUS      RESTARTS   AGE
helloworld-run-pod-75dwt   0/1     Completed   0          45s

Pod 的狀態是已完成,因爲 task 已經執行完畢了。它會運行一個容器,容器的名字會符合TaskRunmetadata部分 name 字段所定義的值。

我們可以描述一下 Pod,請關注containers區域,以獲取 task 啓動的容器的概況:

kubectl describe pod helloworld-run-pod-75dwt
…
Containers:
  step-sayhello:
    Container ID:  docker://e3bb6b747e6cbb76829e7658b7bf2976f3f09861775a4584eccfba0c143996a6
    Image:         busybox
...

最後,我們可以使用tkn的 logs 命令查看 TaskRun 的日誌:

tkn tr logs helloworld-run
[sayhello] Hello World

現在,我們對 Tekton 的 task 已經有了基本的瞭解,接下來我們更進一步,實現一個具備了所需 step 的真正 pipeline。

Pipeline 資源

PipelineResource定義了輸入 / 輸出資源的位置,這些資源會被 Task 中的 step 所用到。這些參數通常會遵循 Git URL 或者容器鏡像全限定名的形式。

我們創建一個新的PipelineResource文件來配置項目的倉庫:

apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
 name: git-source
spec:
 type: git
 params:
   - name: url
     value: https://github.com/lordofthejars/hello-world-tekton.git
kubectl apply -f src/main/tekton/git-pipeline-resource.yml -n default
pipelineresource.tekton.dev/git-source created

然後,創建另外一個PipelineResource來設置容器鏡像:

apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
 name: hello-world-image
spec:
 type: image
 params:
   - name: url
     value: quay.io/lordofthejars/hello-world-quarkus-tekton:1.0.0
kubectl apply -f src/main/tekton/container-image-resource.yml
pipelineresource.tekton.dev/hello-world-image created
tkn resource list
NAME                TYPE    DETAILS
git-source          git     url: https://github.com/lordofthejars/hello-world-tekton.git
hello-world-image   image   url: quay.io/lordofthejars/hello-world-quarkus-tekton:1.0.0

Task

在創建 task 之前,我們先創建一個 Kubernetes Secret,它包含了兩個用於 Quay 訪問憑證的鍵 / 值對,分別是 Quay 的用戶名和 Quay 的密碼。請將 username 和 password 的值替換成正確的值。

kubectl create secret generic quay-credentials --from-literal=quay-username='yyy' --from-literal=quay-password='xxx'
secret/quay-credentials created

接下來,我們創建一個Task來構建項目,創建 Linux 容器鏡像並將其推送至容器 registry 上(在本例中,我們使用 Quay,但是可以切換成任意的其他方案)。

因爲這是一個使用 Quarkus 實現的 Java 項目,所以我們會通過集成 Jib 實現以 Dockerless 的方式創建容器鏡像。在一個容器運行時(Tekton 就是這種情況)中構建容器鏡像時,我們可能會遇到一些在容器中運行 task 容器的問題(構建新的容器)。這也是爲何採用 Dockerless 技術創建容器的重要原因。對於 Java 項目來說,Jib 是一個可行的方案,但是也有其他通用的、不針對特定語言的方案,比如 Buildah 或 Kaniko。

我們創建一個task,它會執行執行 Maven package goal,設置構建所需的 Quarkus 選項並將容器鏡像推送至 Quay。當然,我們還需要以輸入和輸出(PipelineResource)的方式設置 Git 倉庫和容器鏡像名,並以參數(Kubernetes Secrets)的形式設置 Quay 的用戶名和密碼。

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
 name: build-app
spec:
 params:
 - name: quay-credentials-secret
   type: string
   description: name of the secret holding the quay credentials
   default: quay-credentials
 resources:
   inputs:
     - name: source
       type: git
   outputs:
     - name: builtImage
       type: image
 steps:
   - name: maven-build
     image: docker.io/maven:3.6-jdk-11-slim
     command:
       - mvn
     args:
       - clean
       - package
       - -Dquarkus.container-image.push=true
     env:
     - name: QUARKUS_CONTAINER_IMAGE_IMAGE
       value: $(outputs.resources.builtImage.url)
     - name: QUARKUS_CONTAINER_IMAGE_USERNAME
       valueFrom:
         secretKeyRef:
           name: $(params.quay-credentials-secret)
           key: quay-username
     - name: QUARKUS_CONTAINER_IMAGE_PASSWORD
       valueFrom:
         secretKeyRef:
           name: $(params.quay-credentials-secret)
           key: quay-password
     workingDir: "/workspace/source/"

在前面的文件中,我們看到 Quay 憑證的 secret 名被設置爲參數。參數quay-credentials有一個默認值,它的值與kubectl creates secret命令中所用的值是相同的。

輸入參數被命名爲source,類型爲git

輸出參數是容器鏡像的名稱。

env部分中,我們定義了一些環境變量,用來配置 Quarkus 容器鏡像擴展如何構建和推送容器鏡像:

在 Kubernetes 集羣中註冊 task:

kubectl apply -f src/main/tekton/build-push-task.yml
tkn task list
NAME         DESCRIPTION   AGE
build-app                  3 hours ago

最後我們通過創建一個TaskRun來初始化這個 task,此時我們需要鏈接在前文中通過PipelineResource創建的輸入 / 輸出資源並將 secret 名稱設置爲參數。

apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
 name: build-app-run
spec:
 params:
   - name: quay-credentials-secret
     value: quay-credentials
 resources:
   inputs:
     - name: source
       resourceRef:
         name: git-source
   outputs:
     - name: builtImage
       resourceRef:
         name: hello-world-image
 taskRef:
   name: build-app

注意,resourceRef字段指向了在前文中定義的PipelineResource的名稱。

TaskRun被應用的時候,構建過程就開始執行了,它會 clone 項目,使用 Maven 進行構建,然後創建並推送鏡像。通過使用tkn CLI,我們可以看到當前 task 的實時日誌:

tkn tr logs -f
? Select taskrun:  [Use arrows to move, type to filter]
> build-app-run started 38 minutes ago
  helloworld-run started 1 day ago
[git-source-source-w2ck5] {"level":"info","ts":1620922474.2565205,"caller":"git/git.go:169","msg":"Successfully cloned https://github.com/lordofthejars/hello-world-tekton.git @ ee3edc414c47f2bdeda9cc7c47ac54427d35a9dc (grafted, HEAD) in path /workspace/source"}
[git-source-source-w2ck5] {"level":"info","ts":1620922474.276228,"caller":"git/git.go:207","msg":"Successfully initialized and updated submodules in path /workspace/source"}
...
[maven-build] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-plugin-parameter-documenter/2.0.6/maven-plugin-parameter-documenter-2.0.6.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/maven-plugin-parameter-documenter/2.0.6/maven-plugin-parameter-documenter-2.0.6.pom (1.9 kB at 58 kB/s)
[maven-build] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/reporting/maven-reporting-api/2.0.6/maven-reporting-api-2.0.6.pom
…
[maven-build] [INFO] [io.quarkus.container.image.jib.deployment.JibProcessor] Pushed container image quay.io/lordofthejars/hello-world-quarkus-tekton:1.0.0 (sha256:e71b0808af36ce3b9b980b2fb83886be2e06439ee454813052a115829e1e727c)
[maven-build] [INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 24202ms
[maven-build] [INFO] ------------------------------------------------------------------------
[maven-build] [INFO] BUILD SUCCESS
[maven-build] [INFO] ------------------------------------------------------------------------
[maven-build] [INFO] Total time:  01:16 min
[maven-build] [INFO] Finished at: 2021-05-13T16:15:52Z
[maven-build] [INFO] ------------------------------------------------------------------------
[image-digest-exporter-88mpr] {"severity":"INFO","timestamp":"2021-05-13T16:15:53.025263494Z","caller":"logging/config.go:116","message":"Successfully created the logger."}
[image-digest-exporter-88mpr] {"severity":"INFO","timestamp":"2021-05-13T16:15:53.025374882Z","caller":"logging/config.go:117","message":"Logging level set to: info"}
[image-digest-exporter-88mpr] {"severity":"INFO","timestamp":"2021-05-13T16:15:53.025508459Z","caller":"imagedigestexporter/main.go:59","message":"No index.json found for: builtImage","commit":"b86a9a2"}

Pipeline

現在,我們已經創建了一個簡單的 task。但是,實際的持續交付 / 部署 pipeline 應該是由多個 task 組成的:構建並推送容器鏡像,然後將其部署到 Kubernetes 集羣中。

接下來我們創建具有兩個 step 的 task:

創建名爲deploy-task.yml的文件,內容如下所示:

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
 name: kubectl-deploy
spec:
 params:
 - name: deploymentFile
   type: string
   description: deployment file location
 resources:
   inputs:
     - name: source
       type: git
     - name: builtImage
       type: image
 steps:
 - name: update-deployment-file
   image: quay.io/lordofthejars/image-updater:1.0.0
   script: |
     #!/usr/bin/env ash
     yq eval -i '.spec.template.spec.containers[0].image = env(DESTINATION_IMAGE)' $DEPLOYMENT_FILE
   env:
     - name: DESTINATION_IMAGE
       value: "$(inputs.resources.builtImage.url)"
     - name: DEPLOYMENT_FILE
       value: "/workspace/source/$(inputs.params.deploymentFile)"
 - name: kubeconfig
   image: quay.io/rhdevelopers/tutorial-tools:0.0.3
   command: ["kubectl"]
   args:
     - apply
     - -f
     - /workspace/source/$(inputs.params.deploymentFile)

注意,在第一個 step 中,我們使用script來代替command。要傳遞 Tekton 參數到script區域,我們需要通過環境變量來實現。

kubectl apply -f src/main/tekton/deploy-task.yml
task.tekton.dev/kubectl-deploy created
tkn task ls
NAME             DESCRIPTION   AGE
build-app                      18 hours ago
helloworld                     1 day ago
kubectl-deploy                 11 minutes ago

要部署服務,我們需要在 Kubernetes 集羣中執行kubectl命令。爲了實現這一點,我們需要設置一個 Kubernetes Role以允許default服務賬號(因爲這是在我們的樣例中運行 Tekton Pipeline 所使用的服務賬號)具備相應的權限。這個角色必須要允許在運行的容器中應用 Kubernetes 資源。

創建名爲pipeline-sa-role.yml的文件,內容如下:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
 name: pipeline-extra-role
rules:
 - apiGroups:
     - ""
   resources:
     - pods
     - services
     - endpoints
     - configmaps
     - secrets
   verbs:
     - "*"
 - apiGroups:
     - apps
   resources:
     - deployments
     - daemonsets
     - replicasets
     - statefulsets
   verbs:
     - "*"
 - apiGroups:
     - ""
   resources:
     - pods
   verbs:
     - get
 - apiGroups:
     - apps
   resources:
     - replicasets
   verbs:
     - get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
 name: pipeline-exta-role-binding
roleRef:
 kind: Role
 name: pipeline-extra-role
 apiGroup: rbac.authorization.k8s.io
subjects:
 - kind: ServiceAccount
   name: default

註冊角色:

kubectl apply -f src/main/tekton/pipeline-sa-role.yml
role.rbac.authorization.k8s.io/pipeline-extra-role created
rolebinding.rbac.authorization.k8s.io/pipeline-exta-role-binding created

現在,我們已經可以創建 Tekton Pipeline 將這兩個 task 組合在一起了。在這裏,定義 pipeline 參數至關重要,因爲在 pipeline 定義中引用 Tekton Task 的時候,要設置這些參數。在這兩個 task 中,我們都定義了params值(quay-credentials-secretdeploymentFile),並引用pipelineresource作爲輸入 / 輸出。

創建pipeline.yml文件:

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
 name: hello-world-pipeline
spec:
 resources:
   - name: appSource
     type: git
   - name: containerImage
     type: image
 tasks:
   - name: build-app
     taskRef:
       name: build-app
     params:
       - name: quay-credentials-secret
         value: quay-credentials
     resources:
       inputs:
         - name: source
           resource: appSource
       outputs:
         - name: builtImage
           resource: containerImage
   - name: kube-deploy
     taskRef:
       name: kubectl-deploy
     params:
       - name: deploymentFile
         value: src/main/kubernetes/kubernetes.yml
     runAfter:
       - build-app
     resources:
       inputs:
         - name: source
           resource: appSource
         - name: builtImage
           resource: containerImage
kubectl apply -f src/main/tekton/pipeline.yml
pipeline.tekton.dev/hello-world-pipeline created

我們可以使用tkn CLI 列出 pipeline:

tkn pipeline list
NAME                   AGE             LAST RUN   STARTED   DURATION   STATUS
hello-world-pipeline   5 seconds ago   ---        ---       ---        ---

通過命令描述 pipeline,能夠讓我們看到 pipeline 的概述以及在運行它的時候,必須要定義哪些內容:

tkn pipeline describe hello-world-pipeline
Name:        hello-world-pipeline
Namespace:   default
 Resources
 NAME               TYPE
 ∙ appSource        git
 ∙ containerImage   image
 Params
 No params
 Results
 No results
 Workspaces
 No workspaces
  Tasks
 NAME            TASKREF          RUNAFTER    TIMEOUT   CONDITIONS   PARAMS
 ∙ build-app     build-app                    ---       ---          quay-credentials-secret: quay-credentials
 ∙ kube-deploy   kubectl-deploy   build-app   ---       ---          deploymentFile: src/main/kubernetes/deployment.yml
 PipelineRuns
 No pipelineruns

現在,我們不需要任何的TaskRun了,因爲它們會在應用PipelineRun的時候自動創建:

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
 name: hello-world-pipeline-run
spec:
 resources:
   - name: appSource
     resourceRef:
       name: git-source
   - name: containerImage
     resourceRef:
       name: hello-world-image
 pipelineRef:
   name: hello-world-pipeline

PipelineRun中,我們設置了PipelineResourcesPipeline之間的鏈接,因爲它是由TaskRun執行的。

kubectl apply -f src/main/tekton/pipeline-run.yml
pipelinerun.tekton.dev/hello-world-pipeline-run created

與 TaskRun 類似,我們可以通過如下的命令將一個 pipeline 的日誌以流的方式鏈接起來:

tkn pipeline logs -f
…
[kube-deploy : git-source-source-sdgld] {"level":"info","ts":1620978300.0659564,"caller":"git/git.go:169","msg":"Successfully cloned https://github.com/lordofthejars/hello-world-tekton.git @ b954dbc68e0aa7e4cfb6defeff00b1e4ded2889c (grafted, HEAD) in path /workspace/source"}
[kube-deploy : git-source-source-sdgld] {"level":"info","ts":1620978300.0972755,"caller":"git/git.go:207","msg":"Successfully initialized and updated submodules in path /workspace/source"}
[kube-deploy : kubeconfig] deployment.apps/hello-world created

如果構建成功的話,服務將會部署到當前的 Kubernetes 集羣中。我們可以獲取所有的 Pod 以查看集羣中發生了什麼:

kubectl get pods
NAME                                                   READY   STATUS      RESTARTS   AGE
hello-world-59d47597c-qm9nr                            1/1     Running     0          36m
hello-world-pipeline-run-build-app-xmvg2-pod-v4vps     0/4     Completed   0          37m
hello-world-pipeline-run-kube-deploy-bfqhd-pod-x68xh   0/3     Completed   0          36m

我們可以看到有兩個已完成的 Pod。hello-world-pipeline-run-build-app Pod 對應的是build-app task,它會 clone、構建和測試服務,並且最終會創建和推送容器鏡像。hello-world-pipeline-run-kube-deploy Pod 對應kube-deploy task,它負責部署應用。

除了 task 之外,這裏還有一個正在運行的 Pod。這就是 pipeline 執行期間所部署的應用 Pod。

3 結論

開發和實現微服務架構要比開發單體應用更具挑戰性。我們相信,微服務特性能夠促使你在應用基礎設施方面正確地開發服務。

在本系列的第一篇和第二篇文章中,我們分別學習瞭如何使用 Quarkus 或 Istio 實現微服務特性,但是我們還沒有介紹 Pipeline 這項微服務特性。本文闡述瞭如何使用 Tekton 實現一個基本的持續交付 pipeline,Tekton 是一個 Kubernetes 原生的解決方案,用於構建 CI/CD pipeline。

Tekton 一個很重要的優勢是能夠在容器最終要部署的同一個集羣中創建容器鏡像。這減少了容器在某些機器上構建而在其他機器上部署時可能出現的差異。另一個優勢是使用 YAML 文件來定義 pipeline 的方式。通過這種方式,pipeline 能夠與源代碼一起存儲,使其可創建分支、可創建 tag 或版本化。

有時候,沒有必要從頭開始定義 task,在 Tekton Catalog 上,我們可以看到很多可以直接使用的 task。除此之外,如果你需要開發自定義的 task 的話,要藉助參數和輸入 / 輸出資源將它們設計的儘可能比較開放。通過這種方式,task 有可能實現在你的組織內的重用,從而解決類似的問題。

本文只是 Tekton 的一個簡介。我們可以看到當一個PipelineRun對象在集羣中創建的時候,pipeline 就會運行,但是觸發器 / 事件也可以觸發 Pipeline。舉例來講,事件可能是對 GitHub 倉庫中特性分支的推送。觸發器是一個更高級的話題,你可以通過該地址學習關於觸發器的更多知識。

用於闡述本文的源碼可以在 GitHub 倉庫中找到。第一篇和第二篇文章的源碼也分別可以在這裏和這裏獲取。

作者簡介:

Alex Soto 是紅帽公司的開發者體驗總監。他對 Java 領域、軟件自動化充滿熱情,他相信開源軟件模式。Soto 是 Manning 的《Testing Java Microservices》 和 O’Reilly 的《Quarkus Cookbook》 兩本書的共同作者,他還是多個開源項目的貢獻者。自 2017 年以來,他一直是 Java Champion,是國際演講者和 Salle URL 大學的教師。你可以在 Twitter 上關注他(Alex Soto ⚛️),隨時瞭解 Kubernetes 和 Java 領域的動態。

原文鏈接:

https://www.infoq.com/articles/microservicilities-tekton/

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/Bna2_M9sQp4-My1oyBzKBQ