GitOps Tekton+ArgoCD

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

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-nignx

当把上面这个部署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

tkn下载地址

bash 复制代码
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到哪里了?

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的网页,点点即可回滚

相关推荐
ProtonBase20 分钟前
如何从 0 到 1 ,打造全新一代分布式数据架构
java·网络·数据库·数据仓库·分布式·云原生·架构
乐之者v26 分钟前
leetCode43.字符串相乘
java·数据结构·算法
suweijie7684 小时前
SpringCloudAlibaba | Sentinel从基础到进阶
java·大数据·sentinel
公贵买其鹿4 小时前
List深拷贝后,数据还是被串改
java
xlsw_8 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹8 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭9 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫9 小时前
泛型(2)
java
超爱吃士力架9 小时前
邀请逻辑
java·linux·后端
南宫生9 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论