Tekton 是一个功能强大且灵活的 Kubernetes 原生开源框架,用于创建持续集成和交付(CI/CD)系统。通过抽象底层实现细节,用户可以跨多云平台和本地系统进行构建、测试和部署。
Tekton 提供的开源组件可以跨供应商,Tekton 提供的管道、版本、工作流程和其他 CI/CD 组件的行业规范一致,可以和你现有的 CI/CD 工具(例如:Jenkins、Jenkins X、Skaffold 和 Knative 等)配合使用。
Tekton 和其它几种 CI/CD 工具的比较
使用 Tekton 的内置最佳实践可以快速创建云原生 CI / CD 管道,目标是让开发人员创建和部署不可变镜像,管理基础架构的版本控制或执行更简单的回滚。 还可以利用 Tekton 的滚动部署,蓝 / 绿部署,金丝雀部署或 GitOps 工作流等高级部署模式。
使用 Tekton 可跨多个环境(例如:VM、无服务器、Kubernetes 或 Firebase)进行构建,测试和部署。你还可以使用 Tekton 管道跨多云平台或混合环境进行部署。
Tekton 提供了最大的灵活性,让你可以使用自己喜欢的 CI/CD 工具构建强大的管道。
项目地址:https://github.com/tektoncd/pipeline
下面来看一个基于阿里云 Kubernetes 服务部署 Tekton Pipeline 的实例,部署完成后我们使用它来完成源码拉取、应用打包、镜像推送和应用部署。
Tekton Pipeline 中有 5 类对象,核心理念是通过定义 YAML 定义构建过程,构建任务的状态存放在 status 字段中。
其中 5 类对象分别是:PipelineResouce、Task、TaskRun、Pipeline、PipelineRun。
Task 是单个任务的构建过程,需要通过定义 TaskRun 任务去运行 Task。
Pipeline 包含多个 Task,并在此基础上定义 input 和 output,input 和 output 以 PipelineResource 作为交付。
PipelineResource 是可用于 input 和 output 的对象集合。
同样地,需要定义 PipelineRun 才会运行 Pipeline。
在阿里云 Kubernetes 集群中部署 Tekton Pipeline
1 $ kubectl apply --filename https://storage.googleapis.com/tekton-releases/latest/release.yaml
查看Tekton Pipelines组件是否运行正常:
1 2 3 4 $ kubectl -n tekton-pipelines get po NAME READY STATUS RESTARTS AGE tekton-pipelines-controller-6bcd7ff5d6-vzmrh 1/1 Running 0 25h tekton-pipelines-webhook-6856cf9c47-l6nj6 1/1 Running 0 25h
创建 Git Resource 和 Registry Resource
编辑 git-pipeline-resource.yaml 文件
1 2 3 4 5 6 7 8 9 10 11 12 # git repo 的分支名称为 tekton apiVersion: tekton.dev/v1alpha1 kind: PipelineResource metadata: name: git-pipeline-resource spec: type: git params: - name: revision value: tekton - name: url value: https://code.aliyun.com/haoshuwei/jenkins-demo.git
编辑 registry-pipeline-resource.yaml 文件
1 2 3 4 5 6 7 8 9 10 # 容器镜像仓库地址为 registry.cn-hangzhou.aliyuncs.com/haoshuwei/tekton-demo, 标签为 latest apiVersion: tekton.dev/v1alpha1 kind: PipelineResource metadata: name: registry-pipeline-resource spec: type: image params: - name: url value: registry.cn-hangzhou.aliyuncs.com/haoshuwei/tekton-demo
创建 pipeline resource
1 2 $ kubectl -n tekton-pipelines create -f git-pipeline-resource.yaml $ kubectl -n tekton-pipelines create -f registry-pipeline-resource.yaml
查看已创建的 pipeline resource 资源
1 2 3 4 $ kubectl -n tekton-pipelines get PipelineResource NAME AGE git-pipeline-resource 2h registry-pipeline-resource 2h
创建 Git Repo / Docker Registry Authentication
拉取私有 Git 源码项目需要配置使用 Git Repo Authentication,拉取和推送 Docker 镜像需要配置 Docker Registry Authentication。
在 Tekton Pipeline 中,Git Repo / Docker Registry Authentication 会被定义成ServiceAccount来使用。
编辑 secret tekton-basic-user-pass-git.yaml
1 2 3 4 5 6 7 8 9 10 apiVersion: v1 kind: Secret metadata: name: tekton-basic-user-pass-git annotations: tekton.dev/git-0: https://code.aliyun.com type: kubernetes.io/basic-auth stringData: username: <cleartext non-encoded> password: <cleartext non-encoded>
编辑 secret tekton-basic-user-pass-registry.yaml
1 2 3 4 5 6 7 8 9 10 apiVersion: v1 kind: Secret metadata: name: tekton-basic-user-pass-registry 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>
编辑 serviceaccount tekton-git-and-registry.yaml
1 2 3 4 5 6 7 apiVersion: v1 kind: ServiceAccount metadata: name: tekton-git-and-registry secrets: - name: tekton-basic-user-pass-git - name: tekton-basic-user-pass-registry
创建 serviceaccount
1 2 3 $ kubectl -n tekton-pipelines create -f tekton-basic-user-pass-git.yaml $ kubectl -n tekton-pipelines create -f tekton-basic-user-pass-registry.yaml $ kubectl -n tekton-pipelines create -f tekton-git-and-registry.yaml
查看 secret 以及 sa
1 2 3 4 5 6 7 8 9 10 11 12 13 14 $ kubectl -n tekton-pipelines get secret NAME TYPE DATA AGE default-token-pwncj kubernetes.io/service-account-token 3 25h tekton-basic-user-pass-git kubernetes.io/basic-auth 2 151m tekton-basic-user-pass-registry kubernetes.io/basic-auth 2 151m tekton-git-and-registry-token-tr95m kubernetes.io/service-account-token 3 151m tekton-pipelines-controller-token-lc2fv kubernetes.io/service-account-token 3 25h webhook-certs Opaque 3 25h $ kubectl -n tekton-pipelines get sa NAME SECRETS AGE default 1 25h tekton-git-and-registry 3 152m tekton-pipelines-controller 1 25h
配置 serviceaccount
配置一个 tekton-git-and-registry 帐号以获取命名空间 tekton-pipelines 的管理权限,用于部署应用。
创建 ClusterRoleBinding tekton-cluster-admin
1 2 3 4 5 6 7 8 9 10 11 12 apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: tekton-cluster-admin subjects: - kind: ServiceAccount name: tekton-git-and-registry namespace: tekton-pipelines roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io
创建一个 Task
创建 task build-app.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: build-app spec: inputs: resources: - name: java-demo type: git params: - name: pathToDockerFile description: The path to the dockerfile to build default: /workspace/java-demo/Dockerfile - name: pathToContext description: The build context used by Kaniko default: /workspace/java-dem - name: pathToYaml description: The path to teh manifest to apply outputs: resources: - name: builtImage type: image steps: - name: build-mvn-package image: registry.cn-beijing.aliyuncs.com/acs-sample/jenkins-slave-maven:3.3.9-jdk-8-alpine workingDir: /workspace/java-demo command: - mvn args: - package - -B - -DskipTests - name: build-docker-image image: registry.cn-beijing.aliyuncs.com/acs-sample/jenkins-slave-kaniko:0.6.0 command: - kaniko args: - --dockerfile=${inputs.params.pathToDockerFile} - --destination=${outputs.resources.builtImage.url} - --context=${inputs.params.pathToContext} - name: deploy-app image: registry.cn-beijing.aliyuncs.com/acs-sample/jenkins-slave-kubectl:1.11.5 command: - kubectl args: - apply - -f - ${inputs.params.pathToYaml}
创建 TaskRun 运行任务
创建 taskrun build-app-task-run.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 apiVersion: tekton.dev/v1alpha1 kind: TaskRun metadata: name: build-app-task-run spec: serviceAccount: tekton-git-and-registry taskRef: name: build-app trigger: type: manual inputs: resources: - name: java-demo resourceRef: name: git-pipeline-resource params: - name: pathToDockerFile value: Dockerfile - name: pathToContext value: /workspace/java-demo - name: pathToYaml value: /workspace/java-demo/deployment.yaml outputs: resources: - name: builtImage resourceRef: name: registry-pipeline-resource
查看构建状态以及日志
查看 taskrun 状态
1 2 3 $ kubectl -n tekton-pipelines get taskrun NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME build-app-task-run Unknown Pending 4s
查看构建日志
1 2 3 4 5 6 7 8 $ kubectl -n tekton-pipelines get po NAME READY STATUS RESTARTS AGE build-app-task-run-pod-b8f890 3/5 Running 0 75s tekton-pipelines-controller-6bcd7ff5d6-vzmrh 1/1 Running 0 25h tekton-pipelines-webhook-6856cf9c47-l6nj6 1/1 Running 0 25h $ kubectl -n tekton-pipelines logs -f build-app-task-run-pod-b8f890 Error from server (BadRequest): a container name must be specified for pod build-app-task-run-pod-b8f890, choose one of: [build-step-git-source-git-pipeline-resource-77l5v build-step-build-mvn-package build-step-build-docker-image build-step-deploy-app nop] or one of the init containers: [build-step-credential-initializer-8dsnm build-step-place-tools]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 $ kubectl -n tekton-pipelines logs -f build-app-task-run-pod-b8f890 -c build-step-build-mvn-package [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building jenkins-demo-web 1.0.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-resources-plugin/2.6/maven-resources-plugin-2.6.pom [INFO] Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-resources-plugin/2.6/maven-resources-plugin-2.6.pom (8 KB at 7.3 KB/sec) [INFO] Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/23/maven-plugins-23.pom [INFO] Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-plugins/23/maven-plugins-23.pom (9 KB at 26.7 KB/sec) [INFO] Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/22/maven-parent-22.pom [INFO] Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/maven-parent/22/maven-parent-22.pom (30 KB at 61.3 KB/sec) [INFO] Downloading: https://repo.maven.apache.org/maven2/org/apache/apache/11/apache-11.pom [INFO] Downloaded: https://repo.maven.apache.org/maven2/org/apache/apache/11/apache-11.pom (15 KB at 45.3 KB/sec) ....
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $ kubectl -n tekton-pipelines logs -f build-app-task-run-pod-b8f890 -c build-step-build-docker-image INFO[0000] Downloading base image tomcat 2019/05/06 11:58:46 No matching credentials were found, falling back on anonymous INFO[0003] Taking snapshot of full filesystem... INFO[0003] Skipping paths under /builder/home, as it is a whitelisted directory INFO[0003] Skipping paths under /builder/tools, as it is a whitelisted directory INFO[0003] Skipping paths under /dev, as it is a whitelisted directory INFO[0003] Skipping paths under /kaniko, as it is a whitelisted directory INFO[0003] Skipping paths under /proc, as it is a whitelisted directory INFO[0003] Skipping paths under /run/secrets/kubernetes.io/serviceaccount, as it is a whitelisted directory INFO[0003] Skipping paths under /sys, as it is a whitelisted directory INFO[0003] Skipping paths under /var/run, as it is a whitelisted directory INFO[0003] Skipping paths under /workspace, as it is a whitelisted directory INFO[0003] Using files from context: [/workspace/java-demo/target/demo.war] INFO[0003] ADD target/demo.war /usr/local/tomcat/webapps/demo.war INFO[0003] Taking snapshot of files... ...
1 2 3 $ kubectl -n tekton-pipelines logs -f build-app-task-run-pod-637855 -c build-step-deploy-app deployment.extensions/jenkins-java-demo created service/jenkins-java-demo created
taskrun 的完成状态为 True 则构建部署过程完成
1 2 3 $ kubectl -n tekton-pipelines get taskrun NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME build-app-task-run True 4m 2m
小结
Tekton Pipeline 中的任务模板可以拿来复用,而不需要重复定义,另外通过 CRD 重新定义 CI/CD 是一大亮点。
参考文档
https://www.google.com
https://www.infoq.cn/article/tZ6E1_lhsWeh26C9xUJf
https://yq.aliyun.com/articles/701368?utm_content=g_1000055966
https://juejin.im/post/5d5a612a6fb9a06b2d77d39a