云原生 | kubernetes - tekton构建CI/CD流水线

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了云原生 | kubernetes - tekton构建CI/CD流水线相关的知识,希望对你有一定的参考价值。

​ 上一节我们是通过创建Pipelinerun来触发流水线来进行构建,实际生产中完全自动化的实现需要借助tekton中的triggers。本文是上篇的拓展请先了解这篇文章

Tekton Triggers 是一个 Tekton 组件,它允许您从各种来源的事件中检测和提取信息,TaskRunsPipelineRuns 根据该信息确定性地实例化和执行。Tekton 触发器还可以将从事件中提取的信息直接传递给TaskRunsPipelineRuns

#Triggers

Tekton Triggers包含下面几个CRD来对tekton进行拓展。

  • EventListener- 在 Kubernetes 集群上的指定端口监听事件。指定一个或多个Triggers
  • Trigger- 指定当EventListener检测到事件时会发生什么。ATrigger指定 a TriggerTemplate、 aTriggerBinding和可选的 an Interceptor
  • TriggerTemplate- 指定资源的蓝图,例如TaskRunPipelineRun,当您EventListener检测到事件时要实例化和/或执行该蓝图。它公开了您可以在资源模板中的任何位置使用的参数。
  • TriggerBinding- 指定要从中提取数据的事件有效负载中的字段以及对应的字段TriggerTemplate以填充提取的值。然后,您可以使用 中的填充字段TriggerTemplate来填充关联TaskRun或中的字段PipelineRun
  • ClusterTriggerBinding- 的集群范围版本,TriggerBinding对于在集群中重用特别有用。
  • Interceptor- 用于特定平台的“包罗万象”事件处理器,在TriggerBinding您执行有效负载过滤、验证(使用机密)、转换、定义和测试触发条件以及其他有用处理之前运行。一旦事件数据通过拦截器,它就会Trigger在您将有效负载数据传递给TriggerBinding.

git clone -->> make build -->> Kaniko

在这之后,我使用的tasks跟之前相比做了修改,为了方便大家,把它贴在下面。

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: git-clone
  labels:
    app.kubernetes.io/version: "0.6"
  annotations:
    tekton.dev/pipelines.minVersion: "0.29.0"
    tekton.dev/categories: Git
    tekton.dev/tags: git
    tekton.dev/displayName: "git clone"
    tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le,linux/arm64"
spec:
  description: >-
    These Tasks are Git tasks to work with repositories used by other tasks
    in your Pipeline.

    The git-clone Task will clone a repo from the provided url into the
    output Workspace. By default the repo will be cloned into the root of
    your Workspace. You can clone into a subdirectory by setting this Tasks
    subdirectory param. This Task also supports sparse checkouts. To perform
    a sparse checkout, pass a list of comma separated directory patterns to
    this Tasks sparseCheckoutDirectories param.
  workspaces:
    - name: output
      description: The git repo will be cloned onto the volume backing this Workspace.
    - name: ssh-directory
      optional: true
      description: |
        A .ssh directory with private key, known_hosts, config, etc. Copied to
        the users home before git commands are executed. Used to authenticate
        with the git remote when performing the clone. Binding a Secret to this
        Workspace is strongly recommended over other volume types.
    - name: basic-auth
      optional: true
      description: |
        A Workspace containing a .gitconfig and .git-credentials file. These
        will be copied to the users home before any git commands are run. Any
        other files in this Workspace are ignored. It is strongly recommended
        to use ssh-directory over basic-auth whenever possible and to bind a
        Secret to this Workspace over other volume types.
    - name: ssl-ca-directory
      optional: true
      description: |
        A workspace containing CA certificates, this will be used by Git to
        verify the peer with when fetching or pushing over HTTPS.
  params:
    - name: url
      description: Repository URL to clone from.
      type: string
    - name: revision
      description: Revision to checkout. (branch, tag, sha, ref, etc...)
      type: string
      default: ""
    - name: branch
      description: Branch to use
      default: "master"
    - name: refspec
      description: Refspec to fetch before checking out revision.
      default: ""
    - name: submodules
      description: Initialize and fetch git submodules.
      type: string
      default: "true"
    - name: depth
      description: Perform a shallow clone, fetching only the most recent N commits.
      type: string
      default: "1"
    - name: sslVerify
      description: Set the `http.sslVerify` global git config. Setting this to `false` is not advised unless you are sure that you trust your git remote.
      type: string
      default: "true"
    - name: subdirectory
      description: Subdirectory inside the `output` Workspace to clone the repo into.
      type: string
      default: ""
    - name: sparseCheckoutDirectories
      description: Define the directory patterns to match or exclude when performing a sparse checkout.
      type: string
      default: ""
    - name: deleteExisting
      description: Clean out the contents of the destination directory if it already exists before cloning.
      type: string
      default: "true"
    - name: httpProxy
      description: HTTP proxy server for non-SSL requests.
      type: string
      default: ""
    - name: httpsProxy
      description: HTTPS proxy server for SSL requests.
      type: string
      default: ""
    - name: noProxy
      description: Opt out of proxying HTTP/HTTPS requests.
      type: string
      default: ""
    - name: verbose
      description: Log the commands that are executed during `git-clone`s operation.
      type: string
      default: "true"
    - name: gitInitImage
      description: The image providing the git-init binary that this Task runs.
      type: string
      default: "hub.17usoft.com/tekton/tekton-pipeline-git-init:v0.38.2" 
    - name: userHome
      description: |
        Absolute path to the users home directory. Set this explicitly if you are running the image as a non-root user or have overridden
        the gitInitImage param with an image containing custom user configuration.
      type: string
      default: "/tekton/home"
  results:
    - name: commit
      description: The precise commit SHA that was fetched by this Task.
    - name: url
      description: The precise URL that was fetched by this Task.
    - description: The repo name represented by service-name format
      name: short-branch-name
      type: string
  steps:
    - name: clone
      image: "$(params.gitInitImage)"
      env:
      - name: HOME
        value: "$(params.userHome)"
      - name: PARAM_BRANCH
        value: $(params.branch)
      - name: PARAM_URL
        value: $(params.url)
      - name: PARAM_REVISION
        value: $(params.revision)
      - name: PARAM_REFSPEC
        value: $(params.refspec)
      - name: PARAM_SUBMODULES
        value: $(params.submodules)
      - name: PARAM_DEPTH
        value: $(params.depth)
      - name: PARAM_SSL_VERIFY
        value: $(params.sslVerify)
      - name: PARAM_SUBDIRECTORY
        value: $(params.subdirectory)
      - name: PARAM_DELETE_EXISTING
        value: $(params.deleteExisting)
      - name: PARAM_HTTP_PROXY
        value: $(params.httpProxy)
      - name: PARAM_HTTPS_PROXY
        value: $(params.httpsProxy)
      - name: PARAM_NO_PROXY
        value: $(params.noProxy)
      - name: PARAM_VERBOSE
        value: $(params.verbose)
      - name: PARAM_SPARSE_CHECKOUT_DIRECTORIES
        value: $(params.sparseCheckoutDirectories)
      - name: PARAM_USER_HOME
        value: $(params.userHome)
      - name: WORKSPACE_OUTPUT_PATH
        value: $(workspaces.output.path)
      - name: WORKSPACE_SSH_DIRECTORY_BOUND
        value: $(workspaces.ssh-directory.bound)
      - name: WORKSPACE_SSH_DIRECTORY_PATH
        value: $(workspaces.ssh-directory.path)
      - name: WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND
        value: $(workspaces.basic-auth.bound)
      - name: WORKSPACE_BASIC_AUTH_DIRECTORY_PATH
        value: $(workspaces.basic-auth.path)
      - name: WORKSPACE_SSL_CA_DIRECTORY_BOUND
        value: $(workspaces.ssl-ca-directory.bound)
      - name: WORKSPACE_SSL_CA_DIRECTORY_PATH
        value: $(workspaces.ssl-ca-directory.path)
      script: |
        #!/usr/bin/env sh
        set -eu

        if [ "$PARAM_VERBOSE" = "true" ] ; then
          set -x
        fi


        if [ "$WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND" = "true" ] ; then
          cp "$WORKSPACE_BASIC_AUTH_DIRECTORY_PATH/.git-credentials" "$PARAM_USER_HOME/.git-credentials"
          cp "$WORKSPACE_BASIC_AUTH_DIRECTORY_PATH/.gitconfig" "$PARAM_USER_HOME/.gitconfig"
          chmod 400 "$PARAM_USER_HOME/.git-credentials"
          chmod 400 "$PARAM_USER_HOME/.gitconfig"
        fi

        if [ "$WORKSPACE_SSH_DIRECTORY_BOUND" = "true" ] ; then
          cp -R "$WORKSPACE_SSH_DIRECTORY_PATH" "$PARAM_USER_HOME"/.ssh
          chmod 700 "$PARAM_USER_HOME"/.ssh
          chmod -R 400 "$PARAM_USER_HOME"/.ssh/*
        fi

        if [ "$WORKSPACE_SSL_CA_DIRECTORY_BOUND" = "true" ] ; then
           export GIT_SSL_CAPATH="$WORKSPACE_SSL_CA_DIRECTORY_PATH"
        fi
        CHECKOUT_DIR="$WORKSPACE_OUTPUT_PATH/$PARAM_SUBDIRECTORY"

        cleandir() 
          # Delete any existing contents of the repo directory if it exists.
          #
          # We dont just "rm -rf $CHECKOUT_DIR" because $CHECKOUT_DIR might be "/"
          # or the root of a mounted volume.
          if [ -d "$CHECKOUT_DIR" ] ; then
            # Delete non-hidden files and directories
            rm -rf "$CHECKOUT_DIR:?"/*
            # Delete files and directories starting with . but excluding ..
            rm -rf "$CHECKOUT_DIR"/.[!.]*
            # Delete files and directories starting with .. plus any other character
            rm -rf "$CHECKOUT_DIR"/..?*
          fi
        

        if [ "$PARAM_DELETE_EXISTING" = "true" ] ; then
          cleandir
        fi

        test -z "$PARAM_HTTP_PROXY" || export HTTP_PROXY="$PARAM_HTTP_PROXY"
        test -z "$PARAM_HTTPS_PROXY" || export HTTPS_PROXY="$PARAM_HTTPS_PROXY"
        test -z "$PARAM_NO_PROXY" || export NO_PROXY="$PARAM_NO_PROXY"

        /ko-app/git-init \\
          -url="$PARAM_URL" \\
          -revision="$PARAM_REVISION" \\
          -refspec="$PARAM_REFSPEC" \\
          -path="$CHECKOUT_DIR" \\
          -sslVerify="$PARAM_SSL_VERIFY" \\
          -submodules="$PARAM_SUBMODULES" \\
          -depth="$PARAM_DEPTH" \\
          -sparseCheckoutDirectories="$PARAM_SPARSE_CHECKOUT_DIRECTORIES"
        cd "$CHECKOUT_DIR"
        RESULT_SHA="$(git rev-parse HEAD)"
        EXIT_CODE="$?"
        if [ "$EXIT_CODE" != 0 ] ; then
          exit "$EXIT_CODE"
        fi
        printf "%s" "$RESULT_SHA" > "$(results.commit.path)"
        printf "%s" "$PARAM_URL" > "$(results.url.path)"
    - env:
        - name: PARAM_URL
          value: $(params.url)
        - name: PARAM_REVISION
          value: $(params.revision)
        - name: PARAM_BRANCH
          value: $(params.branch)
        - name: WORKSPACE_OUTPUT_PATH
          value: $(workspaces.output.path)
        - name: PARAM_SUBDIRECTORY
          value: $(params.subdirectory)
      image: $(params.gitInitImage)
      name: prepare-outputs
      resources: 
      script: |
        set -eu
        git config --global --add safe.directory "*" 
        CHECKOUT_DIR="$WORKSPACE_OUTPUT_PATH/$PARAM_SUBDIRECTORY"
        cd "$CHECKOUT_DIR"
        
        RESULT_SHORT_BRANCH_NAME="$(basename $PARAM_BRANCH)"
        RESULT_SHA="$(git rev-parse --short HEAD)"
 
        echo "###Results:"
        echo "branch: " $RESULT_SHORT_BRANCH_NAME
        echo "commit: " $RESULT_SHA

        echo -n $RESULT_SHORT_BRANCH_NAME | tee > "$(results.short-branch-name.path)"
        echo -n $RESULT_SHA | tee > "$(results.commit.path)"
        echo -n $PARAM_URL | tee > "$(results.url.path)"
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: golang-build
  labels:
    app.kubernetes.io/version: "0.3"
  annotations:
    tekton.dev/pipelines.minVersion: "0.12.1"
    tekton.dev/categories: Build Tools
    tekton.dev/tags: build-tool
    tekton.dev/displayName: "golang build"
    tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le"
spec:
  description: >-
    This Task is Golang task to build Go projects.

  params:
#  - name: package
#    description: base package to build in
  - name: packages
    description: "packages to build (default: ./cmd/...)"
    default: "./cmd/..."
  - name: subdirectory
    description: subdirectory inside the "source"
    default: "./"
  - name: version
    description: golang version to use for builds
    default: "latest"
  - name: flags
    description: flags to use for the test command
    default: -v
  - name: GOOS
    description: "running programs operating system target"
    default: linux
  - name: GOARCH
    description: "running programs architecture target"
    default: amd64
  - name: GO111MODULE
    description: "value of module support"
    default: auto
  - name: GOCACHE
    description: "Go caching directory path"
    default: ""
  - name: GOMODCACHE
    description: "Go mod caching directory path"
    default: ""
  - name: CGO_ENABLED
    description: "Toggle cgo tool during Go build. Use value 0 to disable cgo (for static builds)."
    default: ""
  - name: GOSUMDB
    description: "Go checksum database url. Use value off to disable checksum validation."
    default: ""
  workspaces:
  - name: source
  steps:
  - name: build
    image: hub.17usoft.com/gstrain/golang:v1.18.3
    workingDir: $(workspaces.source.path)
    script: |
      if [ ! -e $GOPATH/src/$(params.subdirectory)/go.mod ];then
        SRC_PATH="$GOPATH/src/$(params.subdirectory)"
        mkdir -p $SRC_PATH
        cp -R "$(workspaces.source.path)"/$(params.subdirectory)/* $SRC_PATH
        cd $SRC_PATH
      fi
      go build -tags netgo  $(params.flags) $(params.packages)
      pwd && ls -l
      
    env:
    - name: GOOS
      value: "$(params.GOOS)"
    - name: GOARCH
      value: "$(params.GOARCH)"
    - name: GO111MODULE
      value: "$(params.GO111MODULE)"
    - name: GOCACHE
      value: "$(params.GOCACHE)"
    - name: GOMODCACHE
      value: "$(params.GOMODCACHE)"
    - name: CGO_ENABLED
      value: "$(params.CGO_ENABLED)"
    - name: GOSUMDB
      value: "$(params.GOSUMDB)"
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: kaniko
  labels:
    app.kubernetes.io/version: "0.6"
  annotations:
    tekton.dev/pipelines.minVersion: "0.17.0"
    tekton.dev/categories: Image Build
    tekton.dev/tags: image-build
    tekton.dev/displayName: "Build and upload container image using Kaniko"
    tekton.dev/platforms: "linux/amd64"
spec:
  description: >-
    This Task builds a simple Dockerfile with kaniko and pushes to a registry.
    This Task stores the image name and digest as results, allowing Tekton Chains to pick up
    that an image was built & sign it.
  params:
    - name: IMAGE
      description: Name (reference) of the image to build.
    - name: DOCKERFILE
      description: Path to the Dockerfile to build.
      default: ./Dockerfile
    - name: CONTEXT
      description: The build context used by Kaniko.
      default: ./
    - name: EXTRA_ARGS
      type: array
      default: []
    - name: BUILDER_IMAGE
      description: The image on which builds will run (default is v1.5.1)
      default: hub.17usoft.com/tekton/kaniko-executor:v1.5.1
  workspaces:
    - name: source
      description: Holds the context and Dockerfile
    - name: dockerconfig
      description: Includes a docker `config.json`
      optional: true
      mountPath: /kaniko/.docker
  results:
    - name: IMAGE_DIGEST
      description: Digest of the image just built.
    - name: IMAGE_URL
      description: URL of the image just built.
  steps:
    - image: docker.io/library/bash:5.1.4@sha256:b208215a4655538be652b2769d82e576bc4d0a2bb132144c060efc5be8c3f5d6
      name: check-dockerconfig
      resources: 
      script: |
        ls -al /kaniko/.docker
        cat /kaniko/.docker/config.json
    - name: build-and-push
      workingDir: $(workspaces.source.path)
      image: $(params.BUILDER_IMAGE)
      args:
        - $(params.EXTRA_ARGS)
        - --dockerfile=$(params.DOCKERFILE)
        - --context=$(workspaces.source.path)/$(params.CONTEXT) # The user does not need to care the workspace and the source.
        - --destination=$(params.IMAGE)
        - --digest-file=$(results.IMAGE_DIGEST.path)
      securityContext:
        runAsUser: 0
    - name: write-url
      image: docker.io/library/bash:5.1.4@sha256:b208215a4655538be652b2769d82e576bc4d0a2bb132144c060efc5be8c3f5d6
      script: |
        set -e
        image="$(params.IMAGE)"
        echo -n "$image" | tee "$(results.IMAGE_URL.path)"

Modify listing

​ 我们上节结尾处跟大家讲了,我们会添加一个新的任务。当我们完成镜像推送后自动修改配置仓库中yaml信息。

---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: modify-listing
  labels:
    app.kubernetes.io/version: "0.4"
  annotations:
    tekton.dev/pipelines.minVersion: "0.21.0"
    tekton.dev/categories: Git
    tekton.dev/tags: git
    tekton.dev/displayName: "git cli"
    tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le"
spec:
  description: >-
    This task can be used to perform git operations.

    Git command that needs to be run can be passed as a script to
    the task. This task needs authentication to git in order to push
    after the git operation.

  workspaces:
    - name: source
      description: A workspace that contains the fetched git repository.

    - name: input
      optional: true
      description: |
        An optional workspace that contains the files that need to be added to git. You can
        access the workspace from your script using `$(workspaces.input.path)`, for instance:

          cp $(workspaces.input.path)/file_that_i_want .
          git add file_that_i_want
          # etc

    - name: ssh-directory
      optional: true
      description: |
        A .ssh directory with private key, known_hosts, config, etc. Copied to
        the users home before git commands are executed. Used to authenticate
        with the git remote when performing the clone. Binding a Secret to this
        Workspace is strongly recommended over other volume types.

    - name: basic-auth
      optional: true
      description: |
        A Workspace containing a .gitconfig and .git-credentials file. These
        will be copied to the users home before any git commands are run. Any
        other files in this Workspace are ignored. It is strongly recommended
        to use ssh-directory over basic-auth whenever possible and to bind a
        Secret to this Workspace over other volume types.
  params:
    - name: BASE_IMAGE
      description: |
        The base image for the task.
      type: string
      default:  "cnych/helm-kubectl-curl-git-jq-yq "

    - name: GIT_USER_NAME
      type: string
      description: |
        Git user name for performing git operation.
      default: "Administrator"

    - name: GIT_USER_EMAIL
      type: string
      description: |
        Git user email for performing git operation.
      default: "1376252133@qq.com"
    
    - name: subdirectory
      type: string
      default: ""

    - name: IMAGE_URL
      type: string
      description: |
        The latest build image
      default: "$(tasks.kaniko.results.IMAGE_URL)"

    - name: GIT_SCRIPT
      description: The git script to run.
      type: string
      default: |
        cd web-service 
        git clone --branch master --depth 1  http://tekton-pipelines:z7FavbPhfEGrghsdCU5h@10.177.9.244:31002/tekton/project.git repo
        cd "repo/web-service"
        ls -l
        echo old value:
        cat 02-deployment.yaml | yq r - spec.template.spec.containers[0].image
        echo replacing with new value:
        yq w -i 02-deployment.yaml spec.template.spec.containers[0].image "$IMAGE_URL"
        echo verifying new value :
        yq r 02-deployment.yaml spec.template.spec.containers[0].image
        if ! git diff-index --quiet HEAD --; then
          git status
          git add .
          git commit -m "auto updated yaml by tekton pipeline"
          git push
        else
            echo "no changes, git repository is up to date"
        fi

    - name: USER_HOME
      description: |
        Absolute path to the users home directory. Set this explicitly if you are running the image as a non-root user or have overridden
        the gitInitImage param with an image containing custom user configuration.
      type: string
      default: "/root"

    - name: VERBOSE
      description: Log the commands that are executed during `git-clone`s operation.
      type: string
      default: "true"

  results:
    - name: commit
      description: The precise commit SHA after the git operation.

  steps:
    - name: git
      image: $(params.BASE_IMAGE)
      workingDir: $(workspaces.source.path)
      env:
      - name: HOME
        value: $(params.USER_HOME)
      - name: PARAM_VERBOSE
        value: $(params.VERBOSE)
      - name: PARAM_USER_HOME
        value: $(params.USER_HOME)
      - name: WORKSPACE_OUTPUT_PATH
        value: $(workspaces.output.path)
      - name: WORKSPACE_SSH_DIRECTORY_BOUND
        value: $(workspaces.ssh-directory.bound)
      - name: WORKSPACE_SSH_DIRECTORY_PATH
        value: $(workspaces.ssh-directory.path)
      - name: WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND
        value: $(workspaces.basic-auth.bound)
      - name: WORKSPACE_BASIC_AUTH_DIRECTORY_PATH
        value: $(workspaces.basic-auth.path)
      - name: IMAGE_URL
        value: $(params.IMAGE_URL)
      script: |
        #!/usr/bin/env sh
        set -eu

        # Setting up the config for the git.
        git config --global user.email "$(params.GIT_USER_EMAIL)"
        git config --global user.name "$(params.GIT_USER_NAME)"

        eval(params.GIT_SCRIPT)

​ 聪明的朋友已经看到了,我们这个任务主要的信息定义在$ GIT_SCRIPT ,其实很简单,就是把我们的清单从git上拉去下来通过yq工具来修改image信息,修改成功之后在推送到我们的代码库中。

Triggers创建

我们通过 EventListener 指定触发器,文件如下:

EventListener

apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
  name: gitlab-listener
spec:
  serviceAccountName: tekton-triggers-gstrain-sa
  resources:
    kubernetesResource:
      serviceType: NodePort 
  triggers:
    - name: gitlab-push-events-trigger
      bindings:						#TriggerBinding 对象
        - name: gitrevision
          value: $(body.checkout_sha)
        - name: gitrepositoryurl
          value: $(body.repository.git_http_url)  
        - name: service-name
          value: $(body.repository.name)
        - name: gitref
          value: $(body.ref)
      interceptors:
        - name: "verify-gitlab-payload"
          ref:
            name: "gitlab"
            kind: ClusterInterceptor
          params:
            - name: secretRef
              value:
                secretName: "gitlab-secret"
                secretKey: "secretToken"
            - name: eventTypes
              value:
                - "Push Hook" #接收gitlab push 事件
      template:
        ref: triggertemplate   #TriggerTemplate 对象

因为EventListener 创建完成后会生成一个Listener服务,用来接收事件的响应。我是直接选择的NodePort来对外提供服务,使用路由的可忽略。

[root@master pipeline]# kubectl get svc 
NAME                                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                              AGE
el-gitlab-listener                  NodePort    10.253.177.9     <none>        8080:39949/TCP,9000:47734/TCP        3d7h

Secret

通过secrets来配置gitlab发送webhook时请求的校验

apiVersion: v1
kind: Secret
metadata:
  name: github-secret
type: Opaque
stringData:
  secretToken: "tekton-pipeline-123"

gitlabToken添加流程

-->> project -->> settings -->> webhooks -->> url(Listener服务URL) -->> secret token(github-secret资源)

RBAC

triggers中各个资源的访问,需要声名RBAC

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: tekton-triggers-gstrain-sa
secrets:
  - name: gitlab-secret
  - name: gitlab-auth
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: triggers-gstrain-eventlistener-binding
subjects:
- kind: ServiceAccount
  name: tekton-triggers-gstrain-sa
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: tekton-triggers-eventlistener-roles
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: triggers-gstrain-eventlistener-clusterbinding
subjects:
- kind: ServiceAccount
  name: tekton-triggers-gstrain-sa
  namespace: gstrain-pipeline
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: tekton-triggers-eventlistener-clusterroles

TriggerBinding

指定要从中提取数据的事件有效负载中的字段以及对应的字段,具体指的是哪些字段呢。其实这里所说的是gitlab webhook中发送来的请求,这些字段都可以被我们拿来利用。

bindings:						#TriggerBinding 对象
  - name: gitrevision
    value: $(body.checkout_sha)
  - name: gitrepositoryurl
    value: $(body.repository.git_http_url)  
  - name: service-name
    value: $(body.repository.name)
  - name: gitref
    value: $(body.ref)

  "object_kind": "push",
  "event_name": "push",
  "before": "68e0d3b62814596f5988d1db668df6da787f6b00",
  "after": "6e4977fb359fdde13d3f21ed7ac739102841e4ce",
  "ref": "refs/heads/master",
  "checkout_sha": "6e4977fb359fdde13d3f21ed7ac739102841e4ce",
  "message": null,
  "user_id": 1,
  "user_name": "gstrain",
  "user_username": "gstrain",
  "user_email": "",
  "user_avatar": "https://www.gravatar.com/avatar/5ccc082a1092ca51760a7b3956c04abc?s=80&d=identicon",
  "project_id": 4,
  "project": 
    "id": 4,
    "name": "web-service",
    "description": "",
    "web_url": "http://gitlab-6859ff885-96p66/gstrain/web-service",
    "avatar_url": null,
    "git_ssh_url": "git@gitlab-6859ff885-96p66:gstrain/web-service.git",
    "git_http_url": "http://10.177.9.244:31002/gstrain/web-service.git",
    "namespace": "gstrain",
    "visibility_level": 20,
    "path_with_namespace": "gstrain/web-service",
    "default_branch": "main",
    "ci_config_path": null,
    "homepage": "http://gitlab-6859ff885-96p66/gstrain/web-service",
    "url": "git@gitlab-6859ff885-96p66:gstrain/web-service.git",
    "ssh_url": "git@gitlab-6859ff885-96p66:gstrain/web-service.git",
    "http_url": "http://10.177.9.244:31002/gstrain/web-service.git"
  ,
  "commits": [
    
      "id": "6e4977fb359fdde13d3f21ed7ac739102841e4ce",
      "message": "z\\n",
      "title": "z",
      "timestamp": "2022-08-22T17:46:04+08:00",
      "url": "http://gitlab-6859ff885-96p66/gstrain/web-service/-/commit/6e4977fb359fdde13d3f21ed7ac739102841e4ce",
      "author": 
        "name": "Administrator",
        "email": "1376252133@qq.com"
      ,
      "added": [

      ],
      "modified": [
        "Jenkinsfile"
      ],
      "removed": [

      ]
    
  ],
  "total_commits_count": 1,
  "push_options": 
  ,
  "repository": 
    "name": "web-service",
    "url": "git@gitlab-6859ff885-96p66:gstrain/web-service.git",
    "description": "",
    "homepage": "http://gitlab-6859ff885-96p66/gstrain/web-service",
    "git_http_url": "http://10.177.9.244:31002/gstrain/web-service.git",
    "git_ssh_url": "git@gitlab-6859ff885-96p66:gstrain/web-service.git",
    "visibility_level": 20
  

TriggerTemplate

接下来到了我们最重要的环节,我们可以通过读取 TriggerBinding 定义的参数,定义如下TriggerTemplate ,我们这里定义的是一个 PipelineRun 的模板,需要选定一个定义好的pipeline

---
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerTemplate
metadata:
  name: triggertemplate
spec:
  params:
    - name: gitrevision
      description: The git revision
      default: master
    - name: gitrepositoryurl
      description: The git repository url
    - name: service-name
      description: The service name
    - name: gitref
      description: The branch to checkout
  resourcetemplates:
    - apiVersion: tekton.dev/v1beta1
      kind: PipelineRun
      metadata:
        generateName: $(tt.params.service-name)-pipeline-
        labels:
          service: $(tt.params.service-name)
        namespace: gstrain-pipeline
      spec:
        params:
          - name: git-http-url
            value: $(tt.params.gitrepositoryurl)
          - name: git-revision
            value: $(tt.params.gitrevision)
          - name: service-name
            value: $(tt.params.service-name)        
          - name: git-ref
            value: $(tt.params.gitref)
          - name: subdirectory
            value: $(tt.params.service-name)
#          - name: package
#            value: $(tt.params.service-name)
        serviceAccountName: tekton-triggers-gstrain-sa
        pipelineRef:
          name: gstrain-pipeline
        workspaces:
        - name: shared-data
          persistentVolumeClaim:
            claimName: my-app
        - name: dockerconfig
          secret:
            secretName: dockerconfig
#        - name: git-basic-auth
#          secret:
#            secretName: git-basic-auth

#结果

​ 最后让我们git push来触发我们的triggers,测试下我们的流程是否正常,在kubernetes集群中可查看相应的pod任务。

[root@master ~]# kubectl get pod -l triggers.tekton.dev/eventlistener=gitlab-listener
NAME                                              READY   STATUS      RESTARTS   AGE
web-service-pipeline-pcpsl-change-manifests-pod   0/1     Completed   0          4h37m
web-service-pipeline-pcpsl-fetch-repo-pod         0/2     Completed   0          4h38m
web-service-pipeline-pcpsl-golang-build-pod       0/1     Completed   0          4h38m
web-service-pipeline-pcpsl-kaniko-pod             0/3     Completed   0          4h37m

到这我们的tekton构建CI/CD就已经全部完成,

以上是关于云原生 | kubernetes - tekton构建CI/CD流水线的主要内容,如果未能解决你的问题,请参考以下文章

初探云原生应用管理之:聊聊 Tekton 项目

kubernetes 原生的 CI-CD 工具 Tekton

kubernetes 原生的 CI-CD 工具 Tekton

云原生 CI/CD 框架 Tekton 初体验

云原生在京东丨基于 Tekton 打造下一代云原生 CI 平台

在 Kubernetes 上执行 GitHub Actions 流水线作业