• 【云原生 | Kubernetes 系列】--Gitops持续交付 CD Push Pipeline实现


    1. Tekton Trigger基础

    Tekton Triggers简介

    - 监控特定的事件,并在满足条件时自动触发Tekton Pipeline
    
    • 1
    • Tekton Triggers 为用户提供了一种声明式API
      • 它允许用户按需定义监视的事件,并将其与特定的Pipeline连接,从而实例化出PipelineRun
      • 还允许将事件中的某些属性值信息注入到Pipeline中

    Tekton Triggers重要组件

    - Trigger
    - TriggerBinding
    - TriggerTemplate
    - EventListener
    - Interceptor
    
    • 1
    • 2
    • 3
    • 4
    • 5

    定义一个Trigger实例化EventListener Pod,监听在某个webhook的套接字上,当被监视的组件产生相应事件时,基于webhook将事件推送给EventListener Pod,EvnetListerner Pod接收到事件后,通过TriggerBinding提取出事件的字段置,将值推送给TriggerTemplate(定义了PipelineRun),TriggerTemplate将接收到的事件字段向PipelineRun进行赋值.

    1.1 Interceptor

    负责在Trigger进行事件筛选之前,接收特定平台或系统(Gitlab)上全部事件,进而支持一些预处理操作.
    预处理完成后的时间,由Trigger进行筛选,符合条件的Event将传递给TriggerBinding

    1.2 Trigger

    触发器.用于由特定Event触发的具体行为
    Trigger由TriggerTemplate,TriggerBinding和Interceptor/ClusterInterceptor组成

    - Trigger需要附着在由EventListener定义运行的Pod之上,该Pod可通过监听的套接字接入Event
    - Event经由EventListener传入时,相应的Trigger就会被触发
    - Interceptor负责完成Event的拦截和预处理,并将预处理后的结果传递给TriggerTemplate和TriggerBinding
    
    • 1
    • 2
    • 3

    它是EventListener上的关键组件,主要由TriggerTemplate,TriggerBinding和Interceptor组成

    - TiggerTemplate是必选组件,定义在spec.template字段上,支持引用和内联两种方式
    - TriggerBinding可选,定义在spec.bindings字段上,支持引用和内联两种方式
    - ClusterInterceptor可选,定义在spec.interceptor字段上
    
    • 1
    • 2
    • 3

    事实上,Trigger也完全可以以内联方式直接定义在EventListener之上,这甚至也是更为常见的配置方式.

    1.3 TriggerTemplate

    负责将Tekton的资源配置(TaskRun和PipelineRun)加以"模块化",从而能够基于Event传入的参数进行动态渲染和实例化
    通过参数从TriggerBinding上接受配置信息,并以之实例化和完成Tekton资源创建

    其spec字段主要由以下两个字段组成

    • params
      • 当前TriggertTemplate的参数,从TriggerBinding接受传值
      • resourcetemplates中的资源模板中的参数,通过引用TriggerTemplate的参数值完成实例化
        • 格式为: ( t t . p a r a m s . ) 前 缀 p a r a m s 具 体 n a m e 为 后 缀 . 例 如 : (tt.params.)前缀 params具体name为后缀.例如: (tt.params.)paramsname.:(tt.params.git-url)
        • 先从TriggerTemplate传递给pipelinerun,再由pipelinerun传递给taskrun
    • resourcetemplates
      • 用于定义资源模板
      • 在Tekton的环境中,通常用于定义PipelineRun或TaskRun资源
      • 资源的名称,通常要使用generateName定义其前缀,而非使用name直接指定.指定pipelinerun的前缀,后缀由pipelinerun自动生成

    1.4 TriggerBinding和ClusterTriggerBinding

    TriggerBinding 命名空间级别
    ClusterTriggerBinding集群级别

    负责完成Evnet绑定,捕获其字段并存储为参数传递给TriggerTemplate
    而后,TriggerTemplate将相应的数据赋值给关联的TaskRun或PipelineRun资源上的参数

    其spec字段中,主要定义了params,每个parameters主要是name和value两个字段组成

    - name即为同一Trigger东中引用的TriggerTemplate上声明的某个参数的名称
    - value通常要引用Event事件中特定属性.例如$(body.repository.clone_url) 事件由body和header组成
    
    • 1
    • 2

    1.5 EventListener

    它是kubernetes对象,以Pod形式运行于kubernetes集群上,通过监听特定的端口接收Event
    这些Event则要传给定义在该EventListener上的Trigger进行过滤和处理
    EventListener是Trigger显化出的实体

    - 它一方面从事件源接收Event,另一方面又要根据Event来触发特定行为
    - 它是Tekton的客户端,可能会需要ServiceAccount和RBAC的定义以获取必要的资源权限
    
    • 1
    • 2

    EventListener被实例化成Pod,由它来监控一个特定的事件,当事件产生后推给EventListener Pod,先由Interceptor(基于TriggerBinding或ClusterTriggerBinding)完成内容的初步处理,进行处理并将事件筛选保存为参数发送给TriggerTemplate,完成参数赋值.完成TriggerTemplate中定义的PipelineRun和TaskRun的实例化

    每个EventListener中有1到多个Triggers
    每个Trigger上都有它的Interceptors(列表),TriggerBindings(列表),TriggerTemplate(对象)

    2. Tekton Trigger案例

    2.1 安装Tekton Trigger

    2.1.1 获取Tekton Trigger镜像及yaml

    获取yaml

    wget https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
    wget https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yaml
    
    • 1
    • 2

    获取镜像

    docker pull registry.cn-shanghai.aliyuncs.com/qiuqin/tekton-trigger:controller
    docker pull registry.cn-shanghai.aliyuncs.com/qiuqin/tekton-trigger:eventlistenersink
    docker pull registry.cn-shanghai.aliyuncs.com/qiuqin/tekton-trigger:webhook
    docker pull registry.cn-shanghai.aliyuncs.com/qiuqin/tekton-trigger:interceptors
    docker tag registry.cn-shanghai.aliyuncs.com/qiuqin/tekton-trigger:controller harbor.intra.com/tekton-trigger/controller:v0.21.0
    docker tag registry.cn-shanghai.aliyuncs.com/qiuqin/tekton-trigger:eventlistenersink harbor.intra.com/tekton-trigger/eventlistenersink:v0.21.0
    docker tag registry.cn-shanghai.aliyuncs.com/qiuqin/tekton-trigger:webhook harbor.intra.com/tekton-trigger/webhook:v0.21.0
    docker tag registry.cn-shanghai.aliyuncs.com/qiuqin/tekton-trigger:interceptors harbor.intra.com/tekton-trigger/interceptors:v0.21.0
    docker push harbor.intra.com/tekton-trigger/controller:v0.21.0
    docker push harbor.intra.com/tekton-trigger/eventlistenersink:v0.21.0
    docker push harbor.intra.com/tekton-trigger/webhook:v0.21.0
    docker push harbor.intra.com/tekton-trigger/interceptors:v0.21.0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    替换yaml中的镜像

    替换前

    root@k8s-master-01:/apps/trigger# grep image release.yaml
              image: "gcr.io/tekton-releases/github.com/tektoncd/triggers/cmd/controller:v0.21.0@sha256:c260835027b2d5bfccef8221eed5fb4571a2a4cb843c5bdea006163ee1f617bf"
              args: ["-logtostderr", "-stderrthreshold", "INFO", "-el-image", "gcr.io/tekton-releases/github.com/tektoncd/triggers/cmd/eventlistenersink:v0.21.0@sha256:10605e3af3cf534e10734ea684c94520299c26b29b9dfb67669f7b01a70147dd", "-el-port", "8080", "-el-security-context=true", "-el-events", "disable", "-el-readtimeout", "5", "-el-writetimeout", "40", "-el-idletimeout", "120", "-el-timeouthandler", "30", "-el-httpclient-readtimeout", "30", "-el-httpclient-keep-alive", "30", "-el-httpclient-tlshandshaketimeout", "10", "-el-httpclient-responseheadertimeout", "10", "-el-httpclient-expectcontinuetimeout", "1", "-period-seconds", "10", "-failure-threshold", "1"]
              image: "gcr.io/tekton-releases/github.com/tektoncd/triggers/cmd/webhook:v0.21.0@sha256:bdaef43faede7bc05ded54387f2dee0a3a032710fe876cc17034e75b9faf758d"
              
    root@k8s-master-01:/apps/trigger# grep image interceptors.yaml 
              image: "gcr.io/tekton-releases/github.com/tektoncd/triggers/cmd/interceptors:v0.21.0@sha256:6ec2a6df146507411dfc7b853efd97e43fa5dcbe7e8d9aeb810b704dde3069a1"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    替换后

    root@k8s-master-01:/apps/trigger#  grep image release.yaml
              image: harbor.intra.com/tekton-trigger/controller:v0.21.0
              args: ["-logtostderr", "-stderrthreshold", "INFO", "-el-image", "harbor.intra.com/tekton-trigger/eventlistenersink:v0.21.0", "-el-port", "8080", "-el-security-context=true", "-el-events", "disable", "-el-readtimeout", "5", "-el-writetimeout", "40", "-el-idletimeout", "120", "-el-timeouthandler", "30", "-el-httpclient-readtimeout", "30", "-el-httpclient-keep-alive", "30", "-el-httpclient-tlshandshaketimeout", "10", "-el-httpclient-responseheadertimeout", "10", "-el-httpclient-expectcontinuetimeout", "1", "-period-seconds", "10", "-failure-threshold", "1"]
              image: harbor.intra.com/tekton-trigger/webhook:v0.21.0
              
    root@k8s-master-01:/apps/trigger# grep image interceptors.yaml 
              image: harbor.intra.com/tekton-trigger/interceptors:v0.21.0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    部署

    root@k8s-master-01:/apps/trigger# kubectl apply -f release.yaml 
    root@k8s-master-01:/apps/trigger# kubectl apply -f interceptors.yaml 
    root@k8s-master-01:/apps/trigger# kubectl get pods -n tekton-pipelines 
    NAME                                                 READY   STATUS    RESTARTS         AGE
    tekton-dashboard-55654dbf76-gntt6                    1/1     Running   16 (4d21h ago)   16d
    tekton-pipelines-controller-856774dc6b-vls7d         1/1     Running   0                4d21h
    tekton-pipelines-webhook-7b8876dd96-ph264            1/1     Running   14 (4d21h ago)   16d
    tekton-triggers-controller-75b7bb5cd6-c9qtx          1/1     Running   0                6m49s
    tekton-triggers-core-interceptors-68ddcdd79b-nscp5   1/1     Running   0                2m
    tekton-triggers-webhook-84c6ff6db9-94jb8             1/1     Running   0                6m49s
    root@k8s-master-01:/apps/trigger# kubectl api-resources --api-group=triggers.tekton.dev
    NAME                     SHORTNAMES   APIVERSION                     NAMESPACED   KIND
    clusterinterceptors      ci           triggers.tekton.dev/v1alpha1   false        ClusterInterceptor
    clustertriggerbindings   ctb          triggers.tekton.dev/v1beta1    false        ClusterTriggerBinding
    eventlisteners           el           triggers.tekton.dev/v1beta1    true         EventListener
    triggerbindings          tb           triggers.tekton.dev/v1beta1    true         TriggerBinding
    triggers                 tri          triggers.tekton.dev/v1beta1    true         Trigger
    triggertemplates         tt           triggers.tekton.dev/v1beta1    true         TriggerTemplate
    root@k8s-master-01:/apps/trigger# kubectl get ClusterInterceptor
    NAME        AGE
    bitbucket   6m12s
    cel         6m12s
    github      6m12s
    gitlab      6m11s
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    2.2 Trigger配置

    2.2.1 secret

    webhookToken可以用命令重新生成

    apiVersion: v1
    kind: Secret
    metadata:
      name: gitlab-webhook-token
    type: Opaque
    stringData:
      # Generated by command "openssl rand -base64 12"
      webhookToken: "c1gGXLEa3pMBekVL"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.2.2 RBAC

    访问Trigger及相关资源的权限

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: tekton-triggers-gitlab-sa
    secrets:
    - name: gitlab-webhook-token
    ---
    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: tekton-triggers-gitlab-minimal
    rules:
      # Permissions for every EventListener deployment to function
      - apiGroups: ["triggers.tekton.dev"]
        resources: ["eventlisteners", "triggerbindings", "triggertemplates"]
        verbs: ["get"]
      - 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
    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-minimal
    rules:
      - apiGroups: ["triggers.tekton.dev"]
        resources: ["clusterinterceptors"]
        verbs: ["get", "list"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: tekton-triggers-gitlab-binding
    subjects:
      - kind: ServiceAccount
        name: tekton-triggers-gitlab-sa
        namespace: default
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: tekton-triggers-gitlab-minimal
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    2.2.3 Binding

    apiVersion: triggers.tekton.dev/v1beta1
    kind: TriggerBinding
    metadata:
      name: gitlab-push-binding
    spec:
      params:
      - name: git-revision
        value: $(body.checkout_sha)
      - name: git-repo-url
        value: $(body.repository.git_http_url)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.2.4 Trigger-Template

    这里绑定了TaskRun,那么就会去根据配置的TaskRun进行调用.如果配置了pipelinerun那么就可以进行流水线的调用.

    apiVersion: triggers.tekton.dev/v1beta1
    kind: TriggerTemplate
    metadata:
      name: gitlab-trigger-template
    spec:
      params:  # 定义参数
      - name: git-revision
      - name: git-repo-url
      resourcetemplates:
      - apiVersion: tekton.dev/v1beta1
        kind: TaskRun
        metadata:
          generateName: gitlab-trigger-run-  # TaskRun 名称前缀
        spec:
          serviceAccountName: tekton-triggers-gitlab-sa
          params:
            - name: git-revision
              value: $(tt.params.git-revision)
            - name: git-repo-url
              value: $(tt.params.git-repo-url)
          workspaces:
            - name: source
              emptyDir: {}
          taskSpec:
            workspaces:
              - name: source
            params:
              - name: git-revision
              - name: git-repo-url
            steps:
              - name: fetch-from-git-repo
                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)
              - name: list-files
                image: alpine:3.16
                script: ls -la $(workspaces.source.path)/source
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    2.2.5 EventListener

    apiVersion: triggers.tekton.dev/v1beta1
    kind: EventListener
    metadata:
      name: gitlab-event-listener
    spec:
      serviceAccountName: tekton-triggers-gitlab-sa
      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"]
        bindings:
        - ref: gitlab-push-binding
        template:
          ref: gitlab-trigger-template
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    部署Tekton Trigger

    kubectl apply -f .
    
    • 1

    3.2 Gitlab配置

    2.2.1 Gitlab仓库配置

    确保允许web hooks,如果是集群内的pods允许西钩子向本地网络发送请求.

    请添加图片描述

    确保可以http访问

    请添加图片描述

    默认创建仓库可见性是公开

    请添加图片描述

    gitlab仓库准备好了

    http://192.168.31.199/root/spring-boot-helloWorld.git

    2.2.2 Service配置

    不知道为啥没法直接改el-gitlab-event-listener这个service.于是另外做了个el-gitlab-event-listener-nodeport以Nodeport跑

    # kubectl get svc
    NAME                                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                         AGE
    ehelp-service                       NodePort    10.200.22.255    <none>        8080:30040/TCP                  6d23h
    el-gitlab-event-listener            ClusterIP   10.200.22.2      <none>        8080/TCP,9000/TCP               60m
    el-gitlab-event-listener-nodeport   NodePort    10.200.84.202    <none>        8080:30088/TCP,9000:30089/TCP   4s
    kubernetes                          ClusterIP   10.200.0.1       <none>        443/TCP                         195d
    tomcat-service                      NodePort    10.200.103.146   <none>        80:31080/TCP                    66d
    root@k8s-master-01:/apps/tekton-and-argocd-in-practise/05-tekton-triggers/02-trigger-gitlab# kubectl get endpoints
    NAME                                ENDPOINTS                                                     AGE
    ehelp-service                       <none>                                                        6d23h
    el-gitlab-event-listener            172.100.109.88:8080,172.100.109.88:9000                       62m
    el-gitlab-event-listener-nodeport   172.100.109.88:9000,172.100.109.88:8080                       72s
    kubernetes                          192.168.31.101:6443,192.168.31.102:6443,192.168.31.103:6443   195d
    tomcat-service                      <none>                                                        66d
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.2.3 Webhook配置

    请添加图片描述

    请添加图片描述

    验证push webhook

    请添加图片描述

    此时Tekton的TaskRun就被触发了

    请添加图片描述

    这样这个TaskRun就被执行了.

    先进行了克隆,再把文件清单打印

    请添加图片描述

    3. GitLab+PipelineRun

    3.1 webhookToken

    直接拿前面示例的token过来用,工作中可以再生成一个

    apiVersion: v1
    kind: Secret
    metadata:
      name: gitlab-webhook-token
    type: Opaque
    stringData:
      # Generated by command "openssl rand -base64 12"
      webhookToken: "c1gGXLEa3pMBekVL"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.2 RBAC Trigger

    用来访问Trigger相关组件和服务

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: tekton-triggers-gitlab-sa
    secrets:
    - name: gitlab-webhook-token
    ---
    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: tekton-triggers-gitlab-minimal
    rules:
      # Permissions for every EventListener deployment to function
      - apiGroups: ["triggers.tekton.dev"]
        resources: ["eventlisteners", "triggerbindings", "triggertemplates"]
        verbs: ["get"]
      - 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
    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-minimal
    rules:
      - apiGroups: ["triggers.tekton.dev"]
        resources: ["clusterinterceptors"]
        verbs: ["get", "list"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: tekton-triggers-gitlab-binding
    subjects:
      - kind: ServiceAccount
        name: tekton-triggers-gitlab-sa
        namespace: default
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: tekton-triggers-gitlab-minimal
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    3.3 RBAC deploy

    给部署deployment的权限

    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: helloworld-admin
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: helloworld-admin
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: cluster-admin
    subjects:
    - kind: ServiceAccount
      name: helloworld-admin
      namespace: default
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3.4 PVC配置

    给maven准备一个pvc这样就不用每次重新下载插件了

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: maven-cache
    spec:
      accessModes:
      - ReadWriteMany
      resources:
        requests:
          storage: 5Gi
      storageClassName: nfs-csi
      volumeMode: Filesystem
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3.5 Task配置

    将pipeline中所有的task都放在一个文件中.实现从git克隆,maven构建,tag号获取,镜像构建上传到最终使用kubectl部署应用

    ---
    apiVersion: tekton.dev/v1beta1
    kind: Task
    metadata:
      name: git-clone
    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/v1beta1
    kind: Task
    metadata:
      name: build-to-package
    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/v1beta1
    kind: Task
    metadata:
      name: generate-build-id
    spec:
      params:
        - name: 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.version)-${buildDatetime}
            echo -n ${buildId} | tee $(results.buildId.path)
    ---
    apiVersion: tekton.dev/v1beta1
    kind: Task
    metadata:
      name: image-build-and-push
    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: harbor.intra.com/kaniko/executor:debug
          securityContext:
            runAsUser: 0
          env:
            - name: DOCKER_CONFIG
              value: /kaniko/.docker
          command:
            - /kaniko/executor
          args:
            - --dockerfile=$(params.dockerfile)
            - --context=$(workspaces.source.path)/source
            - --destination=$(params.image-url):$(params.image-tag)
    ---
    apiVersion: tekton.dev/v1beta1
    kind: Task
    metadata:
      name: deploy-using-kubectl
    spec:
      workspaces:
        - name: source
          description: The git repo
      params:
        - name: deploy-config-file
          description: The path to the yaml file to deploy within the git source
        - name: image-url
          description: Image name including repository
        - name: image-tag
          description: Image tag
      steps:
        - name: update-yaml
          image: alpine:3.16
          command: ["sed"]
          args:
            - "-i"
            - "-e"
            - "s@__IMAGE__@$(params.image-url):$(params.image-tag)@g"
            - "$(workspaces.source.path)/source/deploy/$(params.deploy-config-file)"
        - name: run-kubectl
          image: lachlanevenson/k8s-kubectl
          command: ["kubectl"]
          args:
            - "apply"
            - "-f"
            - "$(workspaces.source.path)/source/deploy/$(params.deploy-config-file)"
    ---
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140

    3.6 Pipeline

    通过pipeline params实现将参数传递给tasks

    kind: Pipeline
    metadata:
      name: source-to-image
    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: version
          description: The version of the application
          type: string
          default: "v0.9" 
        - name: deploy-config-file
          description: The path to the yaml file to deploy within the git source
          default: all-in-one.yaml
      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: version
              value: "$(params.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
        - name: deploy-to-cluster
          taskRef:
            name: deploy-using-kubectl
          workspaces:
            - name: source
              workspace: codebase
          params:
            - name: deploy-config-file
              value: $(params.deploy-config-file)
            - name: image-url
              value: $(params.image-url)
            - name: image-tag
              value: "$(tasks.generate-build-id.results.buildId)"
          runAfter:
            - image-build-and-push
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    3.7 TriggerBinding

    这里定义了一些params的值.

    - git-revision通过EventListener获取
    - git-repo-rul通过EventListener获取
    - image-url手工指定
    - version手工指定,其实也可以直接用我们之前生成的id
    
    • 1
    • 2
    • 3
    • 4
    apiVersion: triggers.tekton.dev/v1beta1
    kind: TriggerBinding
    metadata:
      name: s2i-binding
    spec:
      params:
      - name: git-revision
        value: $(body.checkout_sha)
      - name: git-repo-url
        value: $(body.repository.git_http_url)
      - name: image-url
        value: kurtqiu1979/spring
      - name: version
        value: v0.9
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3.8 TriggerTemplate

    这里和上一个示例的区别就是将Taskrun改为了PipelineRun

    apiVersion: triggers.tekton.dev/v1beta1
    kind: TriggerTemplate
    metadata:
      name: s2i-tt
    spec:
      params:  # 定义参数
      - name: git-revision
      - name: git-repo-url
      - name: image-url
      - name: version
      resourcetemplates:
      - apiVersion: tekton.dev/v1beta1
        kind: PipelineRun
        metadata:
          generateName: s2i-trigger-run-  # TaskRun 名称前缀
        spec:
          serviceAccountName: default
          pipelineRef:
            name: source-to-image
          taskRunSpecs:
            - pipelineTaskName: deploy-to-cluster
              taskServiceAccountName: helloworld-admin
          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: version
              value: $(tt.params.version)
          workspaces:
            - name: codebase
              volumeClaimTemplate:
                spec:
                  accessModes:
                    - ReadWriteOnce
                  resources:
                    requests:
                      storage: 1Gi
                  storageClassName: nfs-csi
            - name: docker-config
              secret:
                secretName: docker-config
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    3.9 部署测试push events

    # kubectl apply -f .
    secret/gitlab-webhook-token configured
    serviceaccount/tekton-triggers-gitlab-sa configured
    role.rbac.authorization.k8s.io/tekton-triggers-gitlab-minimal unchanged
    rolebinding.rbac.authorization.k8s.io/tekton-triggers-gitlab-binding unchanged
    clusterrole.rbac.authorization.k8s.io/tekton-triggers-gitlab-minimal unchanged
    clusterrolebinding.rbac.authorization.k8s.io/tekton-triggers-gitlab-binding unchanged
    serviceaccount/helloworld-admin unchanged
    clusterrolebinding.rbac.authorization.k8s.io/helloworld-admin unchanged
    persistentvolumeclaim/maven-cache configured
    task.tekton.dev/git-clone configured
    task.tekton.dev/build-to-package configured
    task.tekton.dev/generate-build-id configured
    task.tekton.dev/image-build-and-push configured
    task.tekton.dev/deploy-using-kubectl configured
    pipeline.tekton.dev/source-to-image configured
    triggerbinding.triggers.tekton.dev/s2i-binding created
    triggertemplate.triggers.tekton.dev/s2i-tt created
    eventlistener.triggers.tekton.dev/s2i-listener created
    # kubectl get pods 
    NAME                                                      READY   STATUS              RESTARTS        AGE
    ehelp-7f6b554776-v4ph4                                    0/1     ContainerCreating   0               5d3h
    el-gitlab-event-listener-75497dbb79-2mgjf                 1/1     Running             3 (3h24m ago)   4h16m
    el-s2i-listener-7c78cc48c-5jzmg                           1/1     Running             0               41s
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    同样,配置下nodeport的svc

    root@k8s-master-01:~# kubectl get svc
    NAME                                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                         AGE
    ehelp-service                       NodePort    10.200.22.255    <none>        8080:30040/TCP                  7d2h
    el-gitlab-event-listener            ClusterIP   10.200.22.2      <none>        8080/TCP,9000/TCP               3h57m
    el-gitlab-event-listener-nodeport   NodePort    10.200.84.202    <none>        8080:30088/TCP,9000:30089/TCP   177m
    el-s2i-listener                     ClusterIP   10.200.138.9     <none>        8080/TCP,9000/TCP               13m
    kubernetes                          ClusterIP   10.200.0.1       <none>        443/TCP                         195d
    tomcat-service                      NodePort    10.200.103.146   <none>        80:31080/TCP                    67d
    root@k8s-master-01:~# kubectl get endpoints
    NAME                                ENDPOINTS                                                     AGE
    ehelp-service                       <none>                                                        7d2h
    el-gitlab-event-listener            172.100.109.88:8080,172.100.109.88:9000                       3h58m
    el-gitlab-event-listener-nodeport   172.100.109.94:9000,172.100.109.94:8080                       177m
    el-s2i-listener                     172.100.109.94:8080,172.100.109.94:9000                       13m
    kubernetes                          192.168.31.101:6443,192.168.31.102:6443,192.168.31.103:6443   195d
    tomcat-service                      <none>                                                        67d
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    这里我们NodePort设置和webhookToken的和之前配置一样.那么可以直接使用刚才的git仓库

    请添加图片描述
    请添加图片描述

    请添加图片描述

    请添加图片描述

    这里可以看到镜像就是我们刚才构建的.

    请添加图片描述

    3.10 测试合并分支

    3.10.1 克隆代码

    root@k8s-master-01:/opt# git clone http://192.168.31.199/root/spring-boot-helloWorld.git
    Cloning into 'spring-boot-helloWorld'...
    remote: Enumerating objects: 164, done.
    remote: Counting objects: 100% (164/164), done.
    remote: Compressing objects: 100% (87/87), done.
    remote: Total 164 (delta 47), reused 164 (delta 47), pack-reused 0
    Receiving objects: 100% (164/164), 24.16 KiB | 24.16 MiB/s, done.
    Resolving deltas: 100% (47/47), done.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.10.2 检出分支

    root@k8s-master-01:/opt/spring-boot-helloWorld# git checkout develop
    Branch 'develop' set up to track remote branch 'develop' from 'origin'.
    Switched to a new branch 'develop'
    # 随便修改一个文件,我这里将deploy/all-in-one.yaml的replicas: 1改为2
    root@k8s-master-01:/opt/spring-boot-helloWorld# git status
    On branch develop
    Your branch is up to date with 'origin/develop'.
    
    Untracked files:
      (use "git add ..." to include in what will be committed)
    
    	deploy/all-in-one.yaml
    
    nothing added to commit but untracked files present (use "git add" to track)
    
    root@k8s-master-01:/opt/spring-boot-helloWorld# git push origin develop
    Username for 'http://192.168.31.199': root
    Password for 'http://root@192.168.31.199': 
    Counting objects: 4, done.
    Delta compression using up to 2 threads.
    Compressing objects: 100% (4/4), done.
    Writing objects: 100% (4/4), 622 bytes | 622.00 KiB/s, done.
    Total 4 (delta 2), reused 0 (delta 0)
    remote: 
    remote: To create a merge request for develop, visit:
    remote:   http://192.168.31.199/root/spring-boot-helloWorld/-/merge_requests/new?merge_request%5Bsource_branch%5D=develop
    remote: 
    To http://192.168.31.199/root/spring-boot-helloWorld.git
       9ac49a1..9646e3d  develop -> develop
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    请添加图片描述

    请添加图片描述

    合并分支后pipelinerun被触发
    请添加图片描述

    此时deploy中的pod个数变成了2个

    root@k8s-master-01:~# kubectl get deploy -n hello
    NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
    spring-boot-helloworld   2/2     2            2           2d18h
    
    • 1
    • 2
    • 3

    至此,实现了从代码上传通过Trigger监听事件触发构建并实现自动发布.

    请添加图片描述

    请添加图片描述

  • 相关阅读:
    总结的HTTP比较详细的知识
    Python制作短信发送程序
    校内评奖评优|基于Springboot+Vue实现高校评优管理系统
    Claude 2,它有 GPT-4 一些无法超越的能力
    HTTP 报文详解
    202112-2 CCF 序列查询新解 (枚举 + 分段讨论 满分题解)
    java毕业设计——基于java+Socket+sqlserver的网络通信系统设计与实现(毕业论文+程序源码)——网络通信系统
    实现基于 GitLab 的数据库 CI/CD 最佳实践
    leetcode栈和队列三剑客
    【iptables 实战】06 iptables网络防火墙实验
  • 原文地址:https://blog.csdn.net/qq_29974229/article/details/127860735