0

我们有一个 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,并遵守以下要求:

  • 最简单的方法
  • 不要使用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 预定义变量用于通用方法
4

1 回答 1

3

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 日志非常酷:

在此处输入图像描述

于 2021-11-16T15:03:32.077 回答