tekton
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 模型
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、安装
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 工作模型
# 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 测试
3、使用
3.1 从git仓库拉取代码
# 安装git-clone task
apiVersion: tekton.dev/v1
kind: Task
metadata:
annotations:
tekton.dev/categories: Git
tekton.dev/displayName: git clone
tekton.dev/pipelines.minVersion: 0.38.0
tekton.dev/platforms: linux/amd64,linux/s390x,linux/ppc64le,linux/arm64
tekton.dev/tags: git
creationTimestamp: "2023-09-19T09:39:27Z"
generation: 1
labels:
app.kubernetes.io/version: "0.9"
hub.tekton.dev/catalog: tekton
name: git-clone
namespace: default
resourceVersion: "6936599"
uid: 7760d316-306a-4ffe-aa90-7f4e2160f951
spec:
description: |-
These Tasks are Git tasks to work with repositories used by other tasks in your Pipeline.
The git-clone Task will clone a repo from the provided url into the output Workspace. By default the repo will be cloned into the root of your Workspace. You can clone into a subdirectory by setting this Task's subdirectory param. This Task also supports sparse checkouts. To perform a sparse checkout, pass a list of comma separated directory patterns to this Task's sparseCheckoutDirectories param.
params:
- description: Repository URL to clone from.
name: url
type: string
- default: ""
description: Revision to checkout. (branch, tag, sha, ref, etc...)
name: revision
type: string
- default: ""
description: Refspec to fetch before checking out revision.
name: refspec
type: string
- default: "true"
description: Initialize and fetch git submodules.
name: submodules
type: string
- default: "1"
description: Perform a shallow clone, fetching only the most recent N commits.
name: depth
type: string
- default: "true"
description: Set the `http.sslVerify` global git config. Setting this to `false`
is not advised unless you are sure that you trust your git remote.
name: sslVerify
type: string
- default: ca-bundle.crt
description: file name of mounted crt using ssl-ca-directory workspace. default
value is ca-bundle.crt.
name: crtFileName
type: string
- default: ""
description: Subdirectory inside the `output` Workspace to clone the repo into.
name: subdirectory
type: string
- default: ""
description: Define the directory patterns to match or exclude when performing
a sparse checkout.
name: sparseCheckoutDirectories
type: string
- default: "true"
description: Clean out the contents of the destination directory if it already
exists before cloning.
name: deleteExisting
type: string
- default: ""
description: HTTP proxy server for non-SSL requests.
name: httpProxy
type: string
- default: ""
description: HTTPS proxy server for SSL requests.
name: httpsProxy
type: string
- default: ""
description: Opt out of proxying HTTP/HTTPS requests.
name: noProxy
type: string
- default: "true"
description: Log the commands that are executed during `git-clone`'s operation.
name: verbose
type: string
- default: gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.40.2
description: The image providing the git-init binary that this Task runs.
name: gitInitImage
type: string
- default: /home/git
description: |
Absolute path to the user's home directory.
name: userHome
type: string
results:
- description: The precise commit SHA that was fetched by this Task.
name: commit
type: string
- description: The precise URL that was fetched by this Task.
name: url
type: string
- description: The epoch timestamp of the commit that was fetched by this Task.
name: committer-date
type: string
steps:
- computeResources: {}
env:
- name: HOME
value: $(params.userHome)
- name: PARAM_URL
value: $(params.url)
- name: PARAM_REVISION
value: $(params.revision)
- name: PARAM_REFSPEC
value: $(params.refspec)
- name: PARAM_SUBMODULES
value: $(params.submodules)
- name: PARAM_DEPTH
value: $(params.depth)
- name: PARAM_SSL_VERIFY
value: $(params.sslVerify)
- name: PARAM_CRT_FILENAME
value: $(params.crtFileName)
- name: PARAM_SUBDIRECTORY
value: $(params.subdirectory)
- name: PARAM_DELETE_EXISTING
value: $(params.deleteExisting)
- name: PARAM_HTTP_PROXY
value: $(params.httpProxy)
- name: PARAM_HTTPS_PROXY
value: $(params.httpsProxy)
- name: PARAM_NO_PROXY
value: $(params.noProxy)
- name: PARAM_VERBOSE
value: $(params.verbose)
- name: PARAM_SPARSE_CHECKOUT_DIRECTORIES
value: $(params.sparseCheckoutDirectories)
- name: PARAM_USER_HOME
value: $(params.userHome)
- name: WORKSPACE_OUTPUT_PATH
value: $(workspaces.output.path)
- name: WORKSPACE_SSH_DIRECTORY_BOUND
value: $(workspaces.ssh-directory.bound)
- name: WORKSPACE_SSH_DIRECTORY_PATH
value: $(workspaces.ssh-directory.path)
- name: WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND
value: $(workspaces.basic-auth.bound)
- name: WORKSPACE_BASIC_AUTH_DIRECTORY_PATH
value: $(workspaces.basic-auth.path)
- name: WORKSPACE_SSL_CA_DIRECTORY_BOUND
value: $(workspaces.ssl-ca-directory.bound)
- name: WORKSPACE_SSL_CA_DIRECTORY_PATH
value: $(workspaces.ssl-ca-directory.path)
image: $(params.gitInitImage)
name: clone
script: |
#!/usr/bin/env sh
set -eu
if [ "${PARAM_VERBOSE}" = "true" ] ; then
set -x
fi
if [ "${WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND}" = "true" ] ; then
cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.git-credentials" "${PARAM_USER_HOME}/.git-credentials"
cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.gitconfig" "${PARAM_USER_HOME}/.gitconfig"
chmod 400 "${PARAM_USER_HOME}/.git-credentials"
chmod 400 "${PARAM_USER_HOME}/.gitconfig"
fi
if [ "${WORKSPACE_SSH_DIRECTORY_BOUND}" = "true" ] ; then
cp -R "${WORKSPACE_SSH_DIRECTORY_PATH}" "${PARAM_USER_HOME}"/.ssh
chmod 700 "${PARAM_USER_HOME}"/.ssh
chmod -R 400 "${PARAM_USER_HOME}"/.ssh/*
fi
if [ "${WORKSPACE_SSL_CA_DIRECTORY_BOUND}" = "true" ] ; then
export GIT_SSL_CAPATH="${WORKSPACE_SSL_CA_DIRECTORY_PATH}"
if [ "${PARAM_CRT_FILENAME}" != "" ] ; then
export GIT_SSL_CAINFO="${WORKSPACE_SSL_CA_DIRECTORY_PATH}/${PARAM_CRT_FILENAME}"
fi
fi
CHECKOUT_DIR="${WORKSPACE_OUTPUT_PATH}/${PARAM_SUBDIRECTORY}"
cleandir() {
# Delete any existing contents of the repo directory if it exists.
#
# We don't just "rm -rf ${CHECKOUT_DIR}" because ${CHECKOUT_DIR} might be "/"
# or the root of a mounted volume.
if [ -d "${CHECKOUT_DIR}" ] ; then
# Delete non-hidden files and directories
rm -rf "${CHECKOUT_DIR:?}"/*
# Delete files and directories starting with . but excluding ..
rm -rf "${CHECKOUT_DIR}"/.[!.]*
# Delete files and directories starting with .. plus any other character
rm -rf "${CHECKOUT_DIR}"/..?*
fi
}
if [ "${PARAM_DELETE_EXISTING}" = "true" ] ; then
cleandir || true
fi
test -z "${PARAM_HTTP_PROXY}" || export HTTP_PROXY="${PARAM_HTTP_PROXY}"
test -z "${PARAM_HTTPS_PROXY}" || export HTTPS_PROXY="${PARAM_HTTPS_PROXY}"
test -z "${PARAM_NO_PROXY}" || export NO_PROXY="${PARAM_NO_PROXY}"
git config --global --add safe.directory "${WORKSPACE_OUTPUT_PATH}"
/ko-app/git-init \
-url="${PARAM_URL}" \
-revision="${PARAM_REVISION}" \
-refspec="${PARAM_REFSPEC}" \
-path="${CHECKOUT_DIR}" \
-sslVerify="${PARAM_SSL_VERIFY}" \
-submodules="${PARAM_SUBMODULES}" \
-depth="${PARAM_DEPTH}" \
-sparseCheckoutDirectories="${PARAM_SPARSE_CHECKOUT_DIRECTORIES}"
cd "${CHECKOUT_DIR}"
RESULT_SHA="$(git rev-parse HEAD)"
EXIT_CODE="$?"
if [ "${EXIT_CODE}" != 0 ] ; then
exit "${EXIT_CODE}"
fi
RESULT_COMMITTER_DATE="$(git log -1 --pretty=%ct)"
printf "%s" "${RESULT_COMMITTER_DATE}" > "$(results.committer-date.path)"
printf "%s" "${RESULT_SHA}" > "$(results.commit.path)"
printf "%s" "${PARAM_URL}" > "$(results.url.path)"
securityContext:
runAsNonRoot: true
runAsUser: 65532
workspaces:
- description: The git repo will be cloned onto the volume backing this Workspace.
name: output
- description: |
A .ssh directory with private key, known_hosts, config, etc. Copied to
the user's home before git commands are executed. Used to authenticate
with the git remote when performing the clone. Binding a Secret to this
Workspace is strongly recommended over other volume types.
name: ssh-directory
optional: true
- description: |
A Workspace containing a .gitconfig and .git-credentials file. These
will be copied to the user's home before any git commands are run. Any
other files in this Workspace are ignored. It is strongly recommended
to use ssh-directory over basic-auth whenever possible and to bind a
Secret to this Workspace over other volume types.
name: basic-auth
optional: true
- description: |
A workspace containing CA certificates, this will be used by Git to
verify the peer with when fetching or pushing over HTTPS.
name: ssl-ca-directory
optional: true
---
# 创建一个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、核心资源
4.1 crd
https://tekton.dev/docs/pipelines/pipeline-api/
4.2 task
# 详细配置
https://tekton.dev/docs/pipelines/tasks/
必要:
apiVersion api版本
kind 资源类型
metadata 元数据信息
spec 配置信息
steps 所要执行task的容器的信息
可选:
description 为所有field添加描述信息
params 参数
workspaces 所要使用的volume
results 将执行结果写入指定的路径
volumes 挂载在指定的task时使用的卷
stepTemplate 为所有step设置一个基本配置
sidecars 指定一个边车容器
4.3 taskrun
# 详细配置
https://tekton.dev/docs/pipelines/taskruns
必要:
apiVersion API 版本
kind 资源类型
metadata 元数据信息
spec 配置信息
# 选择要执行的task来源
- taskRef # 指定一个已定义的task
- taskSpec # 重新配置一个task
可选:
serviceAccountName 指定一个sa来对taskrun进行授权
params 指定参数
timeout 指定运行多久不成功后返回失败
podTemplate 将用于所有要执行task的pod的配置,比如卷挂载,指定运行的用户id等
env 在 Pod 模板中定义的环境变量优先于 和TaskRunPipelineRunstepsstepTemplate
nodeSelector 必须为 true,Pod 才能适应节点。
tolerations 允许(但不要求)Pod 调度到具有匹配污点的节点上。
affinity 允许约束节点集,可以根据节点上存在的标签来调度 Pod。
securityContext 指定容器级安全属性和常见容器设置,例如 和 。runAsUserselinux
volumes 指定 Pod 中的容器可以挂载的卷列表。这允许您为 .volumeMountTask
runtimeClassName 指定 Pod 的运行时类。
automountServiceAccountToken 默认值:。确定 Tekton 是否以预定义的路径自动为 Pod 在容器内使用的服务帐户提供令牌。true
dnsPolicy 默认值:。指定容器的 DNS 策略。合法值为 、 和 。不支持,因为 Tekton Pod 无法与主机网络一起运行。ClusterFirstClusterFirstDefaultNoneClusterFirstWithHostNet
dnsConfig 指定容器的其他 DNS 配置,例如名称服务器和搜索域。
enableServiceLinks 默认值:。确定 Pod 命名空间中的服务是否作为环境变量公开给 Pod,类似于 Docker 服务链接。true
priorityClassName 指定容器的优先级类。允许您有选择地在优先级较低的工作负载上启用抢占。
schedulerName 指定调度 Pod 时要使用的调度程序。您可以为不同类型的 工作负载,例如机器学习工作负载。volcano.sh
imagePullSecrets 指定拉取容器映像时要使用的机密。
hostNetwork 默认值:。确定是否使用主机网络命名空间。false
hostAliases 将条目添加到 Pod 的“/etc/hosts”中,以提供 Pod 级别的主机名覆盖。有关更多信息,请参阅 [此字段的 Kubernetes 文档](https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/)。
topologySpreadConstraints 指定 Pod 在拓扑域中跨集群的分布方式。
Workspaces 定义要使用的卷
4.4 pipeline
必要:
apiVersion api版本
kind 资源类型
metadata 元数据信息
spec 配置信息
tasks 要执行的tasks
可选:
params 参数
workspaces 要使用的卷
tasks: # 里面是一个列表
- name 名称
displayName 面向用户的名称
description 定义的资源描述信息
taskRef 指定一个已定义的task
taskSpec 新建一个task
runAfter 指定task运行顺序,可以是一个列表,多个不同task可以定义相同目标(使其并行执行)
retries 重试次数
when 指定一个条件当满足条件时执行task
timeout 指定超时时间
params 指定参数
workspaces 指定使用的workspaces
matrix
results 指定一个执行结果要保存的位置
displayName 面向用户的名称
description 针对定义资源的描述
finally 当所有其他任务完成后要执行的task 是一个列表。配置同tasks
4.5 pipelinerun
必要:
apiVersion api版本
kind 资源类型
metadata 元数据信息
spec 配置信息
pipelineRef 使用已定义的pipeline
pipelineSpec 新定义一个pipeline
可选:
params 参数
serviceAccountName sa授权
status
必要:
status 对PipelineRun状态的最新观察结果
startTime 开始时间
completionTime 完成时间
pipelineSpec
可选:
pipelineResults 执行结果输出到文件
skippedTasks 跳过执行的task
childReferences taskrun或者task引用列表包含下面字段
kind 资源类型
apiVersion api版本
whenExpressions when表达式
provenance 有关运行时配置和 PipelineRun 中使用的资源的元数据
RefSource: 来源
FeatureFlags: 映射的配置数据
finallyStartTime 最终任务的开始时间
taskRunSpecs 定义taskrun
timeouts 指定失败前的超时
podTemplate 最终执行任务时,pod所使用的模版数据
workspaces 卷定义
4.6 CustomRun
必要:
apiVersion API 版本
kind 资源类型
metadata 元数据信息
spec 配置信息
customRef 指定一个自定义任务
customSpec 新建一个自定义任务
可选:
serviceAccountName 指定一个sa来对taskrun进行授权
params 指定参数
retries 指定重试次数
timeout 指定运行多久不成功后返回失败
Workspaces 定义要使用的卷
4.7 eventlist
# eventlist 具体表现为一个pod 使用binding和trigger来进行binding binding中存在触发器所需要的参数,trigger是一个生成tekton实例的模版,会根据传递来的参数进行pipeline的实例化
必要:
apiVersion api版本
kind 资源类型
metadata 元数据信息
spec 配置信息
serviceAccountName 指定sa授权
可选:
triggers 指定一个触发器,当检测到事件要执行的列表# 见4.8触发器配置
cloudEventURI
resources - 指定事件监听服务资源 # 可以使用k8s原生资源或者自定义资源
kubernetesResource
CustomResource
namespaceSelector 指定生成实例的ns # 指定el pod所处ns
labelSelector 指定实例化的标签选择 #
4.8 trigger
# 工作原理
定义一个触发器,触发器内部使用binding和template,拦截器用来处理外来数据然后传递给binding,再传递给template最后创建实例
拦截器是一个定义如何与后端eventslist pod通信的svc
apiVersion - 指定 API 版本;例如。triggers.tekton.dev/v1alpha1
kind - 指定此资源对象是一个对象。Trigger
metadata - 指定用于唯一标识此对象的元数据;例如 .Triggername
spec - 指定此触发器对象的配置信息,包括:
[bindings] - 指定一个列表
[template] - 指定一个模版
[interceptors] - 指定一个或者多个拦截器进行处理数据
name 名称
ref 引用拦截器
name 引用名称
kind 默认为cluster,可以指定namespace
apiVersion api版本
params 指定要传递给拦截器的参数
params 定义传递给拦截器参数的格式
[serviceAccountName] - (可选)指定要提供给 以实例化/执行目标资源。ServiceAccountEventListener
下面是一个示例定义:Trigger
---
apiVersion: triggers.tekton.dev/v1beta1
kind: Trigger
metadata:
name: trigger
spec:
interceptors:
- ref:
name: "cel"
params:
- name: "filter"
value: "header.match('X-GitHub-Event', 'pull_request')"
- name: "overlays"
value:
- key: extensions.truncated_sha
expression: "body.pull_request.head.sha.truncate(7)"
bindings:
- ref: pipeline-binding
template:
ref: pipeline-template
4.8.1 TriggerTemplate
# 用来实例化tekton对象的模版文件可以是 一般是pipelinerun
Pipeline
PipelineRun
Task
TaskRun
ClusterTask
4.8.2 TriggerBindings
# 从事件中提取信息传递给tt用来生成实例
内联绑定: 定义在tt中
tb定义: 定义在tb中
tb引用: 引用其他的
# 验证
安装工具
从github下载trigger
go build main.go
$ cat testdata/triggerbinding.yaml
apiVersion: tekton.dev/v1alpha1
kind: TriggerBinding
metadata:
name: pipeline-binding
spec:
params:
- name: foo
value: $(body.test)
- name: bar
value: $(header.X-Header)
$ cat testdata/http.txt
POST /foo HTTP/1.1
Content-Length: 16
Content-Type: application/json
X-Header: tacocat
{"test": "body"}
$ binding-eval -b testdata/triggerbinding.yaml -r testdata/http.txt
[
{
"name": "foo",
"value": "body"
},
{
"name": "bar",
"value": "tacocat"
}
]
4.9 Interceptor
4.9.1 clusterInterceptor
apiVersion API 版本
kind 资源类型
metadata 元数据信息
spec 配置信息
[clientConfig] 指定客户端与EventListener的通信方式
---
spec:
clientConfig:
caBundle: <cert data> # https
service:
name: "my-interceptor-svc"
namespace: "default"
path: "/optional-path" # optional
port: 8081 # defaults to 80
4.9.2 NamespacedInterceptor
配置同4.9.1 区别在于为ns级别
4.9.3 配置拦截器
4.9.3.1 格式
name 名称
ref 引用拦截器
name 引用名称
kind 默认为cluster,可以指定namespace
apiVersion api版本
params 指定要传递给拦截器的参数
params 定义传递给拦截器参数的格式
4.9.3.2 一般配置
---
interceptors:
- name: "validate GitHub payload and filter on eventType" 配置名称
ref: # 引用名称为github的拦截器
name: "github"
params: # 传递给github拦截器的参数
- name: "secretRef" # 参数名称
value: # 参数值
secretName: github-secret
secretKey: secretToken
- name: "eventTypes" # 参数名称
value: ["pull_request"] # 参数值
- name: "CEL filter: only when PRs are opened"
ref:
name: "cel"
params:
- name: "filter"
value: "body.action in ['opened', 'reopened']"
4.9.3.3 webhook拦截器
---
apiVersion: triggers.tekton.dev/v1alpha1
kind: EventListener
metadata:
name: listener-interceptor
spec:
serviceAccountName: tekton-triggers-example-sa
triggers:
- name: foo-trig
interceptors:
- webhook:
header:
- name: Foo-Trig-Header1
value: string-value
- name: Foo-Trig-Header2
value:
- array-val1
- array-val2
objectRef:
kind: Service
name: gh-validate
apiVersion: v1
namespace: default
bindings:
- ref: pipeline-binding
template:
ref: pipeline-template
4.9.3.4 gitlab拦截器
interceptors:
- ref:
name: "gitlab"
params:
- name: "secretRef"
value:
secretName: foo
secretKey: bar
- name: "eventTypes"
value: ["Push Hook"]
4.9.4 排错
# 查看el-listening日志
# 修改el实例日志格式为debug config-logging-triggers
loglevel.eventlistener": "info"
4.10 events
tekton EventListener 事件发生
# 事件格式
资源 事件 事件类型
EventListener Started dev.tekton.event.triggers.started.v1
EventListener Succeed dev.tekton.event.triggers.successful.v1
EventListener Done dev.tekton.event.triggers.done.v1
EventListener Failed dev.tekton.event.triggers.failed.v1
# 事件发生时间点
EventListener发出以下事件:
Started:收到请求时第一次发出。EventListener
Succeeded:当事件侦听器收到请求并处理所有触发器请求时发出。
Done:使用事件侦听器处理程序完成时发出。
Failed:如果触发器无法处理请求,则发出
5、设置
https://tekton.dev/docs/operator/
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的最少可使用数量)
6、身份认证
6.1 以非root身份使用
securityContext:
runAsNonRoot: true
runAsUser: 65532
6.2 为git配置身份认证
6.2.1 ssh认证
---
apiVersion: v1
kind: Secret
metadata:
name: git-credentials
type: kubernetes.io/ssh-auth
data:
id_rsa: # cat ~/.ssh/id_rsa|base64|tr -d '\n' LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUJsd0FBQUFkemMyZ3RjbgpOaEFBQUFBd0VBQVFBQUFZRUFuQ21mazNYOFhseVJZaFNZdExGM2U3cWkwS1M5dlJEaTY1d1Y3QUovSzFnWFlDOHZyK2RzCjg3ZDVndU5YdFcrQndkbzJCNjRTVjZINW9XdFhlS0FNakRadU12am1lcW9UZndVa2c1U2kvRzN4c28wNlhYalhiTUJqYjkKVkMwdzA5NllwbUJNWjFqNDBhSUFHRGFub3N0eWdkUWRjeHpCVCt5NnFuSFIwLzJ4MmplL1N3NkpkOE5DYzVkZERCa1R5SQpHcTJRb2x0ZlVqNG5yUUlhRzVGVGl1STZqMW1JN0llL2JERGZKbzNrY1U1dUtTanVNVjB0d0lhNzhsM2V5UDhveFcvSG5aCmZNdHhka2ZRakMrdTkzdnJtWGhMdW84bFQ2NC9XOVlrLzhHOGdtS25vS3AyTC9jbmIrZFNnZkZ3OEZ6eEZTSjM5dWdRSTMKdWdwR0I1SVZTeDV1SmQwZEJqZmJ5SkdIaGEwU0ZHL21FbTdGa0E1cFBGVGxOTFZjMG9XQm50OG5WanozbGxKUUVTTlNQMgpPb0tlSUhpa0RPUnN5Y3F0eUdJK3cwVFJLUDh0YWpLdWZKUjZVWlRFRktyVVZYSUg3bnE5L3huTUxyeFI3ZHVpQjVkbWY4CjhqdVpxc2NHaEdlL0NqY1VaeE4vd29HR2kxQXV0N0w5US85NXBab25BQUFGZ0F3T2tCY01EcEFYQUFBQUIzTnphQzF5YzIKRUFBQUdCQUp3cG41TjEvRjVja1dJVW1MU3hkM3U2b3RDa3ZiMFE0dXVjRmV3Q2Z5dFlGMkF2TDYvbmJQTzNlWUxqVjdWdgpnY0hhTmdldUVsZWgrYUZyVjNpZ0RJdzJiakw0NW5xcUUzOEZKSU9Vb3Z4dDhiS05PbDE0MTJ6QVkyL1ZRdE1OUGVtS1pnClRHZFkrTkdpQUJnMnA2TExjb0hVSFhNY3dVL3N1cXB4MGRQOXNkbzN2MHNPaVhmRFFuT1hYUXdaRThpQnF0a0tKYlgxSSsKSjYwQ0dodVJVNHJpT285WmlPeUh2Mnd3M3lhTjVIRk9iaWtvN2pGZExjQ0d1L0pkM3NqL0tNVnZ4NTJYekxjWFpIMEl3dgpydmQ3NjVsNFM3cVBKVSt1UDF2V0pQL0J2SUppcDZDcWRpLzNKMi9uVW9IeGNQQmM4UlVpZC9ib0VDTjdvS1JnZVNGVXNlCmJpWGRIUVkzMjhpUmg0V3RFaFJ2NWhKdXhaQU9hVHhVNVRTMVhOS0ZnWjdmSjFZODk1WlNVQkVqVWo5anFDbmlCNHBBemsKYk1uS3JjaGlQc05FMFNqL0xXb3lybnlVZWxHVXhCU3ExRlZ5Qis1NnZmOFp6QzY4VWUzYm9nZVhabi9QSTdtYXJIQm9Sbgp2d28zRkdjVGY4S0Job3RRTHJleS9VUC9lYVdhSndBQUFBTUJBQUVBQUFHQU94QVhGYnV6SnJGV0gwVncrQzZDNVY0U2hGCjA2a2c2WDlNckZFODFoOGEvUXI0VkpRUHVEbnE0UEhDMEdHRTVEUW1GWXZCRGZTUnV2QVpsS3JRbkRsU2hsQjR4U0I2VFoKMk5uR0ZLb2I5dU5TWGRqQ2NXWHAvR3pMYnhtMnU0SXZuMnZENkJ4empFYXUwZG9nclIzbVdhT25aU2FSNUFFdzJURURJYQpUVmFQZE54TzBvRitCcmpvSWpYbWNGUHZ3bzhnWWhSUGJRRjVnQWc1UGU4ZnhHSDZvdXdkYjRUWldPRmNwcUsvZlFwZlltCi9oUkgrbzJtWjBIT1JmMnc3RTVzc3FJZHFIRE4wVGgvbW5LTEc1MEVBRUsraGVJTmloMWxNaU4xR0ZNZFpDZTBXQ1ZpNEwKWXdlWTAyZ1E1a29FYXV3TXM5RTlTcHVuTTk5QXFPL3lwQmw5a3FyT0M4NHRSejZSbzYyOUF1aUVjbkhXQ1JXMUI5MDA5SgpQamZDT0JYdTBmL1hEcnhaSzRlNVdkZ0tWM2VPRlFXTC9jK2tBYjNVWkRYRFBmMWlsL05ETWpsYUlKYWpVVWhrOTl3dUcyCi9lblhXQ2NFdkNoS0ZqN096NWwya2F0NHVmU2ZtbjAremhOWklzMUhXT0E1KzRzSkN4dkxPNWcvdVRGampZQzY3UkFBQUEKd1FDSmdNUXp4QjBvUTE2NGZObS9MRzVaV3dBb3FTb3hnSDI2d05xUXQxY3phQ2VDSmQwNExlaDViMUxTQzRIQTBxSjV4aAp4RDZ3ZVk3K2pEUSt1N1dXSEFhMmM2MWh1ZGFjSFByTEVnRFRZRHBBNnhxZnF5ZTdhVVFIckpYWkEwUWU3RHpYd2FCeGkwClhMc21Xd1NUTVRySXpqbjZuU0hWaFI1bGJwRkJCNDFEUkdEZDkrc2d4Ni9FR2Q1dkE1T3FKcWs2bGpnQThPRlM1VXFYQW8Kc1FTbTJEbWlQQTBKL21uSTNYdEozdkpjcElKQ3BnODNLWHFDUm9EQTYzTWMxS1ZOQUFBQURCQU5YTmpxTnA5QXFGRWZGWQplTGVaSVNYTEJNZ0JtaTkzYXB3Tm1BVDUySkI0eWN5RnlRSm53dlRYR0NtbURFb0V6R2xISTlVVDUwUzhlVkgxWmlqS25TCnZZVEsyODQ0U3MrdFRCRkdFaGFoVXkrdXhhci9veUJCSHhHS1VsMGc1RVEyK0tnVnROZ3drUFViMWM1dkxtbnNWdVEwbVYKUGtRb2sramgrbi9uZ25IY2J0VjZ2MnpuYlg1NXppMVkrZnhRUjRKNXZCa0VVMlFnRXpLWlBwQWxKdTFzeVdHS1dhMjNyQQpLdVI1ZVpBbmswMjhjdFpNQmwrc0Zza092UGFuMGNid0FBQU1FQXV2dkdDcVhBY2NLOTdTY0QxYmJ6UjlHSWVad0tSdkRICjRaeVMxL1ZtUXA3ZThnVGZ1VVowQWFGREpyTS9rTjJvbXNNYmk0RnE5Mi9JN1lqYmc4R0YxaTlxQUpYYzZPR0RPdjVMMEQKVHJEVXd3aVgwYUpDbGVSMlBES3R6Yy9ValRHdDAwV3lMdVZKZlVMdVBIbXV1WG1sajNIK2M2cjlKL25LUXk0bXlHd1ExWAp0QlI5RW55Z1BaYll1YWtlV0tIcmpHdUZqWnYxVFlmVklUN2IrMGdjRnVwV1o5c25GT3V3aU1aSGpONEVIbW43ak1OMFR5Cmo1YW1ieUF2RHhLNm5KQUFBQUNXZDFRSEI1ZEdodmJnRT0KLS0tLS1FTkQgT1BFTlNTSCBQUklWQVRFIEtFWS0tLS0tCg==
known_hosts: # cat ~/.ssh/known_hosts|base64|tr -d '\n' CnwxfFlESjAzUVJhNVVZS3dFbUYvZ0FOTjl5YWxTZz18NC9XVzQxRTAwa3BwN2JXbmJrbWo3U2xYRTVFPSBzc2gtZWQyNTUxOSBBQUFBQzNOemFDMWxaREkxTlRFNUFBQUFJTG9sRlcrU3RIdkQ4MGhEQldyS3hKWXdlL2h0MGE5Qnppa1FuYVJhUGZqWQp8MXxtK1NrOXBkK1p0K3QrK2NlRU4raFBMY0N6aUU9fDZWUHVMVVgxZDRsNGNvbktvN1dlL0IzazVFbz0gZWNkc2Etc2hhMi1uaXN0cDI1NiBBQUFBRTJWalpITmhMWE5vWVRJdGJtbHpkSEF5TlRZQUFBQUlibWx6ZEhBeU5UWUFBQUJCQkZxcU82S3MyWmR2K0tXNGNMc0p1bEQ0QmpsajFDdnNScmtmanNqQkkrQkZXWDd4THpCZVNJM0pFT1BPYjFjbHlrUmRKMW1Gekt0a0JRNHBDTGRidVRJPQp8MXw0dW12TDAzeEZmL1c5Z1pNV3RXQTVVZGJ6dDg9fG1CLzUydVNUVnArdWNsQ2RvanFpMXpwRWMzMD0gc3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUxvbEZXK1N0SHZEODBoREJXckt4Sll3ZS9odDBhOUJ6aWtRbmFSYVBmalkKfDF8L3ZMUThVOEx3MW11aXg5ODhlZ0U4VGFtYkVBPXxtWE9ZYXJiVXg5UEI2RDl3RGFpVWVRWkRkYWc9IHNzaC1lZDI1NTE5IEFBQUFDM056YUMxbFpESTFOVEU1QUFBQUlQc0I4aTgvcmxkamUweUtpSEZvTTQ1bEk5RUhWUkdBUU4zSDN2YjFSTUcvCnwxfGFOcnV5UXB4T1FKSk9reVZ1eG9DOWkxVVdVbz18c2ZPZFhwc0FWZ3ZWeXJTWHBXdnIrNHpnRVdnPSBlY2RzYS1zaGEyLW5pc3RwMjU2IEFBQUFFMlZqWkhOaExYTm9ZVEl0Ym1semRIQXlOVFlBQUFBSWJtbHpkSEF5TlRZQUFBQkJCTDg1RFNoaW0wUUFZZ0Jockw3UFYzaDFNa3dCaU42SnpVa3laQndWZGs3aWRRb3pLZHRDdlV0Q0U1SWZvY28zNDY2RERRZHBraGplVjgzMXhQWjFFSEk9CnwxfFpUeG1OVkE1WTczd3dxTDFnS2VMRTY0UUFZbz18SlFWeXpSaDYyaXdNSDBDUzZlbkJTSHVXL3BvPSBzc2gtZWQyNTUxOSBBQUFBQzNOemFDMWxaREkxTlRFNUFBQUFJUHNCOGk4L3JsZGplMHlLaUhGb000NWxJOUVIVlJHQVFOM0gzdmIxUk1HLwp8MXxDZlJsTjM3MWtwSVlOdmIxeTJoWkhtZFNSeWs9fHhGTjdMRGh1QVJUZkZvZjZTMzVJRjI5cUpmTT0gc3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUxvbEZXK1N0SHZEODBoREJXckt4Sll3ZS9odDBhOUJ6aWtRbmFSYVBmalkKfDF8bzgveUFOSHVQYis5UG1qeGpxcllkWFlYOEFzPXx5R2FpbTZFa1ZnNVNtb1psektRS1FhYnluazQ9IHNzaC1lZDI1NTE5IEFBQUFDM056YUMxbFpESTFOVEU1QUFBQUlMb2xGVytTdEh2RDgwaERCV3JLeEpZd2UvaHQwYTlCemlrUW5hUmFQZmpZCnwxfFkvMmFHa0ZuYU5aaEMwVExMcnRnRGVOZEo3cz18MWxVcUJSdkZuYm85NFRBSUhFeTRrMitQYjJVPSBzc2gtZWQyNTUxOSBBQUFBQzNOemFDMWxaREkxTlRFNUFBQUFJSDZ0V2NzYkdTa0tBS2kvdzJQUWlSdmRJc3BxNThMU0ZmQVdsSGhEYSt2NQp8MXxWeU9oMGEvYnUrN3h0blk0MndEbS81ZUQxYkU9fGh4UDdIMW5tSXFvdWh1REVjajgwUkFmZVVEQT0gZWNkc2Etc2hhMi1uaXN0cDI1NiBBQUFBRTJWalpITmhMWE5vWVRJdGJtbHpkSEF5TlRZQUFBQUlibWx6ZEhBeU5UWUFBQUJCQkhEdVBuRERRcyt1QzNOTVdJTU4yT1cyWHo1KzljK2l4dWhSK1JQZkZCaFYzVWMxYnB0TnJZTk5JSGFXbFBQcTVHWXFaU09jekdxVnlwMGVDNGhMdzlBPQo=
config: SG9zdCAxNzIuMzEuMy4xNTUKICBIb3N0bmFtZSAxNzIuMzEuMy4xNTUKICBQcmVmZXJyZWRBdXRoZW50aWNhdGlvbnMgcHVibGlja2V5CiAgSWRlbnRpdHlGaWxlIH4vLnNzaC9pZF9yc2EK
---
# config文件生成
cat ~/.ssh/config
Host 172.31.3.155 # 固定格式
Hostname 172.31.3.155 # git服务器ip
PreferredAuthentications publickey # 固定格式
IdentityFile ~/.ssh/id_rsa # 指定私钥文件路径
6.2.2 账户密码认证
apiVersion: v1
kind: Secret
metadata:
name: basic-user-git
annotations:
tekton.dev/git-0: http://172.31.3.155:80 #git仓库地址 可以跟端口
type: kubernetes.io/basic-auth
stringData:
username: base64编码
password: base64编码
6.3 为docker仓库配置身份认证
apiVersion: v1
data: # cat ~/.docker/config|base64
.dockercfg: ewoJImF1dGhzIjogewoJCSIxNzIuMzEuMy4xNjYiOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2TVRJek5EVTIiCgkJfSwKCQkicXVhbmhlbmcuY29tIjogewoJCQkiYXV0aCI6ICJZV1J0YVc0Nk1USXpORFUyIgoJCX0KCX0KfQ==
kind: Secret
metadata:
name: secret-dockercfg
type: kubernetes.io/dockercfg
7、变量使用
8、测试项目
8.1 测试webhook
目的:查看webhook传递信息
8.1.1 生成triggerbinding
# gitlab-webhook格式
# header
X-Gitlab-Event: Push Hook
# body
{
"object_kind":"push",
"before":"95790bf891e76fee5e1747ab589903a6a1f80f22",
"after":"da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
"ref":"refs/heads/master",
"checkout_sha":"da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
"user_id":4,
"user_name":"John Smith",
"user_username":"jsmith",
"user_email":"john@example.com",
"user_avatar":"https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80",
"project_id":15,
"project":{
"id":15,
"name":"Diaspora",
"description":"",
"web_url":"http://example.com/mike/diaspora",
"avatar_url":null,
"git_ssh_url":"git@example.com:mike/diaspora.git",
"git_http_url":"http://example.com/mike/diaspora.git",
"namespace":"Mike",
"visibility_level":0,
"path_with_namespace":"mike/diaspora",
"default_branch":"master",
"homepage":"http://example.com/mike/diaspora",
"url":"git@example.com:mike/diaspora.git",
"ssh_url":"git@example.com:mike/diaspora.git",
"http_url":"http://example.com/mike/diaspora.git"
},
"repository":{
"name":"Diaspora",
"url":"git@example.com:mike/diaspora.git",
"description":"",
"homepage":"http://example.com/mike/diaspora",
"git_http_url":"http://example.com/mike/diaspora.git",
"git_ssh_url":"git@example.com:mike/diaspora.git",
"visibility_level":0
},
"commits":[
{
"id":"b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
"message":"Update Catalan translation to e38cb41.\n\nSee https://gitlab.com/gitlab-org/gitlab for more information",
"title":"Update Catalan translation to e38cb41.",
"timestamp":"2011-12-12T14:27:31+02:00",
"url":"http://example.com/mike/diaspora/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
"author":{
"name":"Jordi Mallach",
"email":"jordi@softcatala.org"
},
"added":[
"CHANGELOG"
],
"modified":[
"app/controller/application.rb"
],
"removed":[
]
},
{
"id":"da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
"message":"fixed readme",
"title":"fixed readme",
"timestamp":"2012-01-03T23:36:29+02:00",
"url":"http://example.com/mike/diaspora/commit/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
"author":{
"name":"GitLab dev user",
"email":"gitlabdev@dv6700.(none)"
},
"added":[
"CHANGELOG"
],
"modified":[
"app/controller/application.rb"
],
"removed":[
]
}
],
"total_commits_count":4
}
# 作用是当el触发时将参数传递给triggertemplate
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
name: test-binding
spec:
params:
- name: git-webhook
value: $(body.repository.git_http_url)
8.1.2 生成eventlister
apiVersion: triggers.tekton.dev/v1alpha1
kind: EventListener
metadata:
name: test-cicd-listener
spec:
serviceAccountName: tekton-robot
triggers:
- name: test-trigger
interceptors:
- gitlab:
eventTypes:
- Push Hook
bindings:
- ref: test-binding
template:
ref: test-template
resources:
kubernetesResource:
serviceType: NodePort
spec:
template:
spec:
nodeSelector:
disktype: ssd
8.1.3 生成triggertemplate
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
name: test-template
spec:
params:
- name: git-webhook
description: The git webhook
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: test-cicd
spec:
pipelineRef:
name: test-pipeline
params:
- name: git-webhook
value: $(tt.params.git-webhook)
8.1.4 生成pipline
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: test-pipeline
spec:
params:
- name: git-webhook
type: string
tasks:
- name: test-task
taskRef:
name: test-task
params:
- name: git-webhook
value: $(params.git-webhook)
8.1.5 生成task
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: test-task
spec:
params:
- name: git-webhook
type: string
default: "no any message"
steps:
- name: test-task
image: quanheng.com/k8s/ubuntu:2
script: |
#!/bin/bash
echo "$(params.git-webhook)!"
8.1.6 配置gitlab-webhook
(base) gu@python:~$ kubectl get el
NAME ADDRESS AVAILABLE REASON READY REASON
test-cicd-listener http://el-test-cicd-listener.default.svc.cluster.local:8080 True MinimumReplicasAvailable True
(base) gu@python:~$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
el-test-cicd-listener NodePort 10.173.217.133 <none> 8080:10918/TCP,9000:25230/TCP 114m
base) gu@python:~$ kubectl get pod -owide|grep el
el-test-cicd-listener-55df68c555-vm9pz 1/1 Running 0 108m 10.182.107.220 worker-03
8.2 利用tekton实现ci
目的:当上传代码后可以自动进行打包镜像并上传镜像仓库
8.2.1 生成task-拉取代码
apiVersion: tekton.dev/v1
kind: Task
metadata:
annotations:
tekton.dev/categories: Git
tekton.dev/displayName: git clone
tekton.dev/pipelines.minVersion: 0.38.0
tekton.dev/platforms: linux/amd64,linux/s390x,linux/ppc64le,linux/arm64
tekton.dev/tags: git
labels:
app.kubernetes.io/version: "0.9"
hub.tekton.dev/catalog: tekton
name: git-clone
namespace: default
spec:
# 定义所需的参数
params:
- description: git仓库地址
name: url
type: string
- default: ""
description: 修订信息,比如分支名或者tag等
name: revision
type: string
- default: ""
description: Refspec to fetch before checking out revision.
name: refspec
type: string
- default: "true"
description: 初始化子模块
name: submodules
type: string
- default: "1"
description: 执行浅克隆
name: depth
type: string
- default: "true"
description: 将http.sslVerify设置为false
name: sslVerify
type: string
- default: ca-bundle.crt
description: 设置ca证书文件名
name: crtFileName
type: string
- default: ""
description: 设置clone到的子目录
name: subdirectory
type: string
- default: ""
description: 定义要匹配的目录模式
name: sparseCheckoutDirectories
type: string
- default: "true"
description: 删除已存在的目录
name: deleteExisting
type: string
- default: ""
description: HTTP proxy server for non-SSL requests.
name: httpProxy
type: string
- default: ""
description: HTTPS proxy server for SSL requests.
name: httpsProxy
type: string
- default: ""
description: Opt out of proxying HTTP/HTTPS requests.
name: noProxy
type: string
- default: "true"
description: Log the commands that are executed during `git-clone`'s operation.
name: verbose
type: string
- default: quanheng.com/k8s/git-init:v0.40.2
description: The image providing the git-init binary that this Task runs.
name: gitInitImage
type: string
- default: /home/git
description: |
Absolute path to the user's home directory.
name: userHome
type: string
results:
- description: The precise commit SHA that was fetched by this Task.
name: commit
type: string
- description: The precise URL that was fetched by this Task.
name: url
type: string
- description: The epoch timestamp of the commit that was fetched by this Task.
name: committer-date
type: string
steps:
- computeResources: {}
env:
- name: HOME
value: $(params.userHome)
- name: PARAM_URL
value: $(params.url)
- name: PARAM_REVISION
value: $(params.revision)
- name: PARAM_REFSPEC
value: $(params.refspec)
- name: PARAM_SUBMODULES
value: $(params.submodules)
- name: PARAM_DEPTH
value: $(params.depth)
- name: PARAM_SSL_VERIFY
value: $(params.sslVerify)
- name: PARAM_CRT_FILENAME
value: $(params.crtFileName)
- name: PARAM_SUBDIRECTORY
value: $(params.subdirectory)
- name: PARAM_DELETE_EXISTING
value: $(params.deleteExisting)
- name: PARAM_HTTP_PROXY
value: $(params.httpProxy)
- name: PARAM_HTTPS_PROXY
value: $(params.httpsProxy)
- name: PARAM_NO_PROXY
value: $(params.noProxy)
- name: PARAM_VERBOSE
value: $(params.verbose)
- name: PARAM_SPARSE_CHECKOUT_DIRECTORIES
value: $(params.sparseCheckoutDirectories)
- name: PARAM_USER_HOME
value: $(params.userHome)
- name: WORKSPACE_OUTPUT_PATH
value: $(workspaces.output.path)
- name: WORKSPACE_SSH_DIRECTORY_BOUND
value: $(workspaces.ssh-directory.bound)
- name: WORKSPACE_SSH_DIRECTORY_PATH
value: $(workspaces.ssh-directory.path)
- name: WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND
value: $(workspaces.basic-auth.bound)
- name: WORKSPACE_BASIC_AUTH_DIRECTORY_PATH
value: $(workspaces.basic-auth.path)
- name: WORKSPACE_SSL_CA_DIRECTORY_BOUND
value: $(workspaces.ssl-ca-directory.bound)
- name: WORKSPACE_SSL_CA_DIRECTORY_PATH
value: $(workspaces.ssl-ca-directory.path)
image: $(params.gitInitImage)
name: clone
script: |
#!/usr/bin/env sh
set -eu
if [ "${PARAM_VERBOSE}" = "true" ] ; then
set -x
fi
if [ "${WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND}" = "true" ] ; then
cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.git-credentials" "${PARAM_USER_HOME}/.git-credentials"
cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.gitconfig" "${PARAM_USER_HOME}/.gitconfig"
chmod 400 "${PARAM_USER_HOME}/.git-credentials"
chmod 400 "${PARAM_USER_HOME}/.gitconfig"
fi
if [ "${WORKSPACE_SSH_DIRECTORY_BOUND}" = "true" ] ; then
cp -R "${WORKSPACE_SSH_DIRECTORY_PATH}" "${PARAM_USER_HOME}"/.ssh
chmod 700 "${PARAM_USER_HOME}"/.ssh
chmod -R 400 "${PARAM_USER_HOME}"/.ssh/*
fi
if [ "${WORKSPACE_SSL_CA_DIRECTORY_BOUND}" = "true" ] ; then
export GIT_SSL_CAPATH="${WORKSPACE_SSL_CA_DIRECTORY_PATH}"
if [ "${PARAM_CRT_FILENAME}" != "" ] ; then
export GIT_SSL_CAINFO="${WORKSPACE_SSL_CA_DIRECTORY_PATH}/${PARAM_CRT_FILENAME}"
fi
fi
CHECKOUT_DIR="${WORKSPACE_OUTPUT_PATH}/${PARAM_SUBDIRECTORY}"
cleandir() {
# Delete any existing contents of the repo directory if it exists.
#
# We don't just "rm -rf ${CHECKOUT_DIR}" because ${CHECKOUT_DIR} might be "/"
# or the root of a mounted volume.
if [ -d "${CHECKOUT_DIR}" ] ; then
# Delete non-hidden files and directories
rm -rf "${CHECKOUT_DIR:?}"/*
# Delete files and directories starting with . but excluding ..
rm -rf "${CHECKOUT_DIR}"/.[!.]*
# Delete files and directories starting with .. plus any other character
rm -rf "${CHECKOUT_DIR}"/..?*
fi
}
if [ "${PARAM_DELETE_EXISTING}" = "true" ] ; then
cleandir || true
fi
test -z "${PARAM_HTTP_PROXY}" || export HTTP_PROXY="${PARAM_HTTP_PROXY}"
test -z "${PARAM_HTTPS_PROXY}" || export HTTPS_PROXY="${PARAM_HTTPS_PROXY}"
test -z "${PARAM_NO_PROXY}" || export NO_PROXY="${PARAM_NO_PROXY}"
git config --global --add safe.directory "${WORKSPACE_OUTPUT_PATH}"
/ko-app/git-init \
-url="${PARAM_URL}" \
-revision="${PARAM_REVISION}" \
-refspec="${PARAM_REFSPEC}" \
-path="${CHECKOUT_DIR}" \
-sslVerify="${PARAM_SSL_VERIFY}" \
-submodules="${PARAM_SUBMODULES}" \
-depth="${PARAM_DEPTH}" \
-sparseCheckoutDirectories="${PARAM_SPARSE_CHECKOUT_DIRECTORIES}"
cd "${CHECKOUT_DIR}"
RESULT_SHA="$(git rev-parse HEAD)"
EXIT_CODE="$?"
if [ "${EXIT_CODE}" != 0 ] ; then
exit "${EXIT_CODE}"
fi
RESULT_COMMITTER_DATE="$(git log -1 --pretty=%ct)"
printf "%s" "${RESULT_COMMITTER_DATE}" > "$(results.committer-date.path)"
printf "%s" "${RESULT_SHA}" > "$(results.commit.path)"
printf "%s" "${PARAM_URL}" > "$(results.url.path)"
securityContext:
runAsNonRoot: true
runAsUser: 65532
workspaces:
- description: git仓库克隆到的目录
name: output
- description: |
sshkey的目录,这个目录下面应该有一个id_rsa和id_rsa.pub文件,这个目录会被挂载到
name: ssh-directory
optional: true
- description: |
基础认证的目录,这个目录下面应该有一个.git-credentials和.gitconfig文件,这个目录会被挂载到
name: basic-auth
optional: true
- description: |
ca证书的目录,这个目录下面应该有一个ca-bundle.crt文件,这个目录会被挂载到
name: ssl-ca-directory
optional: true
8.2.2 生成task-build镜像
apiVersion: tekton.dev/v1
kind: Task
name: kaniko
namespace: default
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:
- description: Name (reference) of the image to build.
name: IMAGE
type: string
- default: ./Dockerfile
description: Path to the Dockerfile to build.
name: DOCKERFILE
type: string
- default: ./
description: The build context used by Kaniko.
name: CONTEXT
type: string
- default: []
name: EXTRA_ARGS
type: array
- default: registry.cn-hangzhou.aliyuncs.com/weiyigeek/kaniko-executor:latest
description: The image on which builds will run (default is v1.5.1)
name: BUILDER_IMAGE
type: string
results:
- description: Digest of the image just built.
name: IMAGE_DIGEST
type: string
- description: URL of the image just built.
name: IMAGE_URL
type: string
steps:
- args:
- $(params.EXTRA_ARGS)
- --insecure
- --skip-tls-verify
- --skip-tls-verify-pull
- --dockerfile=$(params.DOCKERFILE)
- --context=$(workspaces.source.path)/$(params.CONTEXT)
- --destination=$(params.IMAGE)
- --digest-file=$(results.IMAGE_DIGEST.path)
computeResources: {}
image: $(params.BUILDER_IMAGE)
name: build-and-push
securityContext:
runAsUser: 0
volumeMounts:
- mountPath: /etc/hosts
name: hosts
- mountPath: /workspace/source/hosts
name: host
workingDir: $(workspaces.source.path)
- computeResources: {}
image: quanheng.com/k8s/bash:5.1.4
name: write-url
script: |
set -e
image="$(params.IMAGE)"
echo -n "${image}" | tee "$(results.IMAGE_URL.path)"
volumeMounts:
- mountPath: /etc/hosts
name: hosts
volumes:
- hostPath:
path: /etc/hosts
name: hosts
- hostPath:
path: /etc/hosts
name: host
workspaces:
- description: Holds the context and Dockerfile
name: source
- description: Includes a docker `config.json`
mountPath: /kaniko/.docker
name: docker-credentials
optional: true
8.2.3 生成pipeline
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY