Knative 社區很早就在討論用 Tekton 替換 Build 模塊的事宜。Knative Build 官方已經正式說明再也不建議使用 Knative Build 了。
git
若是你知道 Knative Build 是什麼相信你理解起 Tekton 就是很容易的一件事了。github
A Kubernetes-native Build resource.
A K8s-native Pipeline resource. https://tekton.dev
Tekton 主要由以下五個核心概念組成:web
Task
Task 就是一個任務執行模板,之因此說 Task 是一個模板是由於 Task 定義中能夠包含變量,Task 在真正執行的時候須要給定變量的具體值。Tekton 的 Task 很相似於一個函數的定義,Task 經過 inputs.params 定義須要哪些入參,而且每個入參還能夠指定默認值。Task 的 steps 字段表示當前 Task 是有哪些子步驟組成的。每個步驟具體就是一個鏡像的執行,鏡像的啓動參數能夠經過 Task 的入參使用模板語法進行配置。docker
apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: task-with-parameters spec: inputs: params: - name: flags type: array - name: someURL type: string steps: - name: build image: registry.cn-hangzhou.aliyuncs.com/knative-sample/alpine:3.9 command: ["sh", "-c"] args: [ "echo ${inputs.params.flags} ; echo ${someURL}"]
TaskRun
Task 定義好之後是不能執行的,就像一個函數定義好之後須要調用才能執行同樣。因此須要再定義一個 TaskRun 去執行 Task。TaskRun 主要是負責設置 Task 須要的參數,並經過 taskRef 字段引用要執行的 Task。api
apiVersion: tekton.dev/v1alpha1 kind: TaskRun metadata: name: run-with-parameters spec: taskRef: name: task-with-parameters inputs: params: - name: flags value: "--set" - name: someURL value: "https://github.com/knative-sample"
Pipeline
一個 TaskRun 只能執行一個 Task,當須要編排多個 Task 的時候就須要 Pipeline 出馬了。Pipeline 是一個編排 Task 的模板。Pipeline 的 params 聲明瞭執行時須要的入參。 Pipeline 的 spec.tasks 定義了須要編排的 Task。Tasks 是一個數組,數組中的 task 並非經過數組聲明的順序去執行的,而是經過 runAfter 來聲明 task 執行的順序。Tekton controller 在解析 CRD 的時候會解析 Task 的順序,而後依據設定的順序依次去執行。Pipeline 在編排 Task 的時候須要給每個 Task 傳入必須的參數,這些參數的值能夠來自 Pipeline 自身的 params。數組
apiVersion: tekton.dev/v1alpha1 kind: Pipeline metadata: name: pipeline-with-parameters spec: params: - name: context type: string description: Path to context default: /some/where/or/other tasks: - name: task-1 taskRef: name: build params: - name: pathToDockerFile value: Dockerfile - name: pathToContext value: "${params.context}" - name: task-2 taskRef: name: build-push runAfter: - source-to-image params: - name: pathToDockerFile value: Dockerfile - name: pathToContext value: "${params.context}"
PipelineRun
和 Task 同樣 Pipeline 定義完成之後也是不能直接執行的,須要 PipelineRun 才能執行 Pipeline。PipelineRun 的主要做用是給 Pipeline 設定必要的入參,並執行 Pipeline。app
apiVersion: tekton.dev/v1alpha1 kind: PipelineRun metadata: name: pipelinerun-with-parameters spec: pipelineRef: name: pipeline-with-parameters params: - name: "context" value: "/workspace/examples/microservices/leeroy-web"
PipelineResource
前面已經介紹了 Tekton 的四個核心概念。如今咱們已經知道怎麼定義 task、執行 task 以及編排 task 了。但可能你還想在 Task 之間共享資源,這就是 PipelineResource 的做用。好比咱們能夠把 git 倉庫信息放在 PipelineResource 中。這樣全部 Pipeline 就能夠共享這份數據了。函數
piVersion: tekton.dev/v1alpha1 kind: PipelineResource metadata: name: wizzbang-git namespace: default spec: type: git params: - name: url value: https://github.com/wizzbangcorp/wizzbang.git - name: revision value: master
受權信息
git 倉庫、鏡像倉庫這些都是須要鑑權才能使用的。因此還須要一種設定鑑權信息的機制。Tekton 自己是 Kubernetes 原生的編排系統。因此能夠直接使用 Kubernetes 的 ServiceAccount 機制實現鑑權。
實例以下:ui
apiVersion: v1 kind: Secret metadata: name: ack-cr-push-secret annotations: tekton.dev/docker-0: https://registry.cn-hangzhou.aliyuncs.com type: kubernetes.io/basic-auth stringData: username: <cleartext non-encoded> password: <cleartext non-encoded>
apiVersion: v1 kind: ServiceAccount metadata: name: pipeline-account secrets: - name: ack-cr-push-secret
apiVersion: tekton.dev/v1alpha1 kind: PipelineRun metadata: generateName: tekton-kn-sample- spec: pipelineRef: name: build-and-deploy-pipeline ... ... serviceAccount: pipeline-account
https://github.com/knative-sample/tekton-knative 這是一個完整的 Tekton 的 Helle World。下面咱們一塊兒體驗一下這個 Helle World。
在開始實戰以前你須要有一個 Kubernetes 集羣,並還須要安裝 Knative 和 Tekton。tekton-knative 中的 release-v0.5.2.yaml 直接提交到 Kubernetes 集羣便可完成 Tekton 的安裝。下面咱們開始體驗使用 Tekton 從源碼到構建再到部署的自動化過程。url
clone 代碼
clone 代碼到本地。
git clone https://github.com/knative-sample/tekton-knative
建立 PipelineResource
主要內容在 resources/picalc-git.yaml
文件中。以下所示主要是把 https://github.com/knative-sample/tekton-knative 保存在 resource 中給其餘資源使用。
apiVersion: tekton.dev/v1alpha1 kind: PipelineResource metadata: name: tekton-knative-git spec: type: git params: - name: revision value: master - name: url value: https://github.com/knative-sample/tekton-knative
建立 task
建立 task,這個例子中咱們建立兩個 task:source-to-image 和 deploy-using-kubectl
tasks/source-to-image.yaml
文件中。此 task 的主要功能是把源代碼編譯成鏡像。主要是使用 kaniko 實現容器內編譯 Docker 鏡像的能力。此 Task 的參數主要是設置編譯上下文的一些信息,好比:Dockerfile、ContextPath 以及目標鏡像 tag 等。
apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: source-to-image spec: inputs: resources: - name: git-source type: git params: - name: pathToContext description: The path to the build context, used by Kaniko - within the workspace default: . - name: pathToDockerFile description: The path to the dockerfile to build (relative to the context) default: Dockerfile - name: imageUrl description: Url of image repository - name: imageTag description: Tag to apply to the built image default: "latest" steps: - name: build-and-push image: registry.cn-hangzhou.aliyuncs.com/knative-sample/kaniko-project-executor:v0.10.0 command: - /kaniko/executor args: - --dockerfile=${inputs.params.pathToDockerFile} - --destination=${inputs.params.imageUrl}:${inputs.params.imageTag} - --context=/workspace/git-source/${inputs.params.pathToContext} env: - name: DOCKER_CONFIG value: /builder/home/.docker
tasks/deploy-using-kubectl.yaml
文件中。以下所示這個 Task 主要的做用是經過參數獲取到目標鏡像的信息,而後執行一條 sed 命令把 Knative Service yaml 中的 __IMAGE__
替換成目標鏡像。再經過 kubectl 發佈到 Kubernetes 中。
apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: deploy-using-kubectl spec: inputs: resources: - name: git-source type: git params: - name: pathToYamlFile description: The path to the yaml file to deploy within the git source - name: imageUrl description: Url of image repository - name: imageTag description: Tag of the images to be used. default: "latest" steps: - name: update-yaml image: alpine command: ["sed"] args: - "-i" - "-e" - "s;__IMAGE__;${inputs.params.imageUrl}:${inputs.params.imageTag};g" - "/workspace/git-source/${inputs.params.pathToYamlFile}" - name: run-kubectl image: registry.cn-hangzhou.aliyuncs.com/knative-sample/kubectl:v0.5.0 command: ["kubectl"] args: - "apply" - "-f" - "/workspace/git-source/${inputs.params.pathToYamlFile}"
定義 Pipeline
如今咱們已經有兩個 Task 了,如今咱們就用一個 PIpeline 來編排這兩個 Task:
apiVersion: tekton.dev/v1alpha1 kind: Pipeline metadata: name: build-and-deploy-pipeline spec: resources: - name: git-source type: git params: - name: pathToContext description: The path to the build context, used by Kaniko - within the workspace default: src - name: pathToYamlFile description: The path to the yaml file to deploy within the git source - name: imageUrl description: Url of image repository - name: imageTag description: Tag to apply to the built image tasks: - name: source-to-image taskRef: name: source-to-image params: - name: pathToContext value: "${params.pathToContext}" - name: imageUrl value: "${params.imageUrl}" - name: imageTag value: "${params.imageTag}" resources: inputs: - name: git-source resource: git-source - name: deploy-to-cluster taskRef: name: deploy-using-kubectl runAfter: - source-to-image params: - name: pathToYamlFile value: "${params.pathToYamlFile}" - name: imageUrl value: "${params.imageUrl}" - name: imageTag value: "${params.imageTag}" resources: inputs: - name: git-source resource: git-source
鑑權信息
以下所示,定義一個 Secret 和 ServiceAccount。而且給 ServiceAccount 綁定執行 Knative Service 的權限。
首先建立一個 Secret 保存鏡像倉庫的鑑權信息,以下所示:
apiVersion: v1 kind: Secret metadata: name: ack-cr-push-secret annotations: tekton.dev/docker-0: https://registry.cn-hangzhou.aliyuncs.com type: kubernetes.io/basic-auth stringData: username: <cleartext non-encoded> password: <cleartext non-encoded>
下面這些信息保存到文件中,而後使用 kubectl apply -f 指令提交到 Kubernetes
--- apiVersion: v1 kind: ServiceAccount metadata: name: pipeline-account secrets: - name: ack-cr-push-secret --- apiVersion: v1 kind: Secret metadata: name: kube-api-secret annotations: kubernetes.io/service-account.name: pipeline-account type: kubernetes.io/service-account-token --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: pipeline-role rules: - apiGroups: ["serving.knative.dev"] resources: ["services"] verbs: ["get", "create", "update", "patch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: pipeline-role-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: pipeline-role subjects: - kind: ServiceAccount name: pipeline-account
定義 PIpelineRun
ServiceAccount 對應的鑑權信息是經過和 PIpelineRun 綁定的方式執行的。參見 run/picalc-pipeline-run.yaml
文件
apiVersion: tekton.dev/v1alpha1 kind: PipelineRun metadata: generateName: tekton-kn-sample- spec: pipelineRef: name: build-and-deploy-pipeline resources: - name: git-source resourceRef: name: tekton-knative-git params: - name: pathToContext value: "src" - name: pathToYamlFile value: "knative/helloworld-go.yaml" - name: imageUrl value: "registry.cn-hangzhou.aliyuncs.com/knative-sample/tekton-knative-helloworld" - name: imageTag value: "1.0" trigger: type: manual serviceAccount: pipeline-account
執行 HelloWorld
準備 PIpeline 的資源
kubectl apply -f tasks/source-to-image.yaml -f tasks/deploy-using-kubectl.yaml -f resources/picalc-git.yaml -f image-secret.yaml -f pipeline-account.yaml -f pipeline/build-and-deploy-pipeline.yaml
執行 create 把 pipelieRun 提交到 Kubernetes 集羣。之因此這裏使用 create 而不是使用 apply 是由於 PIpelineRun 每次都會建立一個新的,kubectl 的 create 指令會基於 generateName 建立新的 PIpelineRun 資源。
kubectl create -f run/picalc-pipeline-run.yaml
查看一下 pod 信息多是下面這樣:
└─# kubectl get pod NAME READY STATUS RESTARTS AGE tekton-kn-sample-45d84-deploy-to-cluster-wfrzx-pod-f093ef 0/3 Completed 0 8h tekton-kn-sample-45d84-source-to-image-7zpqn-pod-c2d20c 0/2 Completed 0 8h
本文做者:冬島
本文爲雲棲社區原創內容,未經容許不得轉載。