GitOps 提供了一种基于 Git 的操作理念,而 Tekton 和 ArgoCD 分别作为 CI/CD 工具,共同实现了这一理念在 Kubernetes 集群中的应用
k8s只是jenkins 流水线中的一环,但是在tekton中,k8s是基础设施
工作流程:
- 代码提交:开发人员提交代码到 Git 仓库。
- CI 流程(通过 Tekton 实现):Tekton 触发构建流水线,编译代码、运行测试、构建 Docker 镜像,并将其推送到镜像仓库。
- CD 流程(通过 GitOps 和 Argo CD 实现):Tekton 更新 Git 仓库中的声明性配置(如 Kubernetes YAML 文件),Argo CD 检测到配置的变化后,将新的版本自动部署到 Kubernetes 集群中。
1. tekton
装的时候有两条漏网之鱼
bash
vim TektonCD-Pipelines.yaml # 改下下面,去掉后面的sha256.我这里没删是为了留个纪念
#jiangmaoxi/base:latest 把这个改成 alpine:3.12 把别的sha256删掉,只留tag就行了,要不它总重新pull镜像
# This is gcr.io/google.com/cloudsdktool/cloud-sdk:302.0.0-slim
"-gsutil-image", "jiangmaoxi/cloud-sdk:latest@sha256:27b2c22bf259d9bc1a291e99c63791ba0c27a04d2db0a43241ba0f1f20f4067f",
# The shell image must be root in order to create directories and copy files to PVCs.
# gcr.io/distroless/base:debug as of February 17, 2022
# image shall not contains tag, so it will be supported on a runtime like cri-o
"-shell-image", "jiangmaoxi/base:latest@sha256:3cebc059e7e52a4f5a389aa6788ac2b582227d7953933194764ea434f4d70d64",
yaml
skopeo copy --all docker://gcr.io/google.com/cloudsdktool/cloud-sdk docker://jiangmaoxi/cloud-sdk
skopeo copy --all docker://gcr.io/distroless/base docker://jiangmaoxi/base
有run才能跑。step组成task,task组成pipeline。task和pipeline 都是 CRD
Tekton Triggers 是用于触发 CI/CD 流水线的组件。
它提供了一种机制,可以根据外部事件(如 Git 仓库中的代码提交、拉取请求或定时事件)来自动触发 Pipelines 的执行。
当把上面这个部署ingress-nginx的yaml文件里的LoadBalance 改成NodePort后
bash
kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.233.13.142 <none> 80:31061/TCP,443:30608/TCP 133m
ingress-nginx-controller-admission ClusterIP 10.233.13.240 <none> 443/TCP 133m
[root@master1 tekton]# cat tekton-dashboard-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tekton-dashboard-ingress
namespace: tekton-pipelines
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: tekton.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: tekton-dashboard
port:
number: 9097
然后在host里配置好 节点ip 域名。然后通过浏览器访问 http://域名: port
install tkn
bash
tar -zxvf tkn_0.31.3_Linux_x86_64.tar.gz -C /usr/local/bin/ tkn
tkn version
云笔记笔记
-
pipelineResource 包括git 的url还有 revision master
harbor的地址还有用户名密码的 Secret 跟 名为build-sa的 ServiceAccout 关联
-
基于时间戳生成 image tag 的Task
在Task中,params是 Task需要输入的参数, results 定义 Task 在执行后生成的输出。step 定义了Task 的具体操作
-
专门用来构建镜像的Task
sidecar 是与主容器并行的容器,包括主容器没有的工具,sidecar与主容器共享网络、卷等。
docker:dind 即 Docker-in-Docker镜像,它包含了一个docker 守护进程,dind 目的是让容器内能运行Docker 命令,甚至启动其他容器。
可以通过sidecar 来启动 dind.
tcp://localhost:2375:这个端口不使用 TLS(即不加密)。
tcp://localhost:2376:这个端口使用 TLS(即加密)。通过这个地址和sidecar,即dind通信,使用它的docker
tcp://localhost:2376. dind 会自动生成证书并在 2376 端口上启用 TLS。
Task中的 resource 就是指的 PipelineResource,但是它已经是 deprecated(已弃用)
pipelineResource 与 Task共享输入输出,应该用 params 和 results来替代 PipelineResource.
-
创建引用 Task的 pipeline
kind: pipeline 中,params 就是task中用的参数值,然后下面根据名字引用 tasks,填上参数。
-
引用Pipeline的 PipelineRun
还加上了之前带有 Secret的 serviceAccount.要注意在pipeline的yaml中,params都是 default 值,真正传实际值在 PipelineRun这里。
先apply task.yaml, 然后是 pipeline.yaml,最后是 pipelineRun.yaml
GitLab触发任务构建
别用 TaskRun, PipelineRun了。提交代码自动触发吧。用 Triggers
EventListener (通过HTTP服务暴露出来)监听Webhook等事件,
在 EventListener 接收到事件后,它首先会调用 Interceptor 来处理或过滤事件。
Interceptor 过滤事件,只有特定的事件,比如GitHub推送事件才会被允许触发后续流程,捕获事件后发给相应的TriggerBinding(事件中的数据被提取并绑定参数), TriggerBinding 将参数传给 TriggerTemplate, TriggerBinding 作用于特定的命名空间,ClusterTriggerBinding 作用于整个集群中。
安装好tkn 的时候,triggers 就已经装好了
EventListener 中 定义了 使用的 sa, interceptors (里面包含了gitlab的secret, push 事件),还有bindings 和 Template.
创建完它后会生成一个svc,用来接收事件响应
Gitlab如果部署在集群内部,就用Service的DNS形式来访问 EventListener 即可,如果在外部,用NodePort 或者 Ingress.
每个 Service 都有一个 DNS 名称,通常是 service-name.namespace.svc.cluster.local,你可以在集群内部使用这个 DNS 名称来访问对应的服务。
Secret, WebHook 需要一个 Secret Token, 还有gitlab 登录的账号密码都要写在 Secret.yaml 里
ServiceAccout: 比如 具有 上面 Secret 的 Token和gitlab的 username 和 passwd
Role: 定义了在哪个命名空间中对哪些资源具有增删改查中的哪些权限
RoleBinding 将Role 绑定到了 某个 sa 上,然后 Pod 使用了这个 sa,就具有role 中定义的权限。
TriggerBinding 与 TriggerTemplate的绑定就是在EventListener那里提一嘴就完成了。
TriggerBinding的参数又来自于哪里?
来自于GitLab Webhook发过来的数据,从里面的body中提取的。
TriggerTemplate 里面的 params就提到了 TriggerBinding中的参数。
generateName: gitlab-run- 作用是指定taskRun的前缀名,后缀k8s 会自动生成
TaskSpec, 在没有预先定义Task,可以在这里定义
tt. 是从 TriggerBinding 中传递的参数前缀
这里面哪里表示pull代码了?把代码pull到哪里了?
yaml
resources:
inputs:
- name: source
type: git
这里定义了一个名为 source 的输入资源,它的类型是 git。
这表示这个资源将从一个 Git 仓库中拉取代码。
image: ubuntu 表示在运行这一步骤时,会拉取并使用 ubuntu 镜像。
这个镜像会被拉取到执行 TaskRun 的节点(即 Kubernetes 中运行 Pod 的节点)上。
代码会被拉取到运行 TaskRun 的 Pod 中的特定目录。这个目录是由 Tekton 自动管理的,通常位于容器的文件系统中。
eventlistener 为 svc 和 pod 还有 eventlistener 资源
在集群内用kubectl get eventlistener地址访问,集群外用 Ingress
ingress nginx
目的在集群之外访问到 EventListener
部署ingress-nginx
将 ingress-nginx-controller 从NodePort 改成 LoadBalancer
ingress.yaml 中要指明用的是 nginx,host, svc的名字和端口
在dnsserver里添加 EventListener的域名解析
然后在gitlab的 Webhooks里填入域名和Secret token,就是你之前自己定的那个token
Gitlab 提交代码后,在k8s 中会出现 taskrun对应的pod, 查看这个pod 的日志,可以看到 showPath
它会在你触发 CI/CD 流水线时创建。TaskRun 会启动一个或多个 Pod 来执行定义的任务(如拉取代码、构建镜像、运行测试等)。
Pod 的终止:当 TaskRun 中的所有步骤执行完毕后,Pod 的任务就完成了。Kubernetes 默认会自动清理完成状态的 Pod,因此这些 Pod 会被终止并移除。
自动化流水线
Clone 代码 -> 单元测试 -> 编译打包 -> Docker 镜像构建/推送 -> kubectl 部署服务及回滚
每一步都是一个 Task
sa 用于harbor gitlab 认证,存储后端用 sc: nfs
clone代码的task直接去tekton官网下载,改动下即可使用
编译打包app阶段,workspaces 是pv或者emptyDir. 它用于不同任务之间共享文件和数据。只要使用相同的workspaces name,它们就将共享一个路径,在构建镜像的时候就能得到上一步中创建的二进制文件
DinD 是用来构建和推送镜像的。用DinD就得用sidecar.
在部署到k8s的时候也可以使用helm
Helm就在代码仓库中,已经在共享目录里了。早就clone下来了
helm Chart 里面包含了k8s所需的Deployment,service等和模板化的配置文件。
helm仓库是存储 chart的地方,可以使用 helm repo add 命令添加官方或自定义的 Helm 仓库。然后 helm repo update,更新本地Chart
修改values.yaml 更新Chart 配置,values.yaml里面就有你之前build 好的镜像
不用下面这么复杂,直接在pipelineRun中的overwrite_values那里指定值就行了。
使用简单的脚本来更新 values.yaml 文件中的镜像名称和标签。
yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: update-helm-values
spec:
params:
- name: IMAGE_URL
description: "The URL of the image repository"
- name: IMAGE_TAG
description: "The tag of the image"
workspaces:
- name: source
steps:
- name: update-values
image: ubuntu
script: |
sed -i "s|repository:.*|repository: $(params.IMAGE_URL)|g" /workspace/source/values.yaml
sed -i "s|tag:.*|tag: $(params.IMAGE_TAG)|g" /workspace/source/values.yaml
回滚
最好是我们手动去触发
也可以通过WhenExpressions 自动触发,通过helm-status获取部署状态来决定是否回滚
也是通过helm 的 rollback 实现的回滚
这次是真的流水线
pipeline中定义 workspace,Resource, Params 等,然后传递到Task中,pipeline中也引用了大量的Task,然后把之前写入值的参数传给task
workspace用的nfs
push代码后自动触发
就是用EventListener(里面带binding) 和 TriggerTemplate 代替 pipelineRun,一 push 代码就自动构建
ArgoCD
deploy和rollback 属于 CD 部分,这部分用ArgoCD 替换。
是一个在argocd 命名空间下的 pod。用到ingress-nginx 和 dnsserver 将argoCD svc暴露出去。为的是 argoCD的网页
有命令行工具 argocd, 用它可以修改网页登录passwd
有两个gitlab库,一个在CI 阶段的代码库,一个是在CD 阶段的 helm库
网页端部署CD项目
项目下创建 app,它可以指定部署哪个 helm的git
CI 推送到镜像仓库后,要手动修改代码仓库中的values文件,手动触发 Argo CD创建,回滚也是在ArgoCD中操作(有链路图的,点点就能回滚),不需要单独的Task 任务,这需要改造pipeline,自己写yaml
yaml就是上传代码之后,自动构建镜像,添加一个task用来修改helm values.yaml里的image值,然后使用helm 利用argocd部署app.回滚使用的是argocd的网页,点点即可回滚