如何使用预定义的 GitLab CI 变量和流入 GitLab Pipeline 日志的 Tekton 日志直接从 GitLab CI 触发 Tekton Pipeline

jon*_*ckt 2 gitlab gitlab-ci kubernetes amazon-eks tekton

我们有一个正在运行的 AWS EKS(使用 Pulumi 设置),我们在其中安装了 Tekton,如云原生 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)
Run Code Online (Sandbox Code Playgroud)

我们已经添加了SOURCE_URLSOURCE_REVISION作为参数。

问题是:我们如何从 GitLab CI(在我们的 内部)触发 TektonPipelineRun.gitlab-ci.yml并满足以下要求:

  • 最简单的方法
  • 不要使用Tekton 触发器(包括commit-status-tracker)引入的额外复杂性,但仍将 GitLab 作为事实来源(例如,查看绿色/红色管道在提交时运行等)
  • 报告成功将 Tekton Pipelines 运行为绿色 GitLab CI Pipelines,并将失败的 Tekton Pipelines 作为红色 GitLab CI Pipelines
  • 将 Tekton Pipeline 日志保存/流式传输到 GitLab CI Pipeline 日志中 - 无论是在 Tekton Pipelines 内出现错误还是成功的情况下
  • 使用GitLab CI 预定义变量作为通用方法

jon*_*ckt 7

太长了;

我创建了一个完全易于理解的示例项目,在此处显示了所有必要的步骤和运行管道: https: //gitlab.com/jonashackt/microservice-api-spring-boot/.gitlab-ci.yml ,其中包含直接触发 Tekton Pipeline 的完整内容:

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
Run Code Online (Sandbox Code Playgroud)

以下是您需要执行的简短步骤:

.gitlab-ci.yml1. 为您提供的awsCLIkubectl和 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_IDAWS_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'
Run Code Online (Sandbox Code Playgroud)

3. 使用kubeconfig并测试集群连接before_script部分

准备我们稍后在其他步骤中需要的东西可以在该部分中完成before_script。因此,让我们在那里创建目录并根据变量的内容~/.kube创建文件。最后触发 a以检查集群连接是否正常工作。我们的部分现在看起来像这样:~/.kube/configEKSKUBECONFIGkubectl get nodesbefore_script

before_script:
  - mkdir ~/.kube
  - echo "$EKSKUBECONFIG" > ~/.kube/config
  - echo "--- Testdrive connection to cluster"
  - kubectl get nodes
Run Code Online (Sandbox Code Playgroud)

4. 将参数传递给Tekton PipelineRun

通过传递参数kubectl并不简单——甚至需要使用像 Helm 这样的模板引擎来完成。但幸运的是 Tekton CLI 为我们提供了一些东西:tkn pipeline start接受参数。因此,我们可以将Cloud Native Buildpacks Tekton PipelineRun Yaml 文件转换为tknCLI 命令,如下所示:

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
Run Code Online (Sandbox Code Playgroud)

现在这里有一些需要考虑的要点。buildpacks-test-pipeline首先是紧随其后的名称tkn pipeline start,相当于 yaml 文件spec: pipelineRef: name: buildpacks-test-pipeline定义。

Pipeline它还将用作对文件pipeline.yml中定义的对象的引用,该文件以以下形式开头metadata: name: buildpacks-test-pipeline

api版本:tekton.dev/v1beta1 种类:管道元数据:名称:buildpacks-test-pipeline ...

其次定义工作空间并非易事。幸运的是有帮助。我们可以在tknCLI 中定义一个工作区,如下所示--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
Run Code Online (Sandbox Code Playgroud)

5.解决每个GitLab CI Pipeline都是绿色的问题

这可能就是我们需要做的一切。但是:现在,无论 Tekton Pipeline 的状态如何,每个 GitLab CI Pipeline 都是绿色的。

因此,我们再次删除--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
Run Code Online (Sandbox Code Playgroud)

现在我们删除了--showlog并且不使用tknCLI 启动实际的 Tekton 管道,我们需要使用以下命令创建管道运行:

- PIPELINE_RUN_NAME=$(kubectl create -f pipelinerun.yml --output=jsonpath='{.metadata.name}')
Run Code Online (Sandbox Code Playgroud)

有了包含确切管道运行 ID 的可用临时变量PIPELINE_RUN_NAME,我们可以再次将 Tekton 管道日志流式传输到 GitLab CI 日志中:

- tkn pipelinerun logs $PIPELINE_RUN_NAME --follow
Run Code Online (Sandbox Code Playgroud)

最后,我们需要检查 Tekton 管道运行的状态并相应地退出 GitLab CI 管道,以防止红色 Tekton 管道导致绿色 GitLab CI 管道。因此,我们首先检查 Tekton 管道运行的状态。这可以与以下一起使用--output=jsonpath='{.status.conditions[*].reason}'来实现kubectl get pipelineruns

kubectl get pipelineruns $PIPELINE_RUN_NAME --output=jsonpath='{.status.conditions[*].reason}'
Run Code Online (Sandbox Code Playgroud)

然后我们将结果通过管道传送到一个grep检查器,检查是否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
Run Code Online (Sandbox Code Playgroud)

现在,当 Tekton Pipeline 成功时,每个 GitLab CI Pipeline 都会变成绿色 - 当 Tekton Pipeline 失败时,每个 GitLab CI Pipeline 都会变成红色。如果您有兴趣,示例项目有一些日志。在 GitLab CI 日志中看到 Tekton 日志非常酷:

在此输入图像描述