上篇文章简单介绍了基础操作,但是还有些功能没提到参考

这篇文章实现了:

  • 如何构建其他语言程序
  • 挂载 configmap,不覆盖其他目录
  • git 触发部署

1 构建 npm 项目

这里我用自己博客为例,就不开源了

1.1 下载代码

git clone https://git.ccops.cc/Kubernetes/tekton.git

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
cat tekton/cicd/build-push-image-task.yaml

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: build-push-image
spec:
params:
- name: pathToDockerfile
description: The path to the dockerfile to build (relative to the context)
default: Dockerfile
- name: imageUrl
description: Url of image repository
- name: imageTag
description: Tag to apply to the built image
default: latest
workspaces:
- name: source
- name: dockerconfig
mountPath: /kaniko/.docker # config.json 的挂载目录
- name: hexo-config
mountPath: /opt/blog/_config.butterfly.yml # hexo配置文件 的挂载目录
steps:
- name: build-and-push
image: aiotceo/kaniko-executor:v1.6.0
workingDir: $(workspaces.source.path)
command:
- /kaniko/executor
args:
- --dockerfile=$(params.pathToDockerfile)
- --destination=$(params.imageUrl):$(params.imageTag)
- --context=$(workspaces.source.path)
- --skip-tls-verify # 跳过证书验证
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
cat tekton/cicd/blog-pipeline.yaml

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: blog-pipeline
spec:
workspaces: # 声明 workspaces,名字与类型一定要与taks里的对上
- name: blog-build-pvc # pvc
- name: docker-config # docker认证
- name: hexo-config #hexo配置
- name: kubernetes-config # kubeconfig
params:
- name: git_url
- name: revision
- name: gitInitImage
type: string
default: "ccr.ccs.tencentyun.com/ccops/tektoncd-pipeline-cmd-git-init:v0.33.3"
- name: pathToDockerfile
- name: imageUrl
- name: imageTag
tasks: # 添加task到流水线中
- name: clone
taskRef:
name: git-clone
workspaces:
- name: output
workspace: blog-build-pvc
params:
- name: url
value: $(params.git_url)
- name: revision
value: $(params.revision)
- name: gitInitImage
value: $(params.gitInitImage)
- name: build-push-image
params:
- name: pathToDockerfile
value: $(params.pathToDockerfile)
- name: imageUrl
value: $(params.imageUrl)
- name: imageTag
value: $(tasks.clone.results.commit)
taskRef:
name: build-push-image
workspaces: # 传递 workspaces
- name: source
workspace: blog-build-pvc
- name: dockerconfig
workspace: docker-config
- name: hexo-config
workspace: hexo-config
- name: deploy-to-k8s
taskRef:
name: deploy-to-k8s
params:
- name: pathToYamlFile
value: deployment.yaml
- name: IMAGE
value: $(params.imageUrl)
- name: TAG
value: $(tasks.clone.results.commit)
workspaces:
- name: source
workspace: blog-build-pvc
- name: kubernetesconfig
workspace: kubernetes-config
runAfter:
- build-push-image

1.2 部署 pipeline

1.2.1 查看

image-20220412172853421

image-20220412172917611

1.3 部署 npm 项目

1.3.1 项目 dockerfile

1
2
3
4
5
6
7
8
9
10
11
cat Dockerfile
FROM ccr.ccs.tencentyun.com/ccops/hexo:5.4.2 AS build-env # 这里基础镜像已经下了npm的mod了,如需要更新可以加更新命令
ADD . /opt/blog/source/_posts
WORKDIR /opt/blog/source/_posts
RUN hexo g
FROM ccr.ccs.tencentyun.com/ccops/nginx:1.21.6-alpine
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY --from=build-env /opt/blog/public/ /opt/blog
EXPOSE 80
WORKDIR /opt/blog
CMD ["nginx","-g","daemon off;"]

1.4 测试构建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
apiVersion: v1
kind: Secret
metadata:
name: gitlab-auth
annotations:
tekton.dev/git-0: https://git.ccops.cc/
type: kubernetes.io/basic-auth
stringData:
username: xxxx # git账号
password: xxxx # git密码
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: tekton-build-sa
secrets:
- name: gitlab-auth
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: tekton-clusterrole-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: edit
subjects:
- kind: ServiceAccount
name: tekton-build-sa
namespace: blog-cicd
# 上半部分为权限配置,因为这个只是测试用我和到一起了
---
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: blog-pipeline-run
spec:
pipelineRef:
name: blog-pipeline
params:
- name: revision
value: master
- name: git_url
value: https://git.ccops.cc/blog/blog.git
- name: imageUrl
value: ccr.ccs.tencentyun.com/ccops/blog
- name: imageTag
value: "1.1"
- name: pathToDockerfile
value: Dockerfile
workspaces:
- name: blog-build-pvc
volumeClaimTemplate:
spec:
storageClassName: local-path # 通过local sc自动创建pv
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50M
- name: docker-config
secret:
secretName: docker-config
- name: hexo-config
configmap:
name: hexo-config # hexo的configmap名称
subPath: _config.butterfly.yml # 挂载的文件名,taks里一定写文件名而不是目录名
- name: kubernetes-config
secret:
secretName: kubernetes-config
serviceAccountName: tekton-build-sa

1.4.1 查看

2 配置 triggers

2.1 triggers 是什么

Tekton Trigger 是 Tekton 的一个组件,它可以从各种来源的事件中检测并提取需要信息,然后根据这些信息来运行 TaskRun 和 PipelineRun,还可以将提取出来的信息传递给它们以满足不同的运行要求。

其核心组件如下:

  • EventListener:时间监听器,是外部事件的入口 ,通常需要通过 HTTP 方式暴露,以便于外部事件推送,比如配置 Gitlab 的 Webhook。
  • Trigger:指定当 EventListener 检测到事件发生时会发生什么,它会定义 TriggerBinding、TriggerTemplate 以及可选的 Interceptor。
  • TriggerTemplate:用于模板化资源,根据传入的参数实例化 Tekton 对象资源,比如 TaskRun、PipelineRun 等。
  • TriggerBinding:用于捕获事件中的字段并将其存储为参数,然后会将参数传递给 TriggerTemplate。
  • ClusterTriggerBinding:和 TriggerBinding 相似,用于提取事件字段,不过它是集群级别的对象。
  • Interceptor:拦截器,在 TriggerBinding 之前运行,用于负载过滤、验证、转换等处理,只有通过拦截器的数据才会传递给 TriggerBinding。

安装 triggers

kubectl apply -f triggers/ -n tekton-pipelines

2.2 配置 triggers

2.2.1 添加权限

kubectl apply -f deploy/triggers-rabc.yaml -n tekton-pipelines

2.2.2 配置 TriggerTemplate

可以使传入的参数在资源模板中的任何位置被使用,它就好比我们定义了一个对象,这个对象可以接收外部的参数,在对象内部把接收到的参数再传递给 Tekton 资源对象进行使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerTemplate
metadata:
name: blog-pipeline-triggertemplate # 与下面EventListener的bindings字段对应
namespace: blog-cicd
spec:
params: # 参数的定义,从外部接收的参数
- name: gitrevision
description: The git revision
default: master
- name: gitrepositoryurl
description: The git repository url
- name: namespace
description: The namespace to create the resources
resourcetemplates: # # 资源模板,将参数传递给资源模板,实例化一个PipelineRun对象,tt是TriggerTemplate缩写
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: blog-pipeline-run-$(tt.params.gitrevision) # gitcommit ID 变量
namespace: $(tt.params.namespace)
spec:
pipelineRef:
name: blog-pipeline
params:
- name: revision
value: master
- name: git_url
value: $(tt.params.gitrepositoryurl) # 使用git地址变量
- name: imageUrl
value: ccr.ccs.tencentyun.com/ccops/blog
- name: imageTag
value: $(tt.params.gitrevision) # gitcommit ID 变量
- name: pathToDockerfile
value: Dockerfile
workspaces:
- name: blog-build-pvc
persistentVolumeClaim:
claimName: blog-pvc
- name: docker-config
secret:
secretName: docker-config
- name: hexo-config
configmap:
name: hexo-config
subPath: _config.butterfly.yml
- name: kubernetes-config
secret:
secretName: kubernetes-config
serviceAccountName: tekton-build-sa

kubectl apply -f deploy/triggers.yaml -n tekton-pipelines

2.2.3 配置 TriggerBinding

TriggerBinding 用于将事件进行绑定,通过捕获事件中的字段并将其存储为参数。

TriggerBinding 接收从 EventListener 传递过来的参数,然后传给 TriggerTemplate,在 TriggerTemplate 上实例化资源对象。

TriggerBinding 提供 TriggerTemplate 需要的参数,参数以 key-value 的方式存储并传递。其中的 value 是通过$()中包裹的JSONPath表达式来提取(https://tekton.dev/docs/triggers/triggerbindings/)。

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerBinding
metadata:
name: blog-pipelinebinding # 与EventListener的template字段对应
namespace: blog-cicd
spec:
params:
- name: gitrevision
value: $(body.head_commit.id)
- name: namespace
value: blog-cicd
- name: gitrepositoryurl
value: "https://git.ccops.cc/$(body.repository.full_name)" # git地址

2.2.4 配置 EventListener

基于 HTTP 事件的,通过 HTTP 的方式可以绕过常规的认证路径,比如 kubeconfig 等

在 k8s 里需要通过 kube-apiserver 的事件都需要认证、鉴权等一系列操作

EventListener 拥有自己的 serviceaccount,并且这个 serviceaccount 只能用于 Tekton 资源操作,用于监听 Kubernetes 上指定端口的事件,然后会接收传入的事件并指定一个或多个触发器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
cat deploy/eventlistener.yaml
apiVersion: triggers.tekton.dev/v1alpha1
kind: EventListener
metadata:
name: blog-cicd-listener
namespace: blog-cicd
spec:
serviceAccountName: tekton-triggers-example-sa
triggers:
- bindings:
- ref: blog-pipelinebinding # TriggerBinding名称
template:
ref: blog-pipeline-triggertemplate # TriggerTemplate名称
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: tekton-triggers-example-sa
secrets:
- name: gitea-secret # 与下面的Secret名字对应
---
apiVersion: v1
kind: Secret
metadata:
name: gitea-secret
namespace: blog-cicd
type: Opaque
stringData:
secretToken: "61fea7d143806e8d6fa9" # git里要配置的密钥

kubectl apply -f deploy/eventlistener.yaml -n tekton-pipelines

2.2.5 查看

创建完会自动生成一个 listener pod 与 svc,因为我 git 在 k8s 集群里,直接用 svc 名称就行,不在 k8s 集群需要暴露

1
2
3
4
5
kubectl get pod,svc -n blog-cicd
NAME READY STATUS RESTARTS AGE
pod/el-blog-cicd-listener-7575db8489-b5g9d 1/1 Running 0 44h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/el-blog-cicd-listener ClusterIP 10.43.57.170 <none> 8080/TCP,9000/TCP 44h

2.3 配置 git

image-20220414105533730

2.3.1 测试能不能触发

image-20220412133040834

查看日志可以看到触发记录

image-20220412132906817

2.4 提交代码测试下

image-20220414110003943

可以看到会自动创建一个以 commit id 为名称的任务

image-20220414110108728

本来也想把自动删除旧的构建也做了,但是官方文档需要用 tekton 的 operator 进行配置,这点国内实现有问题,使用 operator 会自动从谷歌仓库拉取镜像,如果需要这需求自己写脚本吧