首页 > 解决方案 > 如何使用预定义的 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_URLSOURCE_REVISION作为参数。

问题是:我们如何PipelineRun从 GitLab CI(在我们的内部.gitlab-ci.yml)触发 Tekton,并遵守以下要求:

标签: kubernetesgitlabgitlab-ciamazon-ekstekton

解决方案


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.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_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/configEKSKUBECONFIGkubectl get nodesbefore_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 管道的状态如何。

因此,我们再次删除--showlogand --timeout,但将 a--dry-run--output yaml标志一起添加。如果没有--dry-runtkn 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}'

然后我们将结果通过管道传送到一个grepwhich 检查,如果Failedstatus.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 日志非常酷:

在此处输入图像描述


推荐阅读