如何藉助 Tekton 實現微服務的 Pipeline
作者 | Alex Soto
譯者 | 張衛濱
策劃 | 丁曉昀
在微服務架構中,應用程序是由多個相互連接的服務組成的,這些服務協同工作以實現所需的業務功能。所以,一個典型的企業級微服務架構如下所示:
最初,我們可能認爲使用微服務架構實現一個應用程序是很容易的事情。但是,要恰當地完成這一點並不容易,因爲我們會面臨一些新的挑戰,而這些挑戰是單體架構所未曾遇到的。舉例來講,這樣的挑戰包括容錯、服務發現、擴展性、日誌和跟蹤等。
爲了應對這些挑戰,每個微服務都需要實現在 Red Hat 被稱爲 “微服務特性(microservicility)” 的內容。這個術語指的是除了業務邏輯之外,服務必須要實現的一個橫切性關注點的列表。
這些關注點總結起來如下圖所示:
在本系列的第一部分和第二部分中,我們分別討論瞭如何使用 Quarkus 和 Istio 實現這些微服務特性。但是,還有一個微服務特性是我們在這兩篇文章中都沒有涉及到的,那就是 Pipeline。
在微服務架構中,我們應該能夠獨立地部署服務,而不需要任何的部署編排(orchestration)。在服務間沒有任何的編排意味着沒有必要在每次部署的時候都部署和發佈整個應用程序,只需要其中的很小一部分就可以了。
如果我們能夠發佈應用中各個小的組成部分的話,那麼這會帶來一些好處:
-
減少在應用中引入破壞性變更的幾率。
-
如果出現錯誤的話,更容易部署和回滾。
-
我們可以增加部署至生產環境的頻率。
出於這樣的原因,每個服務應該都有自己部署 Pipeline,這樣的話,我們就可以隨時部署它,只需要遵循它自己的規則或流程即可。
但是,爲每個服務都創建一個部署 Pipeline 會帶來一些挑戰,這是我們需要解決的:
-
如何實現和管理多個 Pipeline。
-
如何爲所有的服務實現自動部署。
-
如何跨服務共享 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.yml
的TaskRun
文件,它會在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 已經執行完畢了。它會運行一個容器,容器的名字會符合TaskRun
中metadata
部分 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 容器鏡像擴展如何構建和推送容器鏡像:
-
容器鏡像名是在輸出資源中定義的。
-
Quay 憑證會從 Kubernetes
Secret
中注入進來。
在 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:
-
第一個 step 是使用
PipelineResource
所設置的容器鏡像更新 KubernetesDeployment
。在編輯 deployment YAML 文件時,我們可以使用 yq 工具。同時,我們使用script
代替command
來展示在容器中運行命令的另外一種方式。 -
第二個 step 執行
kubectl
命令以部署服務。 -
對於這個 task 來講,我們需要三個參數:deployment 文件、存儲 deployment 文件的 Git 倉庫以及前面 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-secret
和deploymentFile
),並引用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
中,我們設置了PipelineResources
和Pipeline
之間的鏈接,因爲它是由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