Tekton gitlab CI/CD 实例

发布时间 2023-12-23 13:44:52作者: 小吉猫

环境介绍

gitlab 地址

gitlab: http://192.168.174.108:8080/root/spring-boot-helloWorld

Task 说明

1. git-clone:克隆项目的源代码
2. build-to-package:代码测试、构建和打包
3. generate-build-id:生成Build ID
4. image-build-and-push:镜像构建(和推送)
5. deploy-to-cluster:将新版本的镜像更新到Kubernetes集群上

创建 secret

secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: gitlab-secret
  namespace: tekton-demo
  annotations:
    tekton.dev/git-0: http://192.168.174.108:8080 # Described below
type: kubernetes.io/basic-auth
stringData:
  username: "xxxxx"
  password: "xxxxxx"
---
apiVersion: v1
kind: Secret
metadata:
  name: gitlab-webhook-token
  namespace: tekton-demo
type: Opaque
stringData:
  # Generated by command "openssl rand -base64 12"
  webhookToken: "+FmTUzNvthZWSsVrtvAqtQ=="

---
apiVersion: v1
kind: Secret
metadata:
  name: docker-config
  namespace: tekton-demo
  annotations:
    tekton.dev/docker-0: https://index.docker.io/v1/ # Described below
type: kubernetes.io/basic-auth
stringData:
  username: "xxxxx"
  password: "xxxxx"

创建 secret 

# kubectl apply -f secret.yaml
secret/gitlab-secret configured
secret/gitlab-webhook-token configured
secret/docker-config created

查看 secret 

# kubectl get secret -n tekton-demo
NAME                   TYPE                       DATA   AGE
docker-config          kubernetes.io/basic-auth   2      93s
gitlab-secret          kubernetes.io/basic-auth   2      3m19s
gitlab-webhook-token   Opaque                     1      3m19s

创建 serviceaccount

serviceaccount.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: gitlab-clone
  namespace: tekton-demo
secrets:
  - name: gitlab-secret
  - name: docker-config

创建 serviceaccount 

# kubectl apply -f serviceaccount.yaml
serviceaccount/gitlab-clone created

查看 serviceaccount

# kubectl get serviceaccount -n tekton-demo
NAME           SECRETS   AGE
default        0         18h
gitlab-clone   1         85s

创建 rbac

rbac.yaml

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: tekton-triggers-gitlab-minimal
  namespace: tekton-demo
rules:
  # Permissions for every EventListener deployment to function
  - apiGroups: ["triggers.tekton.dev"]
    resources: ["eventlisteners", "triggerbindings", "triggertemplates","triggers","interceptors"]
    verbs: ["get","list","watch"]
  - apiGroups: [""]
    # secrets are only needed for Github/Gitlab interceptors, serviceaccounts only for per trigger authorization
    resources: ["configmaps", "secrets", "serviceaccounts"]
    verbs: ["get", "list", "watch"]
  # Permissions to create resources in associated TriggerTemplates
  - apiGroups: ["tekton.dev"]
    resources: ["pipelineruns", "pipelineresources", "taskruns"]
    verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: tekton-triggers-gitlab-binding
  namespace: tekton-demo
subjects:
  - kind: ServiceAccount
    name: gitlab-clone
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-minimal
rules:
  - apiGroups: ["triggers.tekton.dev"]
    resources: ["clusterinterceptors","clustertriggerbindings"]
    verbs: ["get", "list","watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tekton-triggers-gitlab-binding
subjects:
  - kind: ServiceAccount
    name: gitlab-clone
    namespace: tekton-demo
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: tekton-triggers-gitlab-minimal

创建 rbac

# kubectl apply -f rbac.yaml
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-minimal created
clusterrolebinding.rbac.authorization.k8s.io/tekton-triggers-gitlab-binding created

创建存储卷

pvc-cache.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: maven-cache
  namespace: tekton-demo
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
  storageClassName: nfs-csi
  volumeMode: Filesystem
  
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: docker-build-cache
  namespace: tekton-demo
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
  storageClassName: nfs-csi
  volumeMode: Filesystem

创建 pvc

# kubectl apply -f pvc-cache.yaml
persistentvolumeclaim/maven-cache created
persistentvolumeclaim/docker-build-cache created

查看 pvc

# kubectl get pvc -n tekton-demo
NAME                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
docker-build-cache   Bound    pvc-520e91f0-46d5-442f-938e-4c7a0657a583   5Gi        RWX            nfs-csi        18s
maven-cache          Bound    pvc-2d3cfaa1-e200-423b-b29b-52ef570f0e6b   5Gi        RWX            nfs-csi        18s

创建 Task

tasks.yaml

apiVersion: tekton.dev/v1
kind: Task
metadata:
  name: git-clone
  namespace: tekton-demo
spec:
  description: Clone the code repository to the workspace. 
  params:
    - name: git-repo-url
      type: string
      description: git repository url to clone
    - name: git-revision
      type: string
      description: git revision to checkout (branch, tag, sha, ref)
  workspaces:
    - name: source
      description: The git repo will be cloned onto the volume backing this workspace
  steps:
    - name: git-clone
      image: alpine/git:v2.36.1
      script: | 
        git clone -v $(params.git-repo-url) $(workspaces.source.path)/source
        cd $(workspaces.source.path)/source && git reset --hard $(params.git-revision)
---
apiVersion: tekton.dev/v1
kind: Task
metadata:
  name: build-to-package
  namespace: tekton-demo
spec:
  description: build application and package the files to image
  workspaces:
    - name: source
      description: The git repo that cloned onto the volume backing this workspace
  steps:
    - name: build
      image: maven:3.8-openjdk-11-slim
      workingDir: $(workspaces.source.path)/source
      volumeMounts:
        - name: m2
          mountPath: /root/.m2
      script: mvn clean install
  volumes:
    - name: m2
      persistentVolumeClaim:
        claimName: maven-cache
---
apiVersion: tekton.dev/v1
kind: Task
metadata:
  name: generate-build-id
  namespace: tekton-demo
spec:
  params:
    - name: git-version
      description: The version of the application
      type: string
  results:
    - name: datetime
      description: The current date and time
    - name: buildId
      description: The build ID
  steps:
    - name: generate-datetime
      image: ikubernetes/admin-box:v1.2
      script: |
        #!/usr/bin/env bash
        datetime=`date +%Y%m%d-%H%M%S`
        echo -n ${datetime} | tee $(results.datetime.path)
    - name: generate-buildid
      image: ikubernetes/admin-box:v1.2
      script: |
        #!/usr/bin/env bash
        buildDatetime=`cat $(results.datetime.path)`
        buildId=$(params.git-version)-${buildDatetime}
        echo -n ${buildId} | tee $(results.buildId.path)
---
apiVersion: tekton.dev/v1
kind: Task
metadata:
  name: image-build-and-push
  namespace: tekton-demo
spec:
  description: package the application files to image
  params:
    - name: dockerfile
      description: The path to the dockerfile to build (relative to the context)
      default: Dockerfile
    - name: image-url
      description: Url of image repository
    - name: image-tag
      description: Tag to apply to the built image
  workspaces:
    - name: source
    #- name: dockerconfig
    #  mountPath: /kaniko/.docker
  steps:
    - name: image-build-and-push
      image: gcr.dockerproxy.com/kaniko-project/executor:latest
      securityContext:
        runAsUser: 0
      env:
        - name: DOCKER_CONFIG
          value: /root/.docker
      command:
        - /kaniko/executor
      args:
        - --dockerfile=$(params.dockerfile)
        - --context=$(workspaces.source.path)/source
        - --destination=$(params.image-url):$(params.image-tag)
        - --cache=true
        - --cache-dir=/root/build-image-cache
      volumeMounts:
        - name: docker-build-cache
          mountPath: /root/build-image-cache
  volumes:
    - name: docker-build-cache
      persistentVolumeClaim:
        claimName: docker-build-cache
---

创建 task 

# kubectl apply -f task.yaml
task.tekton.dev/git-clone created
task.tekton.dev/build-to-package created
task.tekton.dev/generate-build-id created
task.tekton.dev/image-build-and-push created

查看 task 

# kubectl get task -n tekton-demo
NAME                   AGE
build-to-package       53s
generate-build-id      53s
git-clone              53s
image-build-and-push   53s

查看 task dashboard

创建 pipeline

pipeline.yaml

apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
  name: source-to-image
  namespace: tekton-demo
spec:
  params:
    - name: git-repo-url
      type: string
      description: git repository url to clone
    - name: git-revision
      type: string
      description: git revision to checkout (branch, tag, sha, ref)
      default: main
    - name: image-build-context
      description: The path to the build context, used by Kaniko - within the workspace
      default: .
    - name: image-url
      description: Url of image repository
    - name: git-version
      description: The version of the application
      type: string
      default: "v1.0" 
  workspaces:
    - name: codebase
    #- name: docker-config
  tasks:
    - name: git-clone
      taskRef:
        name: git-clone
      params:
        - name: git-repo-url
          value: "$(params.git-repo-url)"
        - name: git-revision
          value: "$(params.git-revision)"
      workspaces:
        - name: source
          workspace: codebase
    - name: build-to-package
      taskRef:
        name: build-to-package
      workspaces:
        - name: source
          workspace: codebase
      runAfter:
        - git-clone
    - name: generate-build-id
      taskRef:
        name: generate-build-id
      params:
        - name: git-version
          value: "$(params.git-version)"
      runAfter:
        - git-clone
    - name: image-build-and-push
      taskRef:
        name: image-build-and-push
      params:
        - name: image-url
          value: "$(params.image-url)"
        - name: image-tag
          value: "$(tasks.generate-build-id.results.buildId)"
      workspaces:
        - name: source
          workspace: codebase
        #- name: dockerconfig
        #  workspace: docker-config
      runAfter:
        - generate-build-id
        - build-to-package

创建 pipeline

# kubectl apply -f pipeline.yaml
pipeline.tekton.dev/source-to-image created

查看 pipeline

# kubectl get pipeline -n tekton-demo
NAME              AGE
source-to-image   3m5s

查看 pipeline dashborad

创建 triggertemplate

triggertemplate.yaml

apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
  name: s2i-tt
  namespace: tekton-demo
spec:
  params:  # 定义参数
  - name: git-revision
  - name: git-repo-url
  - name: image-url
  - name: git-version
  resourcetemplates:
  - apiVersion: tekton.dev/v1
    kind: PipelineRun
    metadata:
      generateName: s2i-trigger-run-  # TaskRun 名称前缀
    spec:
      pipelineRef:
        name: source-to-image
      taskRunSpec:
        - pipelineTaskName: git-clone
          serviceAccountName: gitlab-clone
        - pipelineTaskName: image-build-and-push
          serviceAccountName: gitlab-clone
      params:
        - name: git-repo-url
          value: $(tt.params.git-repo-url)
        - name: git-revision
          value: $(tt.params.git-revision)
        - name: image-url
          value: $(tt.params.image-url)
        - name: git-version
          value: $(tt.params.git-version)
      workspaces:
        - name: codebase
          volumeClaimTemplate:
            spec:
              accessModes:
                - ReadWriteOnce
              resources:
                requests:
                  storage: 1Gi
              storageClassName: nfs-csi
        #- name: docker-config
        #  secret:
        #    secretName: docker-config

创建 triggertemplate

# kubectl apply -f triggertemplate.yaml
triggertemplate.triggers.tekton.dev/s2i-tt created

查看 triggertemplate

# kubectl get triggertemplate -n tekton-demo
NAME     AGE
s2i-tt   3s

查看 triggertemplate dashboard

创建 triggerbinding

triggerbinding.yaml

apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
  name: s2i-binding
  namespace: tekton-demo
spec:
  params:
  - name: git-revision
    value: $(body.checkout_sha)
  - name: git-repo-url
    value: $(body.repository.git_http_url)
  - name: image-url
    value: 1304995320/spring-boot-helloworld
  - name: git-version
    value: v1.0

创建 triggerbinding

# kubectl apply -f triggerbinding.yaml
triggerbinding.triggers.tekton.dev/s2i-binding created

查看 triggerbinding

# kubectl get triggerbinding -n tekton-demo
NAME          AGE
s2i-binding   84s

查看 triggerbinding dashboard

创建 eventlistener

eventlistener.yaml

apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
  name: s2i-listener 
  namespace: tekton-demo
spec:
  serviceAccountName: gitlab-clone
  triggers:
  - name: gitlab-push-events-trigger
    interceptors:
    - ref:
        name: "gitlab"
      params:
      - name: "secretRef"
        value:
          secretName: gitlab-webhook-token 
          secretKey: webhookToken
      - name: "eventTypes"
        value: 
          - "Push Hook"
          #- "Tag Push Hook"
          - "Merge Request Hook"
    bindings:
    - ref: s2i-binding
    template:
      ref: s2i-tt
  resources:
    kubernetesResource:
      serviceType: NodePort

创建 eventlistener

# kubectl apply -f eventlistener.yaml
eventlistener.triggers.tekton.dev/s2i-listener created

查看 eventlistener

# kubectl get eventlistener -n tekton-demo
NAME           ADDRESS                                                 AVAILABLE   REASON                     READY   REASON
s2i-listener   http://el-s2i-listener.tekton-demo.svc.wgs.local:8080   True        MinimumReplicasAvailable   True    

查看 eventlistener pod

# kubectl get pods -n tekton-demo
NAME                               READY   STATUS    RESTARTS   AGE
el-s2i-listener-59dd5d7dc7-ntfvw   1/1     Running   0          4s

查看 eventlistener svc

# kubectl get svc -n tekton-demo
NAME              TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                         AGE
el-s2i-listener   NodePort   10.100.127.222   <none>        8080:31340/TCP,9000:31150/TCP   35s

查看 eventlistener dashborad

测试 Tekton CI/CD 

添加 webhook

测试 Push event

查看 Push event

查看 EventListener Push event 日志信息

# kubectl logs -f el-s2i-listener-59dd5d7dc7-g7j4x -n tekton-demo
{"severity":"info","timestamp":"2023-12-08T03:08:16.742Z","logger":"eventlistener","caller":"sink/sink.go:442","message":"ResolvedParams : [{Name:image-url Value:1304995320/spring-boot-helloworld} {Name:git-version Value:v1.0} {Name:git-revision Value:513280bfe42b7049e2a6348148888ef2881dc51b} {Name:git-repo-url Value:http://192.168.174.108:8080/root/spring-boot-helloWorld.git}]","commit":"acb7b71-dirty","eventlistener":"s2i-listener","namespace":"tekton-demo","/triggers-eventid":"f4f5c217-cd17-473c-a448-87ba70f40b0e","eventlistenerUID":"e8e634b0-d572-431a-838f-3664e5f46daa","/triggers-eventid":"f4f5c217-cd17-473c-a448-87ba70f40b0e","/trigger":"gitlab-push-events-trigger"}
{"severity":"info","timestamp":"2023-12-08T03:08:16.744Z","logger":"eventlistener","caller":"resources/create.go:98","message":"Generating resource: kind: &APIResource{Name:pipelineruns,Namespaced:true,Kind:PipelineRun,Verbs:[delete deletecollection get list patch create update watch],ShortNames:[pr prs],SingularName:pipelinerun,Categories:[tekton tekton-pipelines],Group:tekton.dev,Version:v1,StorageVersionHash:lWZRMGzJrT4=,}, name: s2i-trigger-run-","commit":"acb7b71-dirty"}
{"severity":"info","timestamp":"2023-12-08T03:08:16.744Z","logger":"eventlistener","caller":"resources/create.go:106","message":"For event ID \"f4f5c217-cd17-473c-a448-87ba70f40b0e\" creating resource tekton.dev/v1, Resource=pipelineruns","commit":"acb7b71-dirty"}

查看 pipelinerun dashboard

查看 docker hub

测试  Tag Push event

interceptors 未定义eventTypes Tag Push Hook,因此不为触发CI/CD流程。

查看 Tag Push event

查看 EventListener Tag Push event 日志信息

# kubectl logs -f el-s2i-listener-59dd5d7dc7-g7j4x -n tekton-demo
{"severity":"info","timestamp":"2023-12-08T03:12:00.729Z","logger":"eventlistener","caller":"sink/sink.go:420","message":"interceptor stopped trigger processing: rpc error: code = FailedPrecondition desc = event type Tag Push Hook is not allowed","commit":"acb7b71-dirty","eventlistener":"s2i-listener","namespace":"tekton-demo","/triggers-eventid":"11392ce5-515b-4201-8cd7-24e3e8860a5a","eventlistenerUID":"e8e634b0-d572-431a-838f-3664e5f46daa","/triggers-eventid":"11392ce5-515b-4201-8cd7-24e3e8860a5a","/trigger":"gitlab-push-events-trigger"}