GitOps Tekton+ArgoCD

news/2024/11/15 0:35:38/

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 集群中。

tekton_10">1. tekton

Tekton入门部署
装的时候有两条漏网之鱼

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",
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-nignx
当把上面这个部署ingress-nginx的yaml文件里的LoadBalance 改成NodePort后

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-ingressnamespace: tekton-pipelinesannotations:kubernetes.io/ingress.class: nginxnginx.ingress.kubernetes.io/rewrite-target: /
spec:rules:- host: tekton.example.comhttp:paths:- path: /pathType: Prefixbackend:service:name: tekton-dashboardport:number: 9097

然后在host里配置好 节点ip 域名。然后通过浏览器访问 http://域名: port

install tkn

tkn下载地址

tar -zxvf tkn_0.31.3_Linux_x86_64.tar.gz -C /usr/local/bin/ tkn
tkn version

云笔记笔记

  1. pipelineResource 包括git 的url还有 revision master
    harbor的地址还有用户名密码的 Secret 跟 名为build-sa的 ServiceAccout 关联

  2. 基于时间戳生成 image tag 的Task
    在Task中,params是 Task需要输入的参数, results 定义 Task 在执行后生成的输出。step 定义了Task 的具体操作

  3. 专门用来构建镜像的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.

  1. 创建引用 Task的 pipeline
    kind: pipeline 中,params 就是task中用的参数值,然后下面根据名字引用 tasks,填上参数。

  2. 引用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到哪里了?

resources:inputs:- name: sourcetype: 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 文件中的镜像名称和标签。

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: update-helm-values
spec:params:- name: IMAGE_URLdescription: "The URL of the image repository"- name: IMAGE_TAGdescription: "The tag of the image"workspaces:- name: sourcesteps:- name: update-valuesimage: ubuntuscript: |sed -i "s|repository:.*|repository: $(params.IMAGE_URL)|g" /workspace/source/values.yamlsed -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的网页,点点即可回滚


http://www.ppmy.cn/news/1512386.html

相关文章

理解Flink算子链

前言 对于flink初学者,如果我们观察WebUi中任务执行情况,可能会有一个疑惑,为什么节点和代码中的算子对不上? 从WebUi上看起来像是一个节点,会把转换处理的很多个任务都连接在一起,合并成了一个“大任务”。这又是怎么回事呢? 算子间的数据传输 我们先来考察一下算子…

Moodle与ONLYOFFICE集成如何实现智能教学管理

陈老老老板&#x1f934; &#x1f9d9;‍♂️本文专栏&#xff1a;生活&#xff08;主要讲一下自己生活相关的内容&#xff09;生活就像海洋,只有意志坚强的人,才能到达彼岸。 &#x1f9d9;‍♂️本文简述&#xff1a;ONLYOFFICE相信大家已经有所了解&#xff0c;本篇讲一下如…

Redis7基础篇(七)

redis哨兵&#xff08;sentinel&#xff09; 目录 redis哨兵&#xff08;sentinel&#xff09; 是什么 能干吗 案例演示 架构 案例步骤 出现的问题 哨兵的运行流程和选举原理 哨兵的使用建议​编辑 是什么 在之前的复制中我们了解到 主机shutdown之后 从机就会一直等…

vue3中实现给pdf加盖公章(手动拖拽公章确认位置)

开发项目时&#xff0c;碰到了一个这样的需求&#xff1a;需要前端从服务器获取到一个pdf文件&#xff0c;然后用户通过手动拖拽公章的方式确认公章应该加盖的位置&#xff0c;然后将位置信息传递给服务器。代码并不是非常完美&#xff0c;仅供大家参考。 引用的两个包版本为 …

C的动态内存管理 free()和malloc()的简单实现——free()根据内存地址便知释放内存的空间大小(原理详解)

malloc与free malloc 分配的内存是未初始化的&#xff0c;其中的字节内容是不确定的&#xff08;可能是随机值&#xff09;。 如果内存分配失败&#xff0c;malloc 返回一个空指针 NULL&#xff0c;可以通过检查返回值来判断是否分配成功。 void* malloc (size_t size); cal…

一个手机到手机之间通话经过了哪些设备

来源&#xff1a;https://www.bilibili.com/video/BV1ic411F7mM/?spm_id_from333.880.my_history.page.click&vd_source6c5d3cd50fc7fa8732bdfb760a055839 一个手机通话需要经过下面三个网络 类别接入网&#xff08;Access Network&#xff09;承载网&#xff08;Transp…

关于路由和负载均衡

路由 想象你在一个大城市里&#xff0c;想去一个从未去过的新餐馆。你会怎么找到那里&#xff1f;你可能会用手机地图&#xff0c;对吧&#xff1f;地图告诉你从你现在的位置出发&#xff0c;应该先左转&#xff0c;再右转&#xff0c;走哪条街&#xff0c;过几个路口&#xf…

【并发编程】什么是CAS?Java是如何实现CAS操作的?

目录 一.什么是CAS&#xff1f; 二.Java中如何实现CAS操作&#xff1f; 一.什么是CAS&#xff1f; 在Java并发编程中&#xff0c;CAS 代表 "Compare-And-Swap"&#xff08;交换并比较&#xff09;&#xff0c;这是一种用于实现无锁编程的原子操作。CAS操作通常用于…