tekton

相关链接:

https://tekton.dev/vault/pipelines-v0.44.x-lts/

https://github.com/tektoncd/pipeline

https://hub.tekton.dev/

https://github.com/argoproj/argo-cd/releases

https://killercoda.com/

https://github.com/ljy-life/tkn-demo

版本说明

Client version: 0.30.0
Pipeline version: v0.44.2
Triggers version: v0.23.0
Dashboard version: v0.34.0

注意: 在 tekton pipeline 0.46.0 版本之后, tekton 官方移除了对 pipelineresource 的支持,所以本次使用的是 tekton 0.44.2 版本。

https://github.com/tektoncd/pipeline/blob/main/docs/pipelineresources.md

Tekton + ArgoCD 云原生时代的 CICD 利器_tekton

tekton 和 kubernetes 版本对应关系

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_02

tekton 安装

https://github.com/tektoncd/pipeline/releases/tag/v0.44.2

kubectl apply -f https://github.com/tektoncd/pipeline/releases/download/v0.44.2/release.yaml

相关镜像可以通过 killercoda 同步之自己的 dockerhub 上,默认存放在 gcr.io 镜像仓库,国内无法拉取镜像

Tekton + ArgoCD 云原生时代的 CICD 利器_tekton_03

tkn cli 安装

https://github.com/tektoncd/cli/releases/tag/v0.30.0

yum install -y  https://github.com/tektoncd/cli/releases/download/v0.30.0/tektoncd-cli-0.30.0_Linux-64bit.rpm

# 也可以通过下载二进制文件
wget https://github.com/tektoncd/cli/releases/download/v0.30.0/tkn_0.30.0_Linux_x86_64.tar.gz
tar -xf tkn_0.30.0_Linux_x86_64.tar.gz
cp tkn_0.30.0_Linux_x86_64/tkn /usr/local/bin/

# 执行查看当前版本
[root@master tekton]# tkn version
Client version: 0.30.0
Pipeline version: v0.44.2

tekton Dashboard 安装

https://github.com/tektoncd/dashboard/releases/tag/v0.34.0

kubectl apply -f https://github.com/tektoncd/dashboard/releases/download/v0.34.0/release.yaml

# 开放 32097 端口进行访问,也可以配置 Ingress
kubectl -n tekton-pipelines patch svc tekton-dashboard -p '{"spec":{"type":"NodePort","ports":[{"name":"http","nodePort": 32097,"port": 9097,"protocol": "TCP","targetPort": 9097}]}}'

# 查看版本
[root@master tekton]# tkn version
Client version: 0.30.0
Pipeline version: v0.44.2
Triggers version: v0.23.0
Dashboard version: v0.34.0

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_04

tekton Trigger 安装

https://github.com/tektoncd/triggers/releases/tag/v0.23.0

kubectl apply -f https://storage.googleapis.com/tekton-releases/triggers/previous/v0.23.0/release.yaml
kubectl apply -f https://storage.googleapis.com/tekton-releases/triggers/previous/v0.23.0/interceptors.yaml

argoCD

https://github.com/argoproj/argo-cd/releases/tag/v2.5.16

argoCD 安装

wget https://raw.githubusercontent.com/argoproj/argo-cd/v2.5.16/manifests/install.yaml

# 修改 ardocd-server 启动命令,增加 --insecure 参数
10504       containers:
10505       - command:
10506         - argocd-server
10507         - --insecure
10508         env:
10509         - name: ARGOCD_SERVER_INSECURE

# 部署
kubectl apply -n argocd -f install.yaml

Tekton + ArgoCD 云原生时代的 CICD 利器_tekton_05

argoCD cli 安装

wget https://github.com/argoproj/argo-cd/releases/download/v2.5.16/argocd-linux-amd64
chmod +x argocd-linux-amd64
mv argocd-linux-amd64 /usr/local/bin/argocd

argoCD ingress 访问

# cat ingress-argocd.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  namespace: argocd
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: argocd.whale.com # 根据实际情况进行修改
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: argocd-server
            port:
              number: 80

获取用户密码并进行修改

kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
aSXJ30csHCS84SlN

本地配置 hosts 解析后,使用 cli 登录修改

[root@master tekton]# cat /etc/hosts
10.0.7.220 argocd.whale.com
10.0.7.220 el.whale.com
# 使用原密码登录 argocd
argocd login argocd.whale.com

# 修改原密码
argocd account update-password
WARN[0000] Failed to invoke grpc call. Use flag --grpc-web in grpc calls. To avoid this warning message, use flag --grpc-web.
*** Enter password of currently logged in user (admin): 输入当前密码,可直接复制粘贴
*** Enter new password for user admin: 12345678 必须为8-32位
*** Confirm new password for user admin: 密码确认
Password updated 更新成功,可使用此密码登录WEB UI界面。
Context 'argocd.whale.com' updated

CICD 配置

注意:为了更贴合实际场景,gitlab 和 harbor 均为 https 配置

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_06

需要在 gitlab 服务器和 kubernets coreDNS 配置 hosts 域名解析,或者在内部 DNS 配置 A 记录解析

# hosts
10.0.7.220 el.whale.com
10.0.7.220 argocd.whale.com

# coreDNS 配置域名解析 
kubectl -n kube-system edit cm coredns 
...
        hosts {
        10.0.7.220 el.whale.com
        10.0.7.220 argocd.whale.com
        fallthrough
        }
...

Tekton + ArgoCD 云原生时代的 CICD 利器_tekton_07

一、gitlab 仓库配置

自建的 仓库 为 https 环境,证书为自签名证书,这种方式更符合公司场景, http 环境的更加简单,只是在某些地方需要注意下

1. 创建源码仓库 tekton-pipeline-demo

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_08

将相关源码上传至仓库中,源码只是启动了一个 gin 框架,用于测试。

[root@whale ~]# mkdir -pv tekton-pipeline-demo
[root@whale ~]# cd tekton-pipeline-demo
[root@whale tekton-pipeline-demo]# ls
Dockerfile  go.mod  go.sum  main.go  README.md
}
[root@whale tekton-pipeline-demo]# git init 
初始化空的 Git 版本库于 /root/tekton-pipeline-demo/.git/
[root@whale tekton-pipeline-demo]# git remote add origin https://10.0.2.196:8443/root/tekton-pipeline-demo.git
[root@whale tekton-pipeline-demo]# git add .
[root@whale tekton-pipeline-demo]# git commit -m "Initial commit"
[master(根提交) 9787e89] Initial commit
 5 files changed, 87 insertions(+)
 create mode 100644 Dockerfile
 create mode 100644 README.md
 create mode 100644 go.mod
 create mode 100644 go.sum
 create mode 100644 main.go
[root@whale tekton-pipeline-demo]# git push -u origin master
Username for 'https://10.0.2.196:8443': root
Password for 'https://root@10.0.2.196:8443': 
Counting objects: 7, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (7/7), 2.52 KiB | 0 bytes/s, done.
Total 7 (delta 0), reused 0 (delta 0)
To https://10.0.2.196:8443/root/tekton-pipeline-demo.git
 * [new branch]      master -> master
分支 master 设置为跟踪来自 origin 的远程分支 master。


Tekton + ArgoCD 云原生时代的 CICD 利器_tekton_09

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_10

查看 gitlab 是否存在内容

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_11

2. 创建 helm 仓库 tekton-argo-helm

Tekton + ArgoCD 云原生时代的 CICD 利器_tekton_12

同上,将 helm 的相关源码上传至镜像仓库

[root@whale ~]# mkdir -pv tekton-argo-helm
mkdir: 已创建目录 "tekton-argo-helm"
[root@whale ~]# cd tekton-argo-helm
[root@whale tekton-argo-helm]# ls
helm
[root@whale tekton-argo-helm]# ls helm/
Chart.yaml  my-values.yaml  templates  values.yaml
[root@whale tekton-argo-helm]# git init 
初始化空的 Git 版本库于 /root/tekton-argo-helm/.git/
[root@whale tekton-argo-helm]# git remote add origin https://10.0.2.196:8443/root/tekton-argo-helm.git
[root@whale tekton-argo-helm]# git add .
[root@whale tekton-argo-helm]# git commit -m "Initial commit"
[master(根提交) 4997af4] Initial commit
 9 files changed, 256 insertions(+)
 create mode 100644 helm/.helmignore
 create mode 100644 helm/Chart.yaml
 create mode 100644 helm/my-values.yaml
 create mode 100644 helm/templates/NOTES.txt
 create mode 100644 helm/templates/_helpers.tpl
 create mode 100644 helm/templates/deployment.yaml
 create mode 100644 helm/templates/ingress.yaml
 create mode 100644 helm/templates/service.yaml
 create mode 100644 helm/values.yaml
[root@whale tekton-argo-helm]# git push -u origin master
Username for 'https://10.0.2.196:8443': root
Password for 'https://root@10.0.2.196:8443': 
Counting objects: 13, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (13/13), 3.60 KiB | 0 bytes/s, done.
Total 13 (delta 1), reused 0 (delta 0)
To https://10.0.2.196:8443/root/tekton-argo-helm.git
 * [new branch]      master -> master
分支 master 设置为跟踪来自 origin 的远程分支 master。

Tekton + ArgoCD 云原生时代的 CICD 利器_tekton_13

二、tekton Task 任务创建

1. Task git-clone

task-clone.yaml,使用的是 tekton hub 中的 git-clone 模板

# cat task-clone.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: git-clone
spec:
  workspaces:
    - name: output
      description: The git repo will be cloned onto the volume backing this Workspace.
    - name: basic-auth
      optional: true
      description: |
        A Workspace containing a .gitconfig and .git-credentials file. These
        will be copied to the user's 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: url
      description: Repository URL to clone from.
      type: string
    - name: revision
      description: Revision to checkout. (branch, tag, sha, ref, etc...)
      type: string
      default: ""
    - 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: "false"  # 使用的https环境,关闭 ssl 证书校验
    - 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: 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: "ljymyy/git-init:v0.44.2"  # 修改为dockerhub中的地址
    - name: userHome
      description: |
        Absolute path to the user's 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: "/home/git"
  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.
  steps:
    - name: clone
      image: "$(params.gitInitImage)"
      env:
      - name: HOME
        value: "$(params.userHome)"
      - 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_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_BASIC_AUTH_DIRECTORY_BOUND
        value: $(workspaces.basic-auth.bound)
      - name: WORKSPACE_BASIC_AUTH_DIRECTORY_PATH
        value: $(workspaces.basic-auth.path)
      securityContext:
        runAsNonRoot: no
        runAsUser: 0
      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

        CHECKOUT_DIR="${WORKSPACE_OUTPUT_PATH}/${PARAM_SUBDIRECTORY}"

        cleandir() {
          # Delete any existing contents of the repo directory if it exists.
          #
          # We don't 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 || true
        fi

        /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)"

2. Task build

task-build.yaml

# cat task-build.yaml 
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: build
spec:
  workspaces:
    - name: go-repo
      mountPath: /workspace/repo
  steps:
    - name: build
      image: golang:1.14-alpine
      workingDir: /workspace/repo
      script: |
        go build -v -o app
      env:
        - name: GOPROXY
          value: https://goproxy.cn
        - name: GOOS
          value: linux
        - name: GOARCH
          value: amd64

3. Task docker

task-docker.yaml

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: docker
spec:
  workspaces:
    - name: go-repo
  params:
    - name: image
      description: Reference of the image docker will produce.
    - name: registry_mirror
      description: Specific the docker registry mirror
      default: ""
    - name: registry_url
      description: private docker images registry url
  steps:
    - name: docker-build # 构建步骤
      image: docker:stable
      env:
        - name: DOCKER_HOST # 用 TLS 形式通过 TCP 链接 sidecar
          value: tcp://localhost:2376
        - name: DOCKER_TLS_VERIFY # 校验 TLS
          value: "1"
        - name: DOCKER_CERT_PATH # 使用 sidecar 守护进程生成的证书
          value: /certs/client
        - name: DOCKER_PASSWORD
          valueFrom:
            secretKeyRef:
              name: harbor-auth
              key: password
        - name: DOCKER_USERNAME
          valueFrom:
            secretKeyRef:
              name: harbor-auth
              key: username
      workingDir: $(workspaces.go-repo.path)
      script: | # docker 构建命令
        docker login $(params.registry_url) -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
        docker --tlsverify=false build --no-cache -f ./Dockerfile -t $(params.image) .
        docker --tlsverify=false push $(params.image)
      volumeMounts: # 声明挂载证书目录
        - mountPath: /certs/client
          name: dind-certs
  sidecars: # sidecar 模式,提供 docker daemon服务,实现真正的 DinD 模式
    - image: docker:dind
      name: server
      args:
        - --storage-driver=vfs
        - --userland-proxy=false
        - --debug
        - --tlsverify=false
        - --insecure-registry=$(params.registry_url)
        - --registry-mirror=$(params.registry_mirror)
      securityContext:
        privileged: true
      env:
        - name: DOCKER_TLS_CERTDIR # 将生成的证书写入与客户端共享的路径
          value: /certs
      volumeMounts:
        - mountPath: /certs/client
          name: dind-certs
      readinessProbe: # 等待 dind daemon 生成它与客户端共享的证书
        periodSeconds: 1
        exec:
          command: ["ls", "/certs/client/ca.pem"]
  volumes: # 使用 emptyDir 的形式即可
    - name: dind-certs

4. Task manifest

修改 helm 中 values.yamltask-helm-manifest.yaml

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: change-manifests
spec:
  params:
    - name: git_url
      description: Git repository containing manifest files to update
    - name: git_email
      default: whale@cloudwise.com
    - name: git_name
      default: Tekton Pipeline
    - name: git_manifest_dir
      description: Manifests files dir
    - name: tool_image
      default: ljymyy/helm-kubectl-curl-git-jq-yq
    - name: image_tag
      description: Deploy docker image tag
  steps:
    - name: git-push
      image: $(params.tool_image)
      env:
        - name: GIT_USERNAME
          valueFrom:
            secretKeyRef:
              name: gitlab-auth
              key: username
              optional: true
        - name: GIT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: gitlab-auth
              key: password
              optional: true
      command: ["/bin/bash"]
      args:
        - -c
        - |
          set -eu
          echo Load environment variables from previous steps
          # source /workspace/env-config
          git config --global user.email "$(params.git_email)"
          git config --global user.name "$(params.git_name)"
          # sslVerfiy false
          git config --global http.sslVerify false
          # 如果是 http 需要修改下边 url 为 http
          git clone --branch master --depth 1  https://${GIT_USERNAME}:${GIT_PASSWORD}@$(params.git_url) repo
          cd "repo/$(params.git_manifest_dir)"
          ls -l
          echo old value:
          cat my-values.yaml | yq r - 'image.tag'
          echo replacing with new value:
          echo $(params.image_tag)
          yq w --inplace my-values.yaml 'image.tag' "$(params.image_tag)"
          echo verifying new value
          yq r my-values.yaml 'image.tag'
          if ! git diff-index --quiet HEAD --; then
            git status
            git add .
            git commit -m "helm values updated by tekton pipeline in change-manifests task"
            git push
          else
              echo "no changes, git repository is up to date"
          fi

5. Task argo deploy

task-argo.yaml

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: sync
spec:
  volumes:
  - name: argocd-secret
    secret:
      secretName: $(inputs.params.argocd_secret)
  params:
    - name: argocd_url
      description: "The URL of the ArgoCD server"
    - name: argocd_secret
      description: "The secret containing the username and password for the tekton task to connect to argo"
    #- name: commit_id
    #  description: "The commit ID to update"
    - name: app_name
      description: "The name of the argo app to update"
    - name: app_revision
      default: "HEAD"
      description: "The revision of the argo app to update"
  steps:
  - name: deploy
    image: argoproj/argocd
    volumeMounts:
    - name: argocd-secret
      mountPath: /var/secret
    command:
    - sh
    args:
    - -ce
    - |
      set -e
      echo "update commit id"
      argocd login --insecure $(params.argocd_url) --username $(/bin/cat /var/secret/username) --password $(/bin/cat /var/secret/password)
      argocd app sync $(params.app_name) --revision $(params.app_revision)
      argocd app wait $(params.app_name) --health

三、 tekton Pipeline 流水线创建

pipeline 流水线可以讲 task 串在一起

1. Pipeline demo

argo-demo-pipeline.yaml

# cat argo-demo-pipeline.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: pipeline
spec:
  workspaces: # 声明 workspaces
    - name: go-repo-pvc
  params:
    # 定义代码仓库
    - name: git_url
    - name: git_infra_url
    - name: revision
      type: string
      default: "master"
    # 定义镜像参数
    - name: image
    - name: image_tag
    - name: registry_url
      type: string
      default: "harbor.cloudwise.com"
    - name: registry_mirror
      type: string
      default: "https://by0gaj4f.mirror.aliyuncs.com/"
    - name: git_manifest_dir
      default: "helm"
    # 定义 argocd 参数
    - name: argocd_url
    - name: argocd_secret
    - name: app_name
    - name: app_revision
      type: string
      default: "HEAD"
  tasks: # 添加task到流水线中
    - name: clone
      taskRef:
        name: git-clone
      workspaces:
        - name: output
          workspace: go-repo-pvc
      params:
        - name: url
          value: $(params.git_url)
        - name: revision
          value: $(params.revision)
    - name: build # 编译二进制程序
      taskRef:
        name: build
      runAfter: # 测试任务执行之后才执行 build task
        - clone
      workspaces: # 传递 workspaces
        - name: go-repo
          workspace: go-repo-pvc
    - name: docker # 构建并推送 Docker 镜像
      taskRef:
        name: docker
      runAfter:
        - build
      workspaces: # 传递 workspaces
        - name: go-repo
          workspace: go-repo-pvc
      params: # 传递参数
        - name: image
          value: $(params.image):$(params.image_tag)
        - name: registry_url
          value: $(params.registry_url)
        - name: registry_mirror
          value: $(params.registry_mirror)
    - name: manifests
      taskRef:
        name: change-manifests
      runAfter:
        - docker
      params:
      - name: git_url
        value: $(params.git_infra_url)
      - name: git_manifest_dir
        value: $(params.git_manifest_dir)
      - name: image_tag
        value: $(params.image_tag)
    - name: sync
      taskRef:
        name: sync
      runAfter:
        - manifests
      params:
      - name: argocd_url
        value: $(params.argocd_url)
      - name: argocd_secret
        value: $(params.argocd_secret)
      - name: app_name
        value: $(params.app_name)
      - name: app_revision
        value: $(params.app_revision)

四、tekton 需要的其他认证信息

1. secret 认证信息

gitlab harbor argo auth

申请的 pvc,用做 task 的 workspace 共享secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: gitlab-secret
type: Opaque
stringData:
  secretToken: "1234567"
---
apiVersion: v1
kind: Secret
metadata:
  name: gitlab-auth
  annotations:
    tekton.dev/git-0: https://10.0.2.196:8443
type: kubernetes.io/basic-auth
stringData:
  username: 'root'
  password: '123456'
---
apiVersion: v1
kind: Secret
metadata:
  name: harbor-auth
  annotations:
    tekton.dev/docker-0: https://harbor.whale.com
type: kubernetes.io/basic-auth
stringData:
    username: 'admin'
    password: '123456'
---
apiVersion: v1
kind: Secret
metadata:
  name: argocd-auth
type: Opaque
stringData:
  username: "admin"
  password: "123456"
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: tekton-build-sa
secrets:
  - name: harbor-auth
  - name: gitlab-auth
  - name: gitlab-secret
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tekton-clusterrole-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: tekton-build-sa
  namespace: default
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: go-repo-pvc
spec:
  resources:
    requests:
      storage: 5Gi
  volumeMode: Filesystem
  storageClassName: longhorn # 当前环境的存储类
  accessModes:
    - ReadWriteOnce

2. trigger 认证授权信息

gitlab-rbac.yaml

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: tekton-triggers-gitlab-minimal
rules:
   # EventListeners need to be able to fetch all namespaced resources
  - apiGroups: ['triggers.tekton.dev']
    resources:
      ['eventlisteners', 'triggerbindings', 'triggertemplates', 'triggers', 'interceptors']
    verbs: ['get', 'list', 'watch']
  - apiGroups: ['']
   #  configmaps is needed for updating logging config
    resources: ['configmaps']
    verbs: ['get', 'list', 'watch']
   # Permissions to create resources in associated TriggerTemplates
  - apiGroups: ['tekton.dev']
    resources: ['pipelineruns', 'pipelineresources', 'taskruns']
    verbs: ['create']
  - apiGroups: ['']
    resources: ['serviceaccounts']
    verbs: ['impersonate']
  - apiGroups: ['policy']
    resources: ['podsecuritypolicies']
    resourceNames: ['tekton-triggers']
    verbs: ['use']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: tekton-triggers-gitlab-binding
subjects:
  - kind: ServiceAccount
    name: tekton-triggers-gitlab-sa
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: tekton-triggers-gitlab-minimal
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: tekton-triggers-gitlab-clusterrole
rules:
   # EventListeners need to be able to fetch any clustertriggerbindings
  - apiGroups: ['triggers.tekton.dev']
    resources: ['clustertriggerbindings', 'clusterinterceptors']
    verbs: ['get', 'list', 'watch']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tekton-triggers-gitlab-clusterbinding
subjects:
  - kind: ServiceAccount
    name: tekton-triggers-gitlab-sa
    namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: tekton-triggers-gitlab-clusterrole

gitlab-listener.yaml

apiVersion: triggers.tekton.dev/v1alpha1
kind: EventListener
metadata:
  name: gitlab-listener  # 该事件监听器会创建一个名为el-gitlab-listener的Service对象
spec:
  serviceAccountName: tekton-build-sa
  triggers:
  - name: gitlab-push-events-trigger
    interceptors:
    - ref:
        name: gitlab
      params:
      - name: secretRef  # 引用 gitlab-secret 的 Secret 对象中的 secretToken 的值
        value:
          secretName: gitlab-secret
          secretKey: secretToken
      - name: eventTypes
        value:
          - Push Hook # 只接收 GitLab Push 事件
    bindings:  # 定义TriggerBinding,配置参数
    - name: gitrevision
      value: $(body.checkout_sha)
    - name: gitrepositoryurl
      value: $(body.repository.git_http_url)
    template:
      ref: gitlab-template

event-ingress.yaml用于做 gitlab webhook 的 地址

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: el.whale.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: el-gitlab-listener
            port:
              number: 8080

3. argo template

argo-gitlab-template.yaml

apiVersion: triggers.tekton.dev/v1alpha1[tekton + argoCD 云原生时代的 CICD 利器](#1.%20创建%20helm%20git%20仓库)
kind: TriggerTemplate
metadata:
  name: gitlab-template
spec:
  params: # 定义参数,和 TriggerBinding 中的保持一致
    - name: gitrevision
    - name: gitrepositoryurl
  resourcetemplates: # 定义资源模板
    - apiVersion: tekton.dev/v1beta1
      kind: PipelineRun # 定义 pipeline 模板
      metadata:
        generateName: gitlab-run- # TaskRun 名称前缀
      spec:
        serviceAccountName: tekton-build-sa
        pipelineRef:
          name: pipeline
        workspaces:
          - name: go-repo-pvc
            persistentVolumeClaim:
              claimName: go-repo-pvc
        params:
          - name: git_url
            value: $(tt.params.gitrepositoryurl)
          - name: git_infra_url
            value: 10.0.2.196:8443/root/tekton-argo-helm.git
          - name: image
            value: "harbor.whale.com/test/tekton-argo-demo"
          - name: image_tag
            value: "$(tt.params.gitrevision)"
          - name: argocd_url
            value: argocd.whale.com
          - name: argocd_secret
            value: argocd-auth
          - name: app_name
            value: whale-demo

五、创建 argo app

1. 创建 helm git 仓库

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_14

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_15

2. 创建项目

Tekton + ArgoCD 云原生时代的 CICD 利器_tekton_16

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_17

Tekton + ArgoCD 云原生时代的 CICD 利器_tekton_18

3. 添加app

Tekton + ArgoCD 云原生时代的 CICD 利器_tekton_19

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_20

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_21

六、gitlab 创建 webhook

1. 允许接收外部请求

Tekton + ArgoCD 云原生时代的 CICD 利器_tekton_22

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_23


  1. 开启应用 webhook

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_24

Tekton + ArgoCD 云原生时代的 CICD 利器_tekton_25

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_26


七、部署 tekton 相关 yaml

[root@master whale-demo]# kubectl apply -f auth/
role.rbac.authorization.k8s.io/tekton-triggers-gitlab-minimal created
rolebinding.rbac.authorization.k8s.io/tekton-triggers-gitlab-binding created
clusterrole.rbac.authorization.k8s.io/tekton-triggers-gitlab-clusterrole created
clusterrolebinding.rbac.authorization.k8s.io/tekton-triggers-gitlab-clusterbinding created
secret/gitlab-secret created
secret/gitlab-auth created
secret/harbor-auth created
secret/argocd-auth created
serviceaccount/tekton-build-sa created
clusterrolebinding.rbac.authorization.k8s.io/tekton-clusterrole-binding created
persistentvolumeclaim/go-repo-pvc created
[root@master whale-demo]# kubectl apply -f task/
task.tekton.dev/sync created
task.tekton.dev/build created
task.tekton.dev/git-clone created
task.tekton.dev/docker created
task.tekton.dev/change-manifests created
[root@master whale-demo]# kubectl apply -f pipeline/
pipeline.tekton.dev/pipeline created
[root@master whale-demo]# kubectl apply -f trigger/
ingress.networking.k8s.io/ingress created
eventlistener.triggers.tekton.dev/gitlab-listener created
[root@master whale-demo]# kubectl apply -f argo
triggertemplate.triggers.tekton.dev/gitlab-template created

八、修改代码,触发构建

[root@whale tekton-pipeline-demo]# git add .
[root@whale tekton-pipeline-demo]# git commit -m "v1"
[master 3ec5df0] v1
 1 file changed, 1 insertion(+), 1 deletion(-)
[root@whale tekton-pipeline-demo]# git push

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_27

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_28

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_29

Tekton + ArgoCD 云原生时代的 CICD 利器_argocd_30