如何使用预定义的 GitLab CI 变量直接从 GitLab CI 触发 Tekton Pipeline & Tekton 日志流式传输到 GitLab Pipeline 日志中
How to trigger Tekton Pipeline from GitLab CI directly with predefined GitLab CI variables & Tekton logs streamed into GitLab Pipeline logs
我们有一个 AWS EKS 运行ning(使用 Pulumi 设置),我们按照 Cloud Native Buildpacks Tekton docs. The example project is available.
中的描述安装了 Tekton
Our Tekton pipeline is configured like this (which is derived 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(在我们的 .gitlab-ci.yml
中)触发 Tekton PipelineRun
要求:
- 最简单的方法
- 不要使用 Tekton Triggers (incl. commit-status-tracker 引入的额外复杂性)但仍将 GitLab 作为真实来源(例如,参见 green/red 管道 运行s 提交等)
- 报告成功 运行 Tekton 管道为绿色 GitLab CI 管道和失败的 Tekton 管道为红色 GitLab CI 管道
- preserve/stream Tekton Pipeline 登录到 GitLab CI Pipeline 日志 - 无论是在 Tekton Pipelines 内部出现错误还是成功时
- 使用 GitLab CI Predefined Variables 作为通用方法
TLDR;
我创建了一个完全易于理解的示例项目,显示了所有必要的步骤和 运行ning 管道: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 which provides an image, which is based on the official https://hub.docker.com/r/amazon/aws-cli 图片,可以通过 registry.gitlab.com/jonashackt/aws-kubectl-tkn:0.21.0
.
访问
2。 CI/CD aws CLI 和 Kubernetes 集群访问的变量
在你的 GitLab CI 项目中(或者更好:在你的 GitLab CI 项目所在的组中)你需要创建 AWS_ACCESS_KEY_ID
, AWS_SECRET_ACCESS_KEY
作为CI/CD 持有 aws cli 凭据的变量(在创建它们时注意 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.在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. So we can transform the 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.解决every GitLab CI Pipeline is green 问题
这可能就是我们需要做的一切。但是:现在每个 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 管道的状态 运行。这可以通过 与 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 在线工具(即 <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 管道成功时,每个 GitLab CI 管道都变为绿色 - 当 Tekton 管道失败时变为红色。 The example project has some logs 如果您有兴趣。在 GitLab 中看到 Tekton 日志真是太酷了 CI logs:
我们有一个 AWS EKS 运行ning(使用 Pulumi 设置),我们按照 Cloud Native Buildpacks Tekton docs. The example project is available.
中的描述安装了 TektonOur Tekton pipeline is configured like this (which is derived 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(在我们的 .gitlab-ci.yml
中)触发 Tekton PipelineRun
要求:
- 最简单的方法
- 不要使用 Tekton Triggers (incl. commit-status-tracker 引入的额外复杂性)但仍将 GitLab 作为真实来源(例如,参见 green/red 管道 运行s 提交等)
- 报告成功 运行 Tekton 管道为绿色 GitLab CI 管道和失败的 Tekton 管道为红色 GitLab CI 管道
- preserve/stream Tekton Pipeline 登录到 GitLab CI Pipeline 日志 - 无论是在 Tekton Pipelines 内部出现错误还是成功时
- 使用 GitLab CI Predefined Variables 作为通用方法
TLDR;
我创建了一个完全易于理解的示例项目,显示了所有必要的步骤和 运行ning 管道: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 which provides an image, which is based on the official https://hub.docker.com/r/amazon/aws-cli 图片,可以通过 registry.gitlab.com/jonashackt/aws-kubectl-tkn:0.21.0
.
2。 CI/CD aws CLI 和 Kubernetes 集群访问的变量
在你的 GitLab CI 项目中(或者更好:在你的 GitLab CI 项目所在的组中)你需要创建 AWS_ACCESS_KEY_ID
, AWS_SECRET_ACCESS_KEY
作为CI/CD 持有 aws cli 凭据的变量(在创建它们时注意 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.在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. So we can transform the 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 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.解决every GitLab CI Pipeline is green 问题
这可能就是我们需要做的一切。但是:现在每个 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 管道的状态 运行。这可以通过 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 在线工具(即 <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 管道成功时,每个 GitLab CI 管道都变为绿色 - 当 Tekton 管道失败时变为红色。 The example project has some logs 如果您有兴趣。在 GitLab 中看到 Tekton 日志真是太酷了 CI logs: