zl程序教程

您现在的位置是:首页 >  后端

当前栏目

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

Kubernetes 实现 -- 系列 原生 持续 PUSH 交付
2023-09-14 09:15:20 时间

1. Tekton Trigger基础

Tekton Triggers简介

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

Tekton Triggers重要组件

- Trigger
- TriggerBinding
- TriggerTemplate
- EventListener
- Interceptor

定义一个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

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

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

事实上,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.5 EventListener

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

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

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

获取镜像

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

替换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"

替换后

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

部署

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

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"

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

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)

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

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

部署Tekton Trigger

kubectl apply -f .

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

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"

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

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

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

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

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

3.7 TriggerBinding

这里定义了一些params的值.

- git-revision通过EventListener获取
- git-repo-rul通过EventListener获取
- image-url手工指定
- version手工指定,其实也可以直接用我们之前生成的id
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

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

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

同样,配置下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

这里我们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.

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 <file>..." 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

请添加图片描述

请添加图片描述

合并分支后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

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

请添加图片描述

请添加图片描述