kubernetes - 如何使用预定义的 GitLab CI 变量和流式传输到 GitLab Pipeline 日志的 Tekton 日志直接从 GitLab CI 触发 Tekton Pipeline
问题描述
我们有一个 AWS EKS 正在运行(使用 Pulumi 设置),我们在其中安装了 Tekton,如Cloud Native Buildpacks Tekton 文档中所述。示例项目可用。
我们的 Tekton 管道配置如下(也源自Cloud Native Buildpacks Tekton 文档):
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: buildpacks-test-pipeline
spec:
params:
- name: IMAGE
type: string
description: image URL to push
- name: SOURCE_URL
type: string
description: A git repo url where the source code resides.
- name: SOURCE_REVISION
description: The branch, tag or SHA to checkout.
default: ""
workspaces:
- name: source-workspace # Directory where application source is located. (REQUIRED)
- name: cache-workspace # Directory where cache is stored (OPTIONAL)
tasks:
- name: fetch-repository # This task fetches a repository from github, using the `git-clone` task you installed
taskRef:
name: git-clone
workspaces:
- name: output
workspace: source-workspace
params:
- name: url
value: "$(params.SOURCE_URL)"
- name: revision
value: "$(params.SOURCE_REVISION)"
- name: subdirectory
value: ""
- name: deleteExisting
value: "true"
- name: buildpacks # This task uses the `buildpacks` task to build the application
taskRef:
name: buildpacks
runAfter:
- fetch-repository
workspaces:
- name: source
workspace: source-workspace
- name: cache
workspace: cache-workspace
params:
- name: APP_IMAGE
value: "$(params.IMAGE)"
- name: BUILDER_IMAGE
value: paketobuildpacks/builder:base # This is the builder we want the task to use (REQUIRED)
我们已经添加了SOURCE_URL
和SOURCE_REVISION
作为参数。
问题是:我们如何PipelineRun
从 GitLab CI(在我们的内部.gitlab-ci.yml
)触发 Tekton,并遵守以下要求:
- 最简单的方法
- 不要使用Tekton Triggers引入的额外复杂性(包括commit-status-tracker),但仍将 GitLab 作为事实来源(例如,查看提交时运行的绿色/红色管道等)
- 报告成功将 Tekton Pipelines 运行为绿色 GitLab CI Pipelines 并将失败的 Tekton Pipelines 运行为红色 GitLab CI Pipelines
- 将 Tekton Pipeline 日志保存/流式传输到 GitLab CI Pipeline 日志中 - 无论是在 Tekton Pipelines 内发生错误还是成功的情况下
- 将GitLab CI 预定义变量用于通用方法
解决方案
TLDR;
我创建了一个完全可理解的示例项目,在此处显示所有必要的步骤和运行管道:https ://gitlab.com/jonashackt/microservice-api-spring-boot/完整.gitlab-ci.yml
直接触发 Tekton 管道:
image: registry.gitlab.com/jonashackt/aws-kubectl-tkn:0.21.0
variables:
AWS_DEFAULT_REGION: 'eu-central-1'
before_script:
- mkdir ~/.kube
- echo "$EKSKUBECONFIG" > ~/.kube/config
- echo "--- Testdrive connection to cluster"
- kubectl get nodes
stages:
- build
build-image:
stage: build
script:
- echo "--- Create parameterized Tekton PipelineRun yaml"
- tkn pipeline start buildpacks-test-pipeline
--serviceaccount buildpacks-service-account-gitlab
--workspace name=source-workspace,subPath=source,claimName=buildpacks-source-pvc
--workspace name=cache-workspace,subPath=cache,claimName=buildpacks-source-pvc
--param IMAGE=$CI_REGISTRY_IMAGE
--param SOURCE_URL=$CI_PROJECT_URL
--param SOURCE_REVISION=$CI_COMMIT_REF_SLUG
--dry-run
--output yaml > pipelinerun.yml
- echo "--- Trigger PipelineRun in Tekton / K8s"
- PIPELINE_RUN_NAME=$(kubectl create -f pipelinerun.yml --output=jsonpath='{.metadata.name}')
- echo "--- Show Tekton PipelineRun logs"
- tkn pipelinerun logs $PIPELINE_RUN_NAME --follow
- echo "--- Check if Tekton PipelineRun Failed & exit GitLab Pipeline accordingly"
- kubectl get pipelineruns $PIPELINE_RUN_NAME --output=jsonpath='{.status.conditions[*].reason}' | grep Failed && exit 1 || exit 0
以下是您需要执行的简短步骤:
.gitlab-ci.yml
1. 为您提供的aws
CLIkubectl
和 Tekton CLI ( tkn
)选择一个基本映像
这完全取决于你。我创建了一个示例项目https://gitlab.com/jonashackt/aws-kubectl-tkn它提供了一个图像,该图像基于官方https://hub.docker.com/r/amazon/aws-cli图像和可通过 访问registry.gitlab.com/jonashackt/aws-kubectl-tkn:0.21.0
。
2. 用于 aws CLI 和 Kubernetes 集群访问的 CI/CD 变量
在您的 GitLab CI 项目内(或者更好:在您的 GitLab CI 项目所在的组内),您需要创建AWS_ACCESS_KEY_ID
,AWS_SECRET_ACCESS_KEY
作为保存 aws cli 凭据的 CI/CD 变量(mask
在创建它们时要小心它们以防止它们蜂鸣打印到 GitLab CI 日志中)。根据您的 EKS 集群(或其他 K8s 集群)配置,您需要提供一个kubeconfig
来访问您的集群。一种方法是创建一个 GitLab CI/CD 变量,例如EKSKUBECONFIG
提供必要的文件(例如,在示例项目中,这是由 Pulumi 提供的pulumi stack output kubeconfig > kubeconfig
)。在使用 Pulumi 的设置中,内部没有秘密凭据,kubeconfig
因此不需要屏蔽变量。但请注意此处可能的凭据,并在需要时相应地保护它们。
还要定义AWS_DEFAULT_REGION
包含您的 EKS 集群的区域:
# As we need kubectl, aws & tkn CLI we use https://gitlab.com/jonashackt/aws-kubectl-tkn
image: registry.gitlab.com/jonashackt/aws-kubectl-tkn:0.21.0
variables:
AWS_DEFAULT_REGION: 'eu-central-1'
3. 使用kubeconfig
和试驾集群连接before_script
部分
稍后在其他步骤中准备我们需要的东西可以在该before_script
部分中完成。所以让我们在那里创建目录并从变量的内容~/.kube
创建文件。最后触发 a检查集群连接是否正常。我们的部分现在看起来像这样:~/.kube/config
EKSKUBECONFIG
kubectl get nodes
before_script
before_script:
- mkdir ~/.kube
- echo "$EKSKUBECONFIG" > ~/.kube/config
- echo "--- Testdrive connection to cluster"
- kubectl get nodes
4. 将参数传递给 Tekton PipelineRun
via 传递参数并kubectl
非易事——甚至需要使用像 Helm 这样的模板引擎来完成。但幸运的是,Tekton CLI 为我们提供了一些东西:tkn pipeline start
接受参数。因此,我们可以将Cloud Native Buildpacks Tekton PipelineRun Yaml 文件转换为tkn
如下 CLI 命令:
tkn pipeline start buildpacks-test-pipeline \
--serviceaccount buildpacks-service-account-gitlab \
--workspace name=source-workspace,subPath=source,claimName=buildpacks-source-pvc \
--workspace name=cache-workspace,subPath=cache,claimName=buildpacks-source-pvc \
--param IMAGE=registry.gitlab.com/jonashackt/microservice-api-spring-boot \
--param SOURCE_URL=https://gitlab.com/jonashackt/microservice-api-spring-boot \
--param SOURCE_REVISION=main \
--timeout 240s \
--showlog
现在这里有几点需要考虑。首先是在作品buildpacks-test-pipeline
之后的名称tkn pipeline start
,相当于 yaml 文件spec: pipelineRef: name: buildpacks-test-pipeline
定义。
它还可以作为Pipeline
对文件pipeline.yml中定义的对象的引用,该文件以如下开头metadata: name: buildpacks-test-pipeline
:
apiVersion:tekton.dev/v1beta1 种类:管道元数据:名称:buildpacks-test-pipeline ...
其次,定义工作空间并非易事。幸运的是有帮助。我们可以tkn
像这样在 CLI中定义一个工作区--workspace name=source-workspace,subPath=source,claimName=buildpacks-source-pvc
:
第三,按预期使用参数现在变得很容易。只需--param
相应地使用。我们还使用--showlog
将 Tekton 日志与--timeout
.
最后使用GitLab CI 预定义变量,我们.gitlab-ci.yml
的构建阶段如下所示:
build-image:
stage: build
script:
- echo "--- Run Tekton Pipeline"
- tkn pipeline start buildpacks-test-pipeline
--serviceaccount buildpacks-service-account-gitlab
--workspace name=source-workspace,subPath=source,claimName=buildpacks-source-pvc
--workspace name=cache-workspace,subPath=cache,claimName=buildpacks-source-pvc
--param IMAGE=$CI_REGISTRY_IMAGE
--param SOURCE_URL=$CI_PROJECT_URL
--param SOURCE_REVISION=$CI_COMMIT_REF_SLUG
--timeout 240s
--showlog
5.解决每个GitLab CI Pipeline都是绿色的问题
这可能是我们需要做的一切。但是:现在每个 GitLab CI 管道都是绿色的,无论 Tekton 管道的状态如何。
因此,我们再次删除--showlog
and --timeout
,但将 a--dry-run
与--output yaml
标志一起添加。如果没有--dry-run
该tkn pipeline start
命令,将PipelineRun
已经创建一个对象定义,我们无法再创建该对象定义kubectl
:
build-image:
stage: build
script:
- echo "--- Create parameterized Tekton PipelineRun yaml"
- tkn pipeline start buildpacks-test-pipeline
--serviceaccount buildpacks-service-account-gitlab
--workspace name=source-workspace,subPath=source,claimName=buildpacks-source-pvc
--workspace name=cache-workspace,subPath=cache,claimName=buildpacks-source-pvc
--param IMAGE=$CI_REGISTRY_IMAGE
--param SOURCE_URL=$CI_PROJECT_URL
--param SOURCE_REVISION=$CI_COMMIT_REF_SLUG
--dry-run
--output yaml > pipelinerun.yml
现在我们--showlog
使用 CLI 删除并且不启动实际的 Tekton 管道tkn
,我们需要使用以下命令创建管道运行:
- PIPELINE_RUN_NAME=$(kubectl create -f pipelinerun.yml --output=jsonpath='{.metadata.name}')
有了包含确切管道运行 ID 的临时变量PIPELINE_RUN_NAME
,我们可以再次将 Tekton 管道日志流式传输到我们的 GitLab CI 日志中:
- tkn pipelinerun logs $PIPELINE_RUN_NAME --follow
最后,我们需要检查 Tekton 管道运行的状态并相应地退出我们的 GitLab CI 管道,以防止红色的 Tekton 管道导致绿色的 GitLab CI 管道。因此,让我们首先检查 Tekton 管道运行的状态。这可以与 a 一起使用来--output=jsonpath='{.status.conditions[*].reason}'
kubectl get pipelineruns
实现:
kubectl get pipelineruns $PIPELINE_RUN_NAME --output=jsonpath='{.status.conditions[*].reason}'
然后我们将结果通过管道传送到一个grep
which 检查,如果Failed
在该status.condiditons.reason
字段内。
最后,我们使用 bash onliner(即<expression to check true or false> && command when true || command when false
)发出合适的exit
命令(参见https://askubuntu.com/a/892605):
- kubectl get pipelineruns $PIPELINE_RUN_NAME --output=jsonpath='{.status.conditions[*].reason}' | grep Failed && exit 1 || exit 0
现在,当 Tekton Pipeline 成功时,每个 GitLab CI Pipeline 都变为绿色 - 当 Tekton Pipeline 失败时变为红色。如果您有兴趣,示例项目有一些日志。在 GitLab CI 日志中看到 Tekton 日志非常酷:
推荐阅读
- node.js - 如何让 multer 正确解析使用表单数据发送的客户端请求?
- rust - 如何以函数的方式在向量中查找值并返回其索引?
- reactjs - React TypeScript:参数不可分配给“从不”类型的参数
- python-3.x - 无法从 fasttext 中的文本文件进行训练。获取 ValueError:空词汇表
- axapta - ax中FormControl和FormBuildControl有什么区别
- docker - docker container port 命令什么也没给出
- python - 使用 Pywin32 拍摄的屏幕截图有时会出现黑色图像,我认为处理不正确
- reactjs - 如何在Firebase实时数据库中生成子节点反应原生
- python - 如何拆分一组int数据以确定最后两位的值?
- ios - willChangeValue 等效于已删除的实体?