如何使用预定义的 GitLab CI 变量和流式传输到 GitLab Pipeline 日志的 Tekton 日志直接从 GitLab CI 触发 Tekton Pipeline
Posted
技术标签:
【中文标题】如何使用预定义的 GitLab CI 变量和流式传输到 GitLab Pipeline 日志的 Tekton 日志直接从 GitLab CI 触发 Tekton Pipeline【英文标题】:How to trigger Tekton Pipeline from GitLab CI directly with predefined GitLab CI variables & Tekton logs streamed into GitLab Pipeline logs 【发布时间】:2021-12-27 16:04:54 【问题描述】:我们正在运行 AWS EKS(使用 Pulumi 设置),我们在其中安装了 Tekton,如 Cloud Native Buildpacks Tekton docs 中所述。 example project is available。
Our Tekton pipeline 是这样配置的(也是派生的from the Cloud Native Buildpacks Tekton docs):
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
作为参数。
问题是:我们如何从 GitLab CI 触发 Tekton PipelineRun
(在我们的 .gitlab-ci.yml
中)遵守以下要求:
【问题讨论】:
【参考方案1】: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
以下是您需要执行的简短步骤:
1.为您的.gitlab-ci.yml
选择一个基本映像,提供aws
CLI、kubectl
和 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
作为 CI/CD 变量,其中包含 aws cli 凭据(请注意 @ 987654346@ 它们同时创建它们,以防止它们被打印到 GitLab CI 日志中)。根据您的 EKS 集群(或其他 K8s 集群)配置,您需要提供 kubeconfig
来访问您的集群。一种方法是创建一个 GitLab CI/CD 变量,如 EKSKUBECONFIG
,提供必要的文件(例如,在示例项目中,这是由 Pulumi 提供的 pulumi stack output kubeconfig > kubeconfig
)。在这个使用 Pulumi 的设置中,kubeconfig
内没有秘密凭据,因此不需要屏蔽变量。但请注意此处可能的凭据,并在需要时相应地保护它们。
同时定义包含您的 EKS 集群区域的 AWS_DEFAULT_REGION
:
# 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.在before_script
部分使用kubeconfig
和testdrive集群连接
稍后在其他步骤中准备我们需要的东西可以在before_script
部分中完成。因此,让我们在那里创建目录~/.kube
,并根据变量EKSKUBECONFIG
的内容创建文件~/.kube/config
。最后触发kubectl get nodes
以检查集群连接是否正常。我们的before_script
部分现在看起来像这样:
before_script:
- mkdir ~/.kube
- echo "$EKSKUBECONFIG" > ~/.kube/config
- echo "--- Testdrive connection to cluster"
- kubectl get nodes
4.将参数传递给 Tekton PipelineRun
通过kubectl
传递参数并非易事——甚至需要使用像 Helm 这样的模板引擎来完成。但幸运的是,Tekton CLI 为我们提供了一些帮助:tkn pipeline start
accepts parameters。因此我们可以将Cloud Native Buildpacks Tekton PipelineRun Yaml file 转换为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
现在有几点需要考虑。首先,tkn pipeline start
之后的名称 buildpacks-test-pipeline
相当于 yaml 文件 spec: pipelineRef: name: buildpacks-test-pipeline
定义。
它还可以作为对pipeline.yml 文件中定义的Pipeline
对象的引用,该文件以metadata: name: buildpacks-test-pipeline
开头,例如:
api版本:tekton.dev/v1beta1 种类:流水线 元数据: 名称:buildpacks-test-pipeline ...
第二次定义工作区并非易事。幸运的是there's help。我们可以像这样在tkn
CLI 中定义一个工作区:--workspace name=source-workspace,subPath=source,claimName=buildpacks-source-pvc
。
第三次按预期使用参数现在变得容易了。只需相应地使用--param
。我们还使用--showlog
将Tekton 日志与--timeout
一起直接流式传输到命令行(或GitLab CI!)。
最后使用GitLab CI Predefined variables我们的.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 管道都是绿色的问题
这可能是我们需要做的一切。但是:现在每个 GitLab CI 管道都是绿色的,无论 Tekton 管道的状态如何。
因此我们再次删除--showlog
和--timeout
,但添加--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
并且没有使用 tkn
CLI 启动实际的 Tekton 管道,我们需要使用以下命令创建管道运行:
- 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 管道运行的状态。这可以通过using --output=jsonpath='.status.conditions[*].reason'
和kubectl get pipelineruns
一起实现:
kubectl get pipelineruns $PIPELINE_RUN_NAME --output=jsonpath='.status.conditions[*].reason'
然后我们将结果通过管道传送到a grep
which checks, if Failed
is inside 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 失败时变为红色。 The example project has some logs 如果您有兴趣。在 GitLab CI 日志中看到 Tekton 日志非常酷:
【讨论】:
以上是关于如何使用预定义的 GitLab CI 变量和流式传输到 GitLab Pipeline 日志的 Tekton 日志直接从 GitLab CI 触发 Tekton Pipeline的主要内容,如果未能解决你的问题,请参考以下文章