tekton

发布时间 2023-09-22 18:00:42作者: 要快乐不要emo

tekton

1、概念

1.1 组件

1.1.1 pipline

使用k8s crd 来定义一个基础组件块,用来组件cicd

1.1.2 trigger

触发器,根据事件来触发cicd

1.1.3 CLI

交互式命令,与tekton进行交互

1.1.4 dashboard

一个图形化的界面,显示cicd

1.1.5 catalog

cicd的一个仓库

1.1.6 hub

访问catalog的一个web界面

1.1.7 Operator

基于k8s的自定义控制器,控制tekton

1.1.8 chain

生成,存储和签名的工具,使用pipeline的组件
# 工作原理
Tekton Chains的工作原理是部署一个在后台运行并监视TaskRun的控制器。当Tekton Pipelines执行您的任务时,Tekton Chains会监视操作,一旦操作成功完成,Chains控制器就会生成所生产工件的来源
记录了任务的输入:源存储库、分支、其他工件;以及输出:容器镜像、包等。这些信息作为元数据记录并签名。您可以将密钥存储在Kubernetes secrets中,或使用支持的密钥管理系统(GCP、AWS、Azure或Vault)对出处进行签名。然后,您可以将出处上传到指定的位置

1.2 使用

1.2.1 cli

1.2.2 kubectl cli

1.2.3 api

1.3 模型

image-20230919092416967

1.3.1 step

# 步骤
pipeline中的每一步操作称之为步骤

1.3.2 task

# 任务
按顺序执行的一些列步骤的集合,task的执行依赖于pod

1.3.3 pipelines

按顺序执行的task的集合,定义了如何执行

1.3.4 taskrun

可以自定义task的运行方式时间

1.3.5 pipelinerun

同taskrun,定义了执行所需要的参数及所用的sectet等类似于模版与实例的关系

1.4 工作原理

通过对step容器注入一个二进制文件来执行我们预定的命令
使用Kubernetes Annotations跟踪cicd的状态。这些注释通过Kubernetes Downward API以文件的形式投影在每个step容器中。二进制文件密切监视投射的文件,并且只有在特定注释显示为文件时才会启动所提供的命令。
例如,当您要求Tekton在一个任务中连续运行两个步骤时,注入到第二个步骤容器中的二进制文件将空闲等待,直到注释报告第一个步骤容器已成功完成
Tekton Pipelines安排一些容器在步骤容器前后自动运行,以支持特定的内置功能,例如检索输入资源和将输出上传到blob存储解决方案。您还可以通过taskRuns和pipelineRuns跟踪它们的运行状态。在运行步骤容器之前,系统还执行许多其他操作来设置环境

2、安装

镜像配置

本节使用镜像可以使用或到docker hub仓库搜索
docker pull anjia0532/tekton-releases.github.com.tektoncd.$产品.cmd.$产品:v0.39.0
docker pull anjia0532/tekton-releases.github.com.tektoncd.dashboard.cmd.dashboard:v0.39.0

2.1 pipeline

2.1.1 安装

# 下载yaml
curl -Lfs -o tektoncd-pipeline.yaml https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
# 下载镜像并将其上传到自己的docker仓库
# 替换镜像为自己的docker仓库
sed -ir 's#gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/#quanheng.com/k8s/#g' *.yamls
# 安装
kubectl apply -f xx.yaml

2.1.2 task测试

# 运行task
---
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  name: hello-task-run
spec:
  taskRef:
    name: hello
apiVersion: tekton.dev/v1beta1
# 定义一个task
---
kind: Task
metadata:
  name: hello
spec:
  steps:
    - name: echo
      image: quanheng.com/k8s/alpine:v2
      script: |
        #!/bin/sh
        echo "Hello World"
# 查看pod和taskrun
(base) gu@python:~/k8s/yaml/tekton/task$ kubectl get pod 
NAME                                      READY   STATUS      RESTARTS       AGE
hello-task-run-pod                        0/1     Completed   0              2m17s
nfs-client-provisioner-5967bfdf67-nmbx2   1/1     Running     24 (23m ago)   3d17h
(base) gu@python:~/k8s/yaml/tekton/task$ kubectl get taskruns.tekton.dev 
NAME             SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
hello-task-run   True        Succeeded   5m25s       2m24s
(base) gu@python:~/k8s/tekton/pipeline-main/yaml$ kubectl logs hello-task-run-pod 
Defaulted container "step-echo" out of: step-echo, prepare (init), place-scripts (init)
Hello World

2.1.3 pipeline测试

2.1.3.1 安装cli

# 下载cli包
https://github.com/tektoncd/cli
# 解压并安装
unzip cli && cd cli && make amd64
# 做软连接
ln -sv /home/gu/k8s/tekton/cli-main/bin/tkn-linux-amd64 /usr/bin/tkn
# 将其作为kubectl plugin
ln -sv /home/gu/k8s/tekton/cli-main/bin/tkn-linux-amd64 /usr/bin/kubectl-tkn

2.1.3.2 测试

# 创建第二个task
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: goodbye
spec:
  params: # 指定必须传入一个字符串变量名称为username
  - name: username
    type: string
  steps:
    - name: goodbye
      image: quanheng.com/k8s/ubuntu:2
      script: |
        #!/bin/bash
        echo "Goodbye $(params.username)!"
# 创建pipeline
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: hello-goodbye
spec:
  params: # 指定必须传入一个字符串变量名称为username
  - name: username
    type: string
  tasks:
    - name: hello
      taskRef:
        name: hello
    - name: goodbye
      runAfter:
        - hello
      taskRef:
        name: goodbye
      params:
      - name: username
        value: $(params.username)
# 创建pipelinerun
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  name: hello-goodbye-run
spec:
  pipelineRef:
    name: hello-goodbye
  params: #传入变量
  - name: username
    value: "Tekton"
# 验证
(base) gu@python:~/k8s/yaml/tekton/pipelines$ tkn pipelinerun logs hello-goodbye-run -f -n default
[hello : echo] Hello World

[goodbye : goodbye] Goodbye Tekton!

2.2 trigger

2.2.1 安装

# 下载
curl -LO https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yaml
curl -LO https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
# 替换文件镜像
sed -ir 's#gcr.io/tekton-releases/github.com/tektoncd/triggers/cmd/#quanheng.com/k8s/#g' *.yamls
# 安装
kubectl apply -f release.yaml
kubectl apply -f interceptors.yaml

2.2.2 工作模型

image-20230919143500180

# Event Listener
一个等待事件发生的监听器
    # Trigger Template(k8s API)
    当配置的事件发生时创建一个pipelinerun
    # Trigger Binding
    将数据传递给template,然后根据给定参数创建pipelinerun
    
# Cluster Interceptor
可以添加一个可选对象来验证和处理事件数据
# 在一个pod中运行一个可以创建pipelinerun的模版对象,当监听的事件发生时触发创建事件将数据传递给模版来创建pipelinerun

2.2.3 测试

# 创建一个template
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
  name: hello-template
spec:
  params: # 传递一个变量
  - name: username
    default: "Kubernetes"
  resourcetemplates: # 资源模版
  - apiVersion: tekton.dev/v1beta1
    kind: PipelineRun # 创建一个pipelinerun
    metadata:
      generateName: hello-goodbye-run-
    spec:
      pipelineRef: # 引用哪个pipeline
        name: hello-goodbye
      params: # 使用变量
      - name: username
        value: $(tt.params.username) # tt=TriggerTemplate
# 创建binding(模版使用的数据)
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
  name: hello-binding
spec: 
  params: 
  - name: username
    value: $(body.username) # 接收到的变化,将其传递给template
# 创建一个事件监听器
apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
  name: hello-listener
spec:
  serviceAccountName: tekton-robot # 指定sa
  triggers: # 指定binding数据和模版template
    - name: hello-trigger 
      bindings: 
      - ref: hello-binding
      template:
        ref: hello-template
# 定义使用的sa
apiVersion: v1
kind: ServiceAccount
metadata:
  name: tekton-robot
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: triggers-example-eventlistener-binding
subjects:
- kind: ServiceAccount
  name: tekton-robot
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: tekton-triggers-eventlistener-roles
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: triggers-example-eventlistener-clusterbinding
subjects:
- kind: ServiceAccount
  name: tekton-robot
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: tekton-triggers-eventlistener-clusterroles
# 运行触发器
kubectl apply -f ./
# 提交一个有效负载
curl -v -H 'content-Type: application/json' -d '{"username": "guquanheng"}'  10.173.200.93:8080
{"eventListener":"hello-listener","namespace":"default","eventListenerUID":"30e562fd-d1c5-4980-a9e6-7872937cec0f","eventID":"85380be6-def2-4527-b150-cbad2e80aec8"}
# 查看触发的负载
(base) gu@python:~/k8s/yaml/tekton/trigger$ kubectl get pipelineruns
NAME                      SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
hello-goodbye-run         True        Succeeded   63m         62m
hello-goodbye-run-v25g4   True        Succeeded   2m20s       2m5s
# 检查管道运行日志。名称是自动生成的
(base) gu@python:~/k8s/yaml/tekton/trigger$ tkn pipelinerun logs hello-goodbye-run-v25g4
[hello : echo] Hello World

[goodbye : goodbye] Goodbye guquanheng!

2.3 dashboard

2.3.1 安装

# 下载安装文件
curl -LO https://storage.googleapis.com/tekton-releases/dashboard/latest/release-full.yaml
# 更改镜像为自己镜像
sed -ir 's#gcr.io/tekton-releases/github.com/tektoncd/triggers/cmd/#quanheng.com/k8s/#g' *.yamls
# 使用istio进行服务暴露
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: tekton-dashboard-vs
  namespace: tekton-pipelines
spec:
  gateways:
    - istio-system/kiali-gateway 
  hosts:
    - '*'
  http:
    - match:
        - port: 18686
      route:
        - destination:
            host: tekton-dashboard
            port:
              number: 9097

2.3.2 测试

image-20230919160523866

image-20230919160615279

3、使用

3.1 从git仓库拉取代码

# 创建一个pipeline
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: clone-read
spec:
  description: | 
    This pipeline clones a git repo, then echoes the README file to the stout.
  params:   # 添加一个参数来表示git仓库
  - name: repo-url
    type: string
    description: The git repo URL to clone from.
  workspaces: # 添加一个工作区用来存储代码
  - name: shared-data
    description: | 
      This workspace contains the cloned repo files, so they can be read by the next task.
  - name: git-credentials # 存储ssh秘钥
    description: My ssh credentials
  tasks: # 使用上述参数来定义一个task
  - name: fetch-source # colne 仓库
    taskRef:
      name: git-clone
    workspaces:
    - name: output
      workspace: shared-data
    - name: ssh-directory
      workspace: git-credentials
    params:
    - name: url
      value: $(params.repo-url)
  - name: show-readme # clone后查看README.md
    runAfter: ["fetch-source"] # 定义在clone后执行
    taskRef: # 引用哪个task
      name: show-readme
    workspaces: # 使用哪个工作区
    - name: source
      workspace: shared-data
---
# 创建一个pipelinerun(实例化上面pipeline定义的参数)
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  generateName: clone-read-run-
spec:
  pipelineRef:
    name: clone-read
  podTemplate:
    securityContext:
      fsGroup: 65532
  workspaces: # 实例化工作区,使用一个pvc来存储代码,
  - name: shared-data
    volumeClaimTemplate:
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi
        storageClassName: nfs # 指定一个类来实现pvc
  - name: git-credentials # 指定git仓库的secret
    secret:
      secretName: git-credentials
  params:  # 设置git仓库url
  - name: repo-url
    value: git@172.31.3.155:guquanheng/argo.git
# 创建一个secret用来访问git私有仓库
# config格式
Host 172.31.3.155
  Hostname 172.31.3.155
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/id_rsa
---
apiVersion: v1
kind: Secret
metadata:
  name: git-credentials
type: kubernetes.io/ssh-auth
data:
  id_rsa:  LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUJsd0FBQUFkemMyZ3RjbgpOaEFBQUFBd0VBQVFBQUFZRUFuQ21mazNYOFhseVJZaFNZdExGM2U3cWkwS1M5dlJEaTY1d1Y3QUovSzFnWFlDOHZyK2RzCjg3ZDVndU5YdFcrQndkbzJCNjRTVjZINW9XdFhlS0FNakRadU12am1lcW9UZndVa2c1U2kvRzN4c28wNlhYalhiTUJqYjkKVkMwdzA5NllwbUJNWjFqNDBhSUFHRGFub3N0eWdkUWRjeHpCVCt5NnFuSFIwLzJ4MmplL1N3NkpkOE5DYzVkZERCa1R5SQpHcTJRb2x0ZlVqNG5yUUlhRzVGVGl1STZqMW1JN0llL2JERGZKbzNrY1U1dUtTanVNVjB0d0lhNzhsM2V5UDhveFcvSG5aCmZNdHhka2ZRakMrdTkzdnJtWGhMdW84bFQ2NC9XOVlrLzhHOGdtS25vS3AyTC9jbmIrZFNnZkZ3OEZ6eEZTSjM5dWdRSTMKdWdwR0I1SVZTeDV1SmQwZEJqZmJ5SkdIaGEwU0ZHL21FbTdGa0E1cFBGVGxOTFZjMG9XQm50OG5WanozbGxKUUVTTlNQMgpPb0tlSUhpa0RPUnN5Y3F0eUdJK3cwVFJLUDh0YWpLdWZKUjZVWlRFRktyVVZYSUg3bnE5L3huTUxyeFI3ZHVpQjVkbWY4CjhqdVpxc2NHaEdlL0NqY1VaeE4vd29HR2kxQXV0N0w5US85NXBab25BQUFGZ0F3T2tCY01EcEFYQUFBQUIzTnphQzF5YzIKRUFBQUdCQUp3cG41TjEvRjVja1dJVW1MU3hkM3U2b3RDa3ZiMFE0dXVjRmV3Q2Z5dFlGMkF2TDYvbmJQTzNlWUxqVjdWdgpnY0hhTmdldUVsZWgrYUZyVjNpZ0RJdzJiakw0NW5xcUUzOEZKSU9Vb3Z4dDhiS05PbDE0MTJ6QVkyL1ZRdE1OUGVtS1pnClRHZFkrTkdpQUJnMnA2TExjb0hVSFhNY3dVL3N1cXB4MGRQOXNkbzN2MHNPaVhmRFFuT1hYUXdaRThpQnF0a0tKYlgxSSsKSjYwQ0dodVJVNHJpT285WmlPeUh2Mnd3M3lhTjVIRk9iaWtvN2pGZExjQ0d1L0pkM3NqL0tNVnZ4NTJYekxjWFpIMEl3dgpydmQ3NjVsNFM3cVBKVSt1UDF2V0pQL0J2SUppcDZDcWRpLzNKMi9uVW9IeGNQQmM4UlVpZC9ib0VDTjdvS1JnZVNGVXNlCmJpWGRIUVkzMjhpUmg0V3RFaFJ2NWhKdXhaQU9hVHhVNVRTMVhOS0ZnWjdmSjFZODk1WlNVQkVqVWo5anFDbmlCNHBBemsKYk1uS3JjaGlQc05FMFNqL0xXb3lybnlVZWxHVXhCU3ExRlZ5Qis1NnZmOFp6QzY4VWUzYm9nZVhabi9QSTdtYXJIQm9Sbgp2d28zRkdjVGY4S0Job3RRTHJleS9VUC9lYVdhSndBQUFBTUJBQUVBQUFHQU94QVhGYnV6SnJGV0gwVncrQzZDNVY0U2hGCjA2a2c2WDlNckZFODFoOGEvUXI0VkpRUHVEbnE0UEhDMEdHRTVEUW1GWXZCRGZTUnV2QVpsS3JRbkRsU2hsQjR4U0I2VFoKMk5uR0ZLb2I5dU5TWGRqQ2NXWHAvR3pMYnhtMnU0SXZuMnZENkJ4empFYXUwZG9nclIzbVdhT25aU2FSNUFFdzJURURJYQpUVmFQZE54TzBvRitCcmpvSWpYbWNGUHZ3bzhnWWhSUGJRRjVnQWc1UGU4ZnhHSDZvdXdkYjRUWldPRmNwcUsvZlFwZlltCi9oUkgrbzJtWjBIT1JmMnc3RTVzc3FJZHFIRE4wVGgvbW5LTEc1MEVBRUsraGVJTmloMWxNaU4xR0ZNZFpDZTBXQ1ZpNEwKWXdlWTAyZ1E1a29FYXV3TXM5RTlTcHVuTTk5QXFPL3lwQmw5a3FyT0M4NHRSejZSbzYyOUF1aUVjbkhXQ1JXMUI5MDA5SgpQamZDT0JYdTBmL1hEcnhaSzRlNVdkZ0tWM2VPRlFXTC9jK2tBYjNVWkRYRFBmMWlsL05ETWpsYUlKYWpVVWhrOTl3dUcyCi9lblhXQ2NFdkNoS0ZqN096NWwya2F0NHVmU2ZtbjAremhOWklzMUhXT0E1KzRzSkN4dkxPNWcvdVRGampZQzY3UkFBQUEKd1FDSmdNUXp4QjBvUTE2NGZObS9MRzVaV3dBb3FTb3hnSDI2d05xUXQxY3phQ2VDSmQwNExlaDViMUxTQzRIQTBxSjV4aAp4RDZ3ZVk3K2pEUSt1N1dXSEFhMmM2MWh1ZGFjSFByTEVnRFRZRHBBNnhxZnF5ZTdhVVFIckpYWkEwUWU3RHpYd2FCeGkwClhMc21Xd1NUTVRySXpqbjZuU0hWaFI1bGJwRkJCNDFEUkdEZDkrc2d4Ni9FR2Q1dkE1T3FKcWs2bGpnQThPRlM1VXFYQW8Kc1FTbTJEbWlQQTBKL21uSTNYdEozdkpjcElKQ3BnODNLWHFDUm9EQTYzTWMxS1ZOQUFBQURCQU5YTmpxTnA5QXFGRWZGWQplTGVaSVNYTEJNZ0JtaTkzYXB3Tm1BVDUySkI0eWN5RnlRSm53dlRYR0NtbURFb0V6R2xISTlVVDUwUzhlVkgxWmlqS25TCnZZVEsyODQ0U3MrdFRCRkdFaGFoVXkrdXhhci9veUJCSHhHS1VsMGc1RVEyK0tnVnROZ3drUFViMWM1dkxtbnNWdVEwbVYKUGtRb2sramgrbi9uZ25IY2J0VjZ2MnpuYlg1NXppMVkrZnhRUjRKNXZCa0VVMlFnRXpLWlBwQWxKdTFzeVdHS1dhMjNyQQpLdVI1ZVpBbmswMjhjdFpNQmwrc0Zza092UGFuMGNid0FBQU1FQXV2dkdDcVhBY2NLOTdTY0QxYmJ6UjlHSWVad0tSdkRICjRaeVMxL1ZtUXA3ZThnVGZ1VVowQWFGREpyTS9rTjJvbXNNYmk0RnE5Mi9JN1lqYmc4R0YxaTlxQUpYYzZPR0RPdjVMMEQKVHJEVXd3aVgwYUpDbGVSMlBES3R6Yy9ValRHdDAwV3lMdVZKZlVMdVBIbXV1WG1sajNIK2M2cjlKL25LUXk0bXlHd1ExWAp0QlI5RW55Z1BaYll1YWtlV0tIcmpHdUZqWnYxVFlmVklUN2IrMGdjRnVwV1o5c25GT3V3aU1aSGpONEVIbW43ak1OMFR5Cmo1YW1ieUF2RHhLNm5KQUFBQUNXZDFRSEI1ZEdodmJnRT0KLS0tLS1FTkQgT1BFTlNTSCBQUklWQVRFIEtFWS0tLS0tCg==
  known_hosts: CnwxfFlESjAzUVJhNVVZS3dFbUYvZ0FOTjl5YWxTZz18NC9XVzQxRTAwa3BwN2JXbmJrbWo3U2xYRTVFPSBzc2gtZWQyNTUxOSBBQUFBQzNOemFDMWxaREkxTlRFNUFBQUFJTG9sRlcrU3RIdkQ4MGhEQldyS3hKWXdlL2h0MGE5Qnppa1FuYVJhUGZqWQp8MXxtK1NrOXBkK1p0K3QrK2NlRU4raFBMY0N6aUU9fDZWUHVMVVgxZDRsNGNvbktvN1dlL0IzazVFbz0gZWNkc2Etc2hhMi1uaXN0cDI1NiBBQUFBRTJWalpITmhMWE5vWVRJdGJtbHpkSEF5TlRZQUFBQUlibWx6ZEhBeU5UWUFBQUJCQkZxcU82S3MyWmR2K0tXNGNMc0p1bEQ0QmpsajFDdnNScmtmanNqQkkrQkZXWDd4THpCZVNJM0pFT1BPYjFjbHlrUmRKMW1Gekt0a0JRNHBDTGRidVRJPQp8MXw0dW12TDAzeEZmL1c5Z1pNV3RXQTVVZGJ6dDg9fG1CLzUydVNUVnArdWNsQ2RvanFpMXpwRWMzMD0gc3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUxvbEZXK1N0SHZEODBoREJXckt4Sll3ZS9odDBhOUJ6aWtRbmFSYVBmalkKfDF8L3ZMUThVOEx3MW11aXg5ODhlZ0U4VGFtYkVBPXxtWE9ZYXJiVXg5UEI2RDl3RGFpVWVRWkRkYWc9IHNzaC1lZDI1NTE5IEFBQUFDM056YUMxbFpESTFOVEU1QUFBQUlQc0I4aTgvcmxkamUweUtpSEZvTTQ1bEk5RUhWUkdBUU4zSDN2YjFSTUcvCnwxfGFOcnV5UXB4T1FKSk9reVZ1eG9DOWkxVVdVbz18c2ZPZFhwc0FWZ3ZWeXJTWHBXdnIrNHpnRVdnPSBlY2RzYS1zaGEyLW5pc3RwMjU2IEFBQUFFMlZqWkhOaExYTm9ZVEl0Ym1semRIQXlOVFlBQUFBSWJtbHpkSEF5TlRZQUFBQkJCTDg1RFNoaW0wUUFZZ0Jockw3UFYzaDFNa3dCaU42SnpVa3laQndWZGs3aWRRb3pLZHRDdlV0Q0U1SWZvY28zNDY2RERRZHBraGplVjgzMXhQWjFFSEk9CnwxfFpUeG1OVkE1WTczd3dxTDFnS2VMRTY0UUFZbz18SlFWeXpSaDYyaXdNSDBDUzZlbkJTSHVXL3BvPSBzc2gtZWQyNTUxOSBBQUFBQzNOemFDMWxaREkxTlRFNUFBQUFJUHNCOGk4L3JsZGplMHlLaUhGb000NWxJOUVIVlJHQVFOM0gzdmIxUk1HLwp8MXxDZlJsTjM3MWtwSVlOdmIxeTJoWkhtZFNSeWs9fHhGTjdMRGh1QVJUZkZvZjZTMzVJRjI5cUpmTT0gc3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUxvbEZXK1N0SHZEODBoREJXckt4Sll3ZS9odDBhOUJ6aWtRbmFSYVBmalkKfDF8bzgveUFOSHVQYis5UG1qeGpxcllkWFlYOEFzPXx5R2FpbTZFa1ZnNVNtb1psektRS1FhYnluazQ9IHNzaC1lZDI1NTE5IEFBQUFDM056YUMxbFpESTFOVEU1QUFBQUlMb2xGVytTdEh2RDgwaERCV3JLeEpZd2UvaHQwYTlCemlrUW5hUmFQZmpZCnwxfFkvMmFHa0ZuYU5aaEMwVExMcnRnRGVOZEo3cz18MWxVcUJSdkZuYm85NFRBSUhFeTRrMitQYjJVPSBzc2gtZWQyNTUxOSBBQUFBQzNOemFDMWxaREkxTlRFNUFBQUFJSDZ0V2NzYkdTa0tBS2kvdzJQUWlSdmRJc3BxNThMU0ZmQVdsSGhEYSt2NQp8MXxWeU9oMGEvYnUrN3h0blk0MndEbS81ZUQxYkU9fGh4UDdIMW5tSXFvdWh1REVjajgwUkFmZVVEQT0gZWNkc2Etc2hhMi1uaXN0cDI1NiBBQUFBRTJWalpITmhMWE5vWVRJdGJtbHpkSEF5TlRZQUFBQUlibWx6ZEhBeU5UWUFBQUJCQkhEdVBuRERRcyt1QzNOTVdJTU4yT1cyWHo1KzljK2l4dWhSK1JQZkZCaFYzVWMxYnB0TnJZTk5JSGFXbFBQcTVHWXFaU09jekdxVnlwMGVDNGhMdzlBPQo=
  config: SG9zdCAxNzIuMzEuMy4xNTUKICBIb3N0bmFtZSAxNzIuMzEuMy4xNTUKICBQcmVmZXJyZWRBdXRoZW50aWNhdGlvbnMgcHVibGlja2V5CiAgSWRlbnRpdHlGaWxlIH4vLnNzaC9pZF9yc2EK
# 创建一个task
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: show-readme
spec:
  description: Read and display README file.
  workspaces:
  - name: source
  steps:
  - name: read
    image: alpine:latest
    script: | 
      #!/usr/bin/env sh
      cat $(workspaces.source.path)/README.md
# 查看结果 
(base) gu@python:~/k8s/yaml/tekton/use/gitpull$ tkn pipelinerun logs  clone-read-run-xr2hn -f
[fetch-source : clone] + '[' false '=' true ]
[fetch-source : clone] + '[' true '=' true ]
[fetch-source : clone] + cp -R /workspace/ssh-directory /home/git/.ssh
[fetch-source : clone] + chmod 700 /home/git/.ssh
[fetch-source : clone] + chmod -R 400 /home/git/.ssh/config /home/git/.ssh/id_rsa /home/git/.ssh/known_hosts
[fetch-source : clone] + '[' false '=' true ]
[fetch-source : clone] + CHECKOUT_DIR=/workspace/output/
[fetch-source : clone] + '[' true '=' true ]
[fetch-source : clone] + cleandir
[fetch-source : clone] + '[' -d /workspace/output/ ]
[fetch-source : clone] + rm -rf '/workspace/output//*'
[fetch-source : clone] + rm -rf '/workspace/output//.[!.]*'
[fetch-source : clone] + rm -rf '/workspace/output//..?*'
[fetch-source : clone] + test -z 
[fetch-source : clone] + test -z 
[fetch-source : clone] + test -z 
[fetch-source : clone] + git config --global --add safe.directory /workspace/output
[fetch-source : clone] + /ko-app/git-init '-url=git@172.31.3.155:guquanheng/argo.git' '-revision=' '-refspec=' '-path=/workspace/output/' '-sslVerify=true' '-submodules=true' '-depth=1' '-sparseCheckoutDirectories='
[fetch-source : clone] {"level":"warn","ts":1695180336.8236978,"caller":"git/git.go:271","msg":"URL(\"git@172.31.3.155:guquanheng/argo.git\") appears to need SSH authentication but no SSH credentials have been provided"}
[fetch-source : clone] {"level":"info","ts":1695180338.4686594,"caller":"git/git.go:176","msg":"Successfully cloned git@172.31.3.155:guquanheng/argo.git @ b66baa6c468d7ca3eff27e72e3820e4a7ff0926f (grafted, HEAD) in path /workspace/output/"}
[fetch-source : clone] {"level":"info","ts":1695180338.5491166,"caller":"git/git.go:215","msg":"Successfully initialized and updated submodules in path /workspace/output/"}
[fetch-source : clone] + cd /workspace/output/
[fetch-source : clone] + git rev-parse HEAD
[fetch-source : clone] + RESULT_SHA=b66baa6c468d7ca3eff27e72e3820e4a7ff0926f
[fetch-source : clone] + EXIT_CODE=0
[fetch-source : clone] + '[' 0 '!=' 0 ]
[fetch-source : clone] + git log -1 '--pretty=%ct'
[fetch-source : clone] + RESULT_COMMITTER_DATE=1695180275
[fetch-source : clone] + printf '%s' 1695180275
[fetch-source : clone] + printf '%s' b66baa6c468d7ca3eff27e72e3820e4a7ff0926f
[fetch-source : clone] + printf '%s' git@172.31.3.155:guquanheng/argo.git

[show-readme : read] this is test pipeline

3.2 创建并上传镜像到仓库

# kaniko使用教程 
https://juejin.cn/post/7217665415710081081#heading-31
# 创建一个task用来实现对镜像的打包及上传
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: kaniko
  labels:
    app.kubernetes.io/version: "0.6"
  annotations:
    tekton.dev/pipelines.minVersion: "0.17.0"
    tekton.dev/categories: Image Build
    tekton.dev/tags: image-build
    tekton.dev/displayName: "Build and upload container image using Kaniko"
    tekton.dev/platforms: "linux/amd64,linux/arm64,linux/ppc64le"
spec:
  description: >-
    This Task builds a simple Dockerfile with kaniko and pushes to a registry.
    This Task stores the image name and digest as results, allowing Tekton Chains to pick up
    that an image was built & sign it.
  params:
    - name: IMAGE
      description: Name (reference) of the image to build.
    - name: DOCKERFILE
      description: Path to the Dockerfile to build.
      default: ./Dockerfile
    - name: CONTEXT
      description: The build context used by Kaniko.
      default: ./
    - name: EXTRA_ARGS
      type: array
      default: []
    - name: BUILDER_IMAGE
      description: The image on which builds will run (default is v1.5.1)
      #default: quanheng.com/k8s/executor:v1.5.2
      # 注意,此处无法对私有仓库进行解析,需要提前下载好镜像后docker load进去或者使用公网地址进行下载
      default: registry.cn-hangzhou.aliyuncs.com/weiyigeek/kaniko-executor:latest
  workspaces:
    - name: source
      description: Holds the context and Dockerfile
    - name: docker-credentials
      description: Includes a docker `config.json`
      optional: true
      mountPath: /kaniko/.docker
  results:
    - name: IMAGE_DIGEST
      description: Digest of the image just built.
    - name: IMAGE_URL
      description: URL of the image just built.
  steps:
    - name: build-and-push
      workingDir: $(workspaces.source.path)
      image: $(params.BUILDER_IMAGE)
      args:
        - $(params.EXTRA_ARGS)
        - --insecure # 使用http与仓库进行通信,使用私有仓库必须用此参数
        - --skip-tls-verify # push忽略tls认证
        - --skip-tls-verify-pull # pull忽略tls
        - --dockerfile=$(params.DOCKERFILE)
        - --context=$(workspaces.source.path)/$(params.CONTEXT) # The user does not need to care the workspace and the source.
        - --destination=$(params.IMAGE)
        - --digest-file=$(results.IMAGE_DIGEST.path)
      # kaniko assumes it is running as root, which means this example fails on platforms
      # that default to run containers as random uid (like OpenShift). Adding this securityContext
      # makes it explicit that it needs to run as root.
      securityContext:
        runAsUser: 0
      volumeMounts: # 依赖hosts解析需要将本地hosts挂载进pod
        - name: hosts
          mountPath: /etc/hosts
        - name: host
          mountPath: /workspace/source/hosts
    - name: write-url
      image: quanheng.com/k8s/bash:5.1.4
      script: |
        set -e
        image="$(params.IMAGE)"
        echo -n "${image}" | tee "$(results.IMAGE_URL.path)"
      volumeMounts:
        - name: hosts
          mountPath: /etc/hosts
  volumes:
    - name: hosts
      hostPath:
        path: /etc/hosts
    - name: host
      hostPath:
        path: /etc/hosts
# 创建一个pipeline
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: clone-build-push
spec:
  description: |
    This pipeline clones a git repo, builds a Docker image with Kaniko and
    pushes it to a registry    
  params:
  - name: repo-url
    type: string
  - name: image-reference
    type: string
  workspaces:
  - name: shared-data
  - name: docker-credentials
  - name: git-credentials
  tasks:
  - name: fetch-source
    taskRef:
      name: git-clone
    workspaces:
    - name: output
      workspace: shared-data
    - name: ssh-directory
      workspace: git-credentials
    params:
    - name: url
      value: $(params.repo-url)
  - name: build-push
    runAfter: ["fetch-source"]
    taskRef:
      name: kaniko
    workspaces:
    - name: source
      workspace: shared-data
    - name: docker-credentials
      workspace: docker-credentials
    params:
    - name: IMAGE
      value: $(params.image-reference)
# 创建pipelinerun
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  generateName: clone-build-push-run-
spec:
  pipelineRef:
    name: clone-build-push
  podTemplate:
    securityContext:
      fsGroup: 65532
  workspaces:
  - name: shared-data
    volumeClaimTemplate:
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi
        storageClassName: nfs
  - name: docker-credentials
    secret:
      secretName: docker-credentials
  - name: git-credentials # 指定git仓库的secret
    secret:
      secretName: git-credentials
  params:
  - name: repo-url
    value: git@172.31.3.155:guquanheng/tekton.git
  - name: image-reference
    value: quanheng.com/k8s/alpine:v7
# 验证结果
(base) gu@python:~/k8s/yaml/tekton/use/pushimage$ kubectl tkn pipelinerun logs  clone-build-push-run-k9pvs -f
[fetch-source : clone] + '[' false '=' true ]
[fetch-source : clone] + '[' true '=' true ]
[fetch-source : clone] + cp -R /workspace/ssh-directory /home/git/.ssh
[fetch-source : clone] + chmod 700 /home/git/.ssh
[fetch-source : clone] + chmod -R 400 /home/git/.ssh/config /home/git/.ssh/id_rsa /home/git/.ssh/known_hosts
[fetch-source : clone] + '[' false '=' true ]
[fetch-source : clone] + CHECKOUT_DIR=/workspace/output/
[fetch-source : clone] + '[' true '=' true ]
[fetch-source : clone] + cleandir
[fetch-source : clone] + '[' -d /workspace/output/ ]
[fetch-source : clone] + rm -rf '/workspace/output//*'
[fetch-source : clone] + rm -rf '/workspace/output//.[!.]*'
[fetch-source : clone] + rm -rf '/workspace/output//..?*'
[fetch-source : clone] + test -z 
[fetch-source : clone] + test -z 
[fetch-source : clone] + test -z 
[fetch-source : clone] + git config --global --add safe.directory /workspace/output
[fetch-source : clone] + /ko-app/git-init '-url=git@172.31.3.155:guquanheng/tekton.git' '-revision=' '-refspec=' '-path=/workspace/output/' '-sslVerify=true' '-submodules=true' '-depth=1' '-sparseCheckoutDirectories='
[fetch-source : clone] {"level":"warn","ts":1695362820.9618697,"caller":"git/git.go:271","msg":"URL(\"git@172.31.3.155:guquanheng/tekton.git\") appears to need SSH authentication but no SSH credentials have been provided"}
[fetch-source : clone] {"level":"info","ts":1695362822.768268,"caller":"git/git.go:176","msg":"Successfully cloned git@172.31.3.155:guquanheng/tekton.git @ c9c9a5c2506927e058508ffc659618c6bc4e6cb8 (grafted, HEAD) in path /workspace/output/"}
[fetch-source : clone] {"level":"info","ts":1695362822.8658404,"caller":"git/git.go:215","msg":"Successfully initialized and updated submodules in path /workspace/output/"}
[fetch-source : clone] + cd /workspace/output/
[fetch-source : clone] + git rev-parse HEAD
[fetch-source : clone] + RESULT_SHA=c9c9a5c2506927e058508ffc659618c6bc4e6cb8
[fetch-source : clone] + EXIT_CODE=0
[fetch-source : clone] + '[' 0 '!=' 0 ]
[fetch-source : clone] + git log -1 '--pretty=%ct'
[fetch-source : clone] + RESULT_COMMITTER_DATE=1695361527
[fetch-source : clone] + printf '%s' 1695361527
[fetch-source : clone] + printf '%s' c9c9a5c2506927e058508ffc659618c6bc4e6cb8
[fetch-source : clone] + printf '%s' git@172.31.3.155:guquanheng/tekton.git

[build-push : build-and-push] INFO[0000] Retrieving image manifest quanheng.com/k8s/ubuntu:2 
[build-push : build-and-push] INFO[0000] Retrieving image quanheng.com/k8s/ubuntu:2 from registry quanheng.com 
[build-push : build-and-push] INFO[0000] Built cross stage deps: map[]                
[build-push : build-and-push] INFO[0000] Retrieving image manifest quanheng.com/k8s/ubuntu:2 
[build-push : build-and-push] INFO[0000] Returning cached image manifest              
[build-push : build-and-push] INFO[0000] Executing 0 build triggers                   
[build-push : build-and-push] INFO[0000] Building stage 'quanheng.com/k8s/ubuntu:2' [idx: '0', base-idx: '-1'] 
[build-push : build-and-push] INFO[0000] Unpacking rootfs as cmd RUN echo hello requires it. 
[build-push : build-and-push] INFO[0007] RUN echo hello                               
[build-push : build-and-push] INFO[0007] Initializing snapshotter ...                 
[build-push : build-and-push] INFO[0007] Taking snapshot of full filesystem...        
[build-push : build-and-push] INFO[0009] Cmd: /bin/sh                                 
[build-push : build-and-push] INFO[0009] Args: [-c echo hello]                        
[build-push : build-and-push] INFO[0009] Running: [/bin/sh -c echo hello]             
[build-push : build-and-push] hello
[build-push : build-and-push] INFO[0009] Taking snapshot of full filesystem...        
[build-push : build-and-push] INFO[0009] No files were changed, appending empty layer to config. No layer added to image. 
[build-push : build-and-push] INFO[0009] CMD ["tail","-f","/etc/resolv.conf"]         
[build-push : build-and-push] INFO[0009] Pushing image to quanheng.com/k8s/ubuntu:3   
[build-push : build-and-push] INFO[0010] Pushed quanheng.com/k8s/ubuntu@sha256:8862a8d0ba6e6057a1d539554697fc4d075688b0ec124039f55d0e2b8417c25d 

[build-push : write-url] quanheng.com/k8s/ubuntu:3

4、API

4.1 crd

https://tekton.dev/docs/pipelines/pipeline-api/

5、设置

5.1 控制器设置

# 指定controller镜像运行的参数,在controller的deployment里进行配置
spec:
  serviceAccountName: tekton-pipelines-controller
  containers:
    - name: tekton-pipelines-controller
      image: ko://github.com/tektoncd/pipeline/cmd/controller
      args: [
          "-kube-api-qps", "50", # qps数量
          "-kube-api-burst", "50", # 
          "-threads-per-controller", "32", # 每个控制器要创建的线程
          # other flags defined here...
        ]

5.2 控制器高可用

# 更改副本数
# 配置数据副本
路径 pipeline-main/config/resolvers
data.buckets	1 # 数据分桶
data.leaseDuration	15 # 租赁
data.renewDeadline	10 # 续订
data.retryPeriod	2 # 重试 
# 设置hpa和pdb(控制人为干预情况下pod的最少可使用数量)

5.3 task

https://tekton.dev/docs/pipelines/tasks/

5.4 taskrun