Skip to content

Tekton 初体验

作者: ryan 发布于: 2025/7/21 更新于: 2025/7/21 字数: 0 字 阅读: 0 分钟

Tekton 是一款功能非常强大而灵活的 CI/CD 开源的云原生框架。Tekton 的前身是 Knative 项目的 build-pipeline 项目,这个项目是为了给 build 模块增加 pipeline 的功能,但是随着不同的功能加入到 Knative build 模块中,build 模块越来越变得像一个通用的 CI/CD 系统,于是,索性将 build-pipeline 剥离出 Knative,就变成了现在的 Tekton,而 Tekton 也从此致力于提供全功能、标准化的云原生 CI/CD 解决方案。

tekton logotype

Tekton 为 CI/CD 系统提供了诸多好处:

  • 可定制:Tekton 是完全可定制的,具有高度的灵活性,我们可以定义非常详细的构建块目录,供开发人员在各种场景中使用。
  • 可重复使用:Tekton 是完全可移植的,任何人都可以使用给定的流水线并重用其构建块,可以使得开发人员无需"造轮子"就可以快速构建复杂的流水线。
  • 可扩展:Tekton Catalog 是社区驱动的 Tekton 构建块存储库,我们可以使用 Tekton Catalog 中定义的组件快速创建新的流水线并扩展现有管道。
  • 标准化:Tekton 在你的 Kubernetes 集群上作为扩展安装和运行,并使用完善的 Kubernetes 资源模型,Tekton 工作负载在 Kubernetes Pod 内执行。
  • 伸缩性:要增加工作负载容量,只需添加新的节点到集群即可,Tekton 可随集群扩展,无需重新定义资源分配或对管道进行任何其他修改。

组件

Tekton 由一些列组件组成:

  • Tekton Pipelines 是 Tekton 的基础,它定义了一组 Kubernetes CRD 作为构建块,我们可以使用这些对象来组装 CI/CD 流水线。
  • Tekton Triggers 允许我们根据事件来实例化流水线,例如,可以我们在每次将 PR 合并到 GitHub 仓库的时候触发流水线实例和构建工作。
  • Tekton CLI 提供了一个名为 tkn 的命令行界面,它构建在 Kubernetes CLI 之上,运行和 Tekton 进行交互。
  • Tekton DashboardTekton Pipelines 的基于 Web 的一个图形界面,可以线上有关流水线执行的相关信息。
  • Tekton Catalog 是一个由社区贡献的高质量 Tekton 构建块(任务、流水线等)存储库,可以直接在我们自己的流水线中使用这些构建块。
  • Tekton Hub 是一个用于访问 Tekton Catalog 的 Web 图形界面工具。
  • Tekton Operator 是一个 Kubernetes Operator,可以让我们在 Kubernetes 集群上安装、更新、删除 Tekton 项目。

安装

项目地址:https://github.com/tektoncd/pipeline

安装 Tekton 非常简单,可以直接通过 tektoncd/pipeline 的 GitHub 仓库中的 release.yaml 文件进行安装,如下所示的命令:

shell
$ kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/previous/v0.37.2/release.yaml

由于官方使用的镜像是 gcr 的镜像,所以正常情况下我们是获取不到的,如果你的集群由于某些原因获取不到镜像,可以使用下面的资源清单文件,我已经将镜像替换成了 Docker Hub 上面的镜像:

shell
$ kubectl apply -f https://my-oss-testing.oss-cn-beijing.aliyuncs.com/k8s/tekton/release.v0.37.2.yml
bash
root@master01:/kube-ops/tekton# kubectl apply -f release-v0.37.2.yaml -n tekton-pipelines
namespace/tekton-pipelines created
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
role.rbac.authorization.k8s.io/tekton-pipelines-webhook created
...
horizontalpodautoscaler.autoscaling/tekton-pipelines-webhook created
deployment.apps/tekton-pipelines-webhook created
service/tekton-pipelines-webhook created

上面的资源清单文件安装后,会创建一个名为 tekton-pipelines 的命名空间,在该命名空间下面会有大量和 tekton 相关的资源对象,我们可以通过在该命名空间中查看 Pod 并确保它们处于 Running 状态来检查安装是否成功:

shell
$ kubectl get pods -n tekton-pipelines
NAME                                          READY   STATUS    RESTARTS   AGE
tekton-pipelines-controller-5d554db6c-2djkm   1/1     Running   0          34s
tekton-pipelines-webhook-578dcd6d5d-b7cnb     1/1     Running   0          3m38s

Tekton dashboard

项目地址:https://github.com/tektoncd/dashboard/blob/release-v0.37.x/docs/install.md

img

此外,还可以安装一个 Tekton 提供的一个 Dashboard,我们可以通过 Dashboard 查看 Tekton 整个任务的构建过程,直接执行下面的命令直接安装即可:

shell
$ kubectl apply -f https://storage.googleapis.com/tekton-releases/dashboard/previous/v0.37.0/release-full.yaml

root@master01:/kube-ops/tekton# kubectl apply -f tekton-dashboard.yaml -n tekton-pipelines
namespace/tekton-dashboard created
customresourcedefinition.apiextensions.k8s.io/extensions.dashboard.tekton.dev created
serviceaccount/tekton-dashboard created
role.rbac.authorization.k8s.io/tekton-dashboard-info created
clusterrole.rbac.authorization.k8s.io/tekton-dashboard-backend created
clusterrole.rbac.authorization.k8s.io/tekton-dashboard-tenant created
rolebinding.rbac.authorization.k8s.io/tekton-dashboard-info created
clusterrolebinding.rbac.authorization.k8s.io/tekton-dashboard-backend created
configmap/dashboard-info created
service/tekton-dashboard created
deployment.apps/tekton-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/tekton-dashboard-tenant created

安装完成后我们可以修改 Dashboard 的 Service 为 NodePort 来访问应用,或者添加一个 Ingress 对象来对外暴露:

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tekton-dashboard
  namespace: tekton-pipelines
spec:
  ingressClassName: nginx # 使用 nginx 的 IngressClass(关联的 ingress-nginx 控制器)
  rules:
    - host: tekton.k8s.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: tekton-dashboard
                port:
                  number: 9097
bash
root@master01:/kube-ops/tekton# kubectl apply -f tekton-ingress.yaml -n tekton-pipelines
ingress.networking.k8s.io/tekton-dashboard created

创建上面的对象后将 tekton.k8s.local 解析到 Ingress 控制器的入口地址,然后就可以通过该地址访问到 Tekton 的 Dashboard 了。

img

概念

Tekton 为 Kubernetes 提供了多种 CRD 资源对象,可用于定义我们的流水线。

img

主要有以下几个资源对象:

  • Task:表示执行命令的一系列有序的步骤,task 里可以定义一系列的 steps,例如编译代码、构建镜像、推送镜像等,每个 task 实际由一个 Pod 执行。
  • TaskRun:Task 只是定义了一个模版,TaskRun 才真正代表了一次实际的运行,当然你也可以自己手动创建一个 TaskRun,TaskRun 创建出来之后,就会自动触发 Task 描述的构建任务。
  • Pipeline:一组有序的 Task,Pipeline 中的 Task 可以使用之前执行过的 Task 的输出作为它的输入。表示一个或多个 Task、PipelineResource 以及各种定义参数的集合。
  • PipelineRun:类似 Task 和 TaskRun 的关系,PipelineRun 也表示某一次实际运行的 pipeline,下发一个 PipelineRun CRD 实例到 Kubernetes 后,同样也会触发一次 pipeline 的构建。
  • ClusterTask:覆盖整个集群的任务,而不是单一的某一个命名空间,这是和 Task 最大的区别,其他基本上一致的。
  • PipelineResource(Deprecated):定义由 Tasks 中的步骤摄取的输入和产生的输出的位置,比如 github 上的源码,或者 pipeline 输出资源,例如一个容器镜像或者构建生成的 jar 包等。
  • Run(alpha):实例化自定义任务以在特定输入时执行。

每个任务都在自己的 Kubernetes Pod 中执行,因此,默认情况下,管道内的任务不共享数据。要在 Tasks 之间共享数据,你必须明确配置每个 Task 以使其输出可用于下一个 Task 并获取先前执行的 Task 的输出作为其输入。

任务

使用 Tekton 后你的 CI/CD 工作流中的每个操作都变成了一个 Step,使用指定的容器镜像来执行。Steps 然后组织在 Tasks 中,它在集群中作为 Kubernetes Pod 运行,还可以进一步组织 Tasks 变成成 Pipelines,还可以控制几个 Tasks 的执行顺序。

img

在早期版本的 Tekton 中,PipelineResources 是用来定义输入输出的资源,例如 git 仓库、Docker 镜像等。然而,随着 Tekton 的发展,社区意识到 PipelineResources 存在一些局限性:

  1. 灵活性不足:PipelineResources 是静态的,不能根据运行时的上下文动态配置。
  2. 集成性问题:PipelineResources 不适合所有用例,尤其在与其他工具的集成上存在一些障碍。
  3. 复杂性:在使用过程中,用户反馈 PipelineResources 增加了使用上的复杂性和维护负担。

因此,Tekton 社区决定逐步弃用 PipelineResources,并鼓励用户通过 TaskRun 和 PipelineRun 中的工作单元 (Task) 直接定义资源。取而代之的是,推荐使用 Tekton 的其他原生功能(例如 WorkspacesParamsResults),这些方式提供了更灵活和动态的资源管理方法。

创建任务Task clone

yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: git-clone
spec:
  description: Git 仓库克隆任务
  workspaces:
  - name: git-directory
    description: 克隆代码在本地存储的路径
  - name: ssh-directory
    description: 使用 SSH 克隆代码时所需的相关凭证
  params:
  - name: url
    description: Git 仓库地址
  - name: revision
    description: Git 分支/标签
  results:
  - name: gitCommitHash
    description: Git 提交的哈希值
  steps:
  - name: git-clone
    image: registry.cn-beijing.aliyuncs.com/xxk8s/git:24911
    workingDir: $(workspaces.git-directory.path)
    env:
    - name: PARAM_URL
      value: $(params.url)
    - name: PARAM_REVISION
      value: $(params.revision)
    - name: WORKSPACE_GIT_DIRECTORY_PATH
      value: $(workspaces.git-directory.path)
    - name: WORKSPACE_SSH_DIRECTORY_BOUND
      value: $(workspaces.ssh-directory.bound)
    - name: WORKSPACE_SSH_DIRECTORY_PATH
      value: $(workspaces.ssh-directory.path)
    script: |
      #!/bin/bash
      # 设置严格模式:-x 打印每条命令及其执行结果,-e 发生错误时退出,-u 遇到未定义变量时退出
      set -xeu

      # 设置 SSH 凭证(如果绑定了 ssh-directory)
      if [ "${WORKSPACE_SSH_DIRECTORY_BOUND}" == "true" ]; then
        # 将 SSH 凭证复制到 ~/.ssh 目录
        cp -RL "${WORKSPACE_SSH_DIRECTORY_PATH}" ~/.ssh
        chmod 700 ~/.ssh
        chmod -R 400 ~/.ssh/*
      fi

      # 进入 Git 工作目录
      cd ${WORKSPACE_GIT_DIRECTORY_PATH}

      # 将 git_repo 添加到 Git 的安全目录列表
      git config --global --add safe.directory ${WORKSPACE_GIT_DIRECTORY_PATH}/git_repo

      # 设置 SSH 命令,禁用严格主机检查
      export GIT_SSH_COMMAND="ssh -i ~/.ssh/ssh-privatekey -o StrictHostKeyChecking=no"

      # 清理旧的 git_repo_temp 目录(如果存在)
      if [ -d "git_repo_temp" ]; then
        echo "Directory git_repo_temp already exists. Removing it."
        rm -rf git_repo_temp
      fi

      # 清理旧的 git_repo_latest 目录(如果存在)
      if [ -d "git_repo_latest" ]; then
        echo "Directory git_repo_latest already exists. Removing it."
        rm -rf git_repo_latest
      fi

      # 克隆 Git 仓库到临时目录
      git clone $(params.url) git_repo_temp
      cd git_repo_temp

      # 获取最新提交的哈希值
      latest_commit=$(git rev-parse --short HEAD)

      # 创建目标目录,目录名包含提交的哈希值
      target_dir="git_repo_$latest_commit"

      # 清理目标目录(如果存在)
      if [ -d "$target_dir" ]; then
        echo "Directory $target_dir already exists. Removing it."
        rm -rf $target_dir
      fi

      # 重命名临时目录为目标目录
      mv ../git_repo_temp ../$target_dir

      # 删除超过 3 个的旧克隆,保留最近 3 次
      cd ..
      ls -dt git_repo_* | tail -n +4 | xargs rm -rf || true

      # 创建/更新软链接,指向最新克隆的目录
      ln -sfn $target_dir git_repo_latest

      # 进入最新克隆的目录
      cd git_repo_latest

      # 输出最新提交的哈希值到 Task 的 results 字段
      GIT_COMMIT_HASH="$(git log --pretty=format:"%h" -n 1)"
      echo -n ${GIT_COMMIT_HASH} | tee $(results.gitCommitHash.path)

  - name: cat
    image: registry.cn-beijing.aliyuncs.com/xxk8s/golang:1.14-alpine
    script: |
      echo "检查 git_repo_latest 目录内容"
      ls -l /workspace/git-directory/git_repo_latest
      cd /workspace/git-directory/git_repo_latest
      ls -l ./
      pwd

  - name: run-test
    image: registry.cn-beijing.aliyuncs.com/xxk8s/golang:1.14-alpine
    workingDir: /workspace/git-directory/git_repo_latest
    command: ['go']
    args: ['test']

创建Task run

yaml
# taskrun-git-clone.yaml
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  name: git-clone-taskrun
spec:
  taskRef:
    name: git-clone  # 引用你定义的 git-clone 任务
  params:
    - name: url
      value: https://github.com/your-repo.git  # 替换为实际的 Git 仓库 URL
    - name: revision
      value: master  # 使用的 Git 分支或标签
  workspaces:
    - name: git-directory
      persistentVolumeClaim:
        claimName: git-clone-pvc  # 挂载到 PVC,用于存储克隆的代码
    - name: 
      secret:
        secretName: git-ssh-secret  # SSH 密钥 Secret,用于 Git SSH 认证
  serviceAccountName: default  # 使用默认的 ServiceAccount 或指定一个有权限的 ServiceAccount

创建 PVC 用于存储代码

yaml
#git-clone-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: git-clone-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: rook-cephfs
bash
root@master01:/kube-ops/tekton# kubectl get pvc
NAME            STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
git-clone-pvc   Bound    pvc-8fe4f377-bd99-4ca5-a158-0e15ab2384ec   10Gi       RWO            rook-cephfs    3s

创建 SSH Secret

bash
root@master01:/kube-ops/tekton# kubectl create secret generic git-ssh-secret \
>   --type=kubernetes.io/ssh-auth \
>   --from-file=ssh-privatekey=/root/.ssh/id_rsa
secret/git-ssh-secret created

root@master01:/kube-ops/tekton# kubectl get secrets  | grep  git-ssh-secret
git-ssh-secret                    kubernetes.io/ssh-auth                1      14s

创建构建镜像 Task

现在我们创建一个 Task 任务来构建并推送 Docker 镜像,我们这里使用的示例应用根目录下面已经包含了一个 Dockerfile 文件了,所以我们直接 Clone 代码就可以获得:

yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: build-push
spec:
  description: 使用 docker 构建镜像
  params:
    - name: image
      description: 镜像地址
    - name: dockerfilePath
      description: Dockerfile 路径
    - name: gitCommitHash
      description: Git 提交哈希
  workspaces:
    - name: git-directory
      description: 克隆代码后存储的路径
    - name: dockerconfig
      description: docker配置文件
  steps:
    - name: build-and-push
      image: registry.cn-beijing.aliyuncs.com/xxk8s/docker:l24910
      workingDir: $(workspaces.git-directory.path)
      env:
      - name: WORKSPACE_GIT_DIRECTORY_PATH
        value: $(workspaces.git-directory.path)
      - name: DOCKER_HOST
        value: tcp://docker-dind.kube-ops:2375
      - name: WORKSPACE_DOCKERCONFIG_PATH
        value: $(workspaces.dockerconfig.path)

      script: |
        #!/bin/sh
        set -xeu
        if [ "${WORKSPACE_DOCKERCONFIG_BOUND}" == "true" ]; then
        cp -RL "${WORKSPACE_DOCKERCONFIG_PATH}" ~/.docker
        chmod 700 ~/.docker
        fi

        # 配置 Git 的安全目录
        git config --global --add safe.directory ${WORKSPACE_GIT_DIRECTORY_PATH}/git_repo_latest

        # 切换到最新的 Git 克隆目录
        cd git_repo_latest

        # 构建并推送 Docker 镜像
        IMAGE="$(params.image)-$(params.gitCommitHash)"
        docker build -t ${IMAGE} -f $(params.dockerfilePath) .
        docker push ${IMAGE}

-----------------------------------------------
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  name: build-push-run
spec:
  taskRef:
    name: build-push
  workspaces:
    - name: git-directory
      persistentVolumeClaim:
        claimName: git-clone-pvc   # 同样使用 PVC 来共享数据
    - name: dockerconfig
      secret:
      secretName: docker-config-secret
  params:
    - name: image
      value: harbor.k8s.local/course/tekton-demo  # 替换为你的镜像地址
    - name: dockerfilePath
      value: Dockerfile  # Dockerfile 路径
    - name: gitCommitHash
      value: latest  # 替换为 Git 提交哈希值

      
------------------------------------------------      
      
    
steps:
  - name: build
    image: docker:git
    workingDir: $(workspaces.git-directory.path)
    volumeMounts:
    - name: docker-socket
      mountPath: /var/run/docker.sock
    env:
    - name: WORKSPACE_DOCKERCONFIG_BOUND
      value: $(workspaces.dockerconfig.bound)
    - name: WORKSPACE_DOCKERCONFIG_PATH
      value: $(workspaces.dockerconfig.path)
    - name: WORKSPACE_GIT_DIRECTORY_PATH
      value: $(workspaces.git-directory.path)
    script: |
      #!/bin/sh
      set -xeu
      if [ "${WORKSPACE_DOCKERCONFIG_BOUND}" == "true" ]; then
        cp -RL "${WORKSPACE_DOCKERCONFIG_PATH}" ~/.docker
        chmod 700 ~/.docker
      fi
      # 将git_repo添加到Git的安全目录列表
      git config --global --add safe.directory ${WORKSPACE_GIT_DIRECTORY_PATH}/git_repo_latest
      cd git_repo_latest
      IMAGE="$(params.image)-$(params.gitCommitHash)"
      docker build -t ${IMAGE} -f $(params.dockerfilePath) .
      docker push ${IMAGE}
yaml
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  name: build-push-run
spec:
  taskRef:
    name: build-push
  params:
    - name: image
      value: harbor.k8s.local  # 替换为你的镜像地址
    - name: dockerfilePath
      value: Dockerfile  # Dockerfile 路径
    - name: gitCommitHash
      value: latest  # 替换为 Git 提交哈希值

docker 凭证

yaml
# harbor-auth.yaml
apiVersion: v1
kind: Secret
metadata:
  name: harbor-auth
  annotations:
    tekton.dev/docker-0: http://harbor.k8s.local
type: kubernetes.io/basic-auth
stringData:
  username: admin
  password: Harbor12345
bash

$ kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: dockerconfig
type: kubernetes.io/dockerconfigjson
data:
  config.json: eyJhdXRocyI6eyJod==
EOF

runtask

yaml
  workspaces:
    - name: git-directory
      persistentVolumeClaim:
        claimName: git-clone-pvc  # 挂载到 PVC,用于存储克隆的代码
    - name: docker-directory
      secret:
        secretName: harbor-auth  # SSH 密钥 Secret,用于 Git SSH 认证
  serviceAccountName: default  # 使用默认的 ServiceAccount 或指定一个有权限的 ServiceAccount

注意 这是我首次创建的一个 runtask

这里我在 bulid-push-run2 点击重新运行会自动刷新此版本 runtask 的 yaml 文件

这里的路径是 xxk8s

在bulid-push-run2 这里选择重新运行后会刷新

这里我又从 xinn 这个路径改为华为的地址,以及还是 xinn,yaml 文件并没有更新

原因是我从衍生任务重新运行的,就不会执行新的 yaml ,坑

Tekton 构建镜像任务对接 Harbor 的两种方式

第一种 docker 配置文件挂载

这种方式是利用已有的 docker config.json, 如果使用 docker 登录过哪些私有仓库都会记录到这个文件中。

例如

bash
{
        "auths": {
                "ghcr.io": {
                        "auth": "cnASDCCASDASSDFSDVSDVSQ2312eA=="
                },
                "harbor.ceamg.com": {
                        "auth": "ASDASDAaWAS123FASDASDuY29t"
                },
                "harbor.k8s.local": {
                        "auth": "YAWRASDDAXCZXCVVASF2TIzNDU="
                },
                "registry.cn-hangzhou.aliyuncs.com": {
                        "auth": "ASDDYyMasdasSDASDSdasaAcAascaDsdasdMTIzLi4="
                }
        }
}

我们只需要把这个文件挂载到 task 中就行了

task-pushimage-file

在 Tekton 的 Task 中,workspace 是用来处理任务期间存储数据的共享路径。它们可以用于持久化数据,或者在多个步骤、任务甚至管道之间共享数据。

这里我们利用workspace 的机制将 Docker 配置文件共享给 Task,使得 Task 能够使用这个配置文件进行 Docker 操作。

workspaces.dockerconfig.bound 是 Tekton 中用于判断某个 workspace 是否被正确绑定到 TaskRun 的一个特殊变量。

这个变量是一个布尔值,取值为 "true""false",用于检查该 workspace 是否被绑定,当 TaskRun 开始执行时,Tekton 会尝试将 workspace(此处是 dockerconfig)绑定到 Pod 的文件系统中。

如果绑定成功,Tekton 会将这个状态反映到 workspaces.dockerconfig.bound 变量上,设置为 "true",那么就会将配置文件复制到~/.docker正常进行 Docker 操作。

yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: build-push
spec:
  description: 使用 docker 构建镜像
  params:
    - name: image
      description: 镜像地址
    - name: dockerfilePath
      description: Dockerfile 路径
    - name: gitCommitHash
      description: Git 提交哈希
  workspaces:
    - name: git-directory
      description: 克隆代码后存储的路径
    - name: dockerconfig
      description: docker配置文件
  steps:
    - name: build-and-push
      image: registry.cn-beijing.aliyuncs.com/xxk8s/docker:l24910
      workingDir: $(workspaces.git-directory.path)
      env:
      - name: WORKSPACE_GIT_DIRECTORY_PATH
        value: $(workspaces.git-directory.path)
      - name: DOCKER_HOST
        value: tcp://docker-dind.kube-ops:2375
      - name: WORKSPACE_DOCKERCONFIG_BOUND
        value: $(workspaces.dockerconfig.bound)
      - name: WORKSPACE_DOCKERCONFIG_PATH
        value: $(workspaces.dockerconfig.path)

      script: |
        #!/bin/sh
        set -xeu
        if [ "${WORKSPACE_DOCKERCONFIG_BOUND}" == "true" ]; then
        
        cp -RL "${WORKSPACE_DOCKERCONFIG_PATH}" ~/.docker
        chmod 700 ~/.docker
        fi

        # 配置 Git 的安全目录
        git config --global --add safe.directory ${WORKSPACE_GIT_DIRECTORY_PATH}/git_repo_latest

        # 切换到最新的 Git 克隆目录
        cd git_repo_latest

        # 构建并推送 Docker 镜像
        IMAGE="$(params.image)-$(params.gitCommitHash)"
        docker build -t ${IMAGE} -f $(params.dockerfilePath) .
        docker push ${IMAGE}

run-task-pushimage-file

我们直接创建一个 runtask 去执行这个任务

在TaskRun 中的workspaces:里面我们使用secret 将dockerconfig 进行挂载,这里指定了secretName: docker-config-secret

在TaskRun 中我们还指定了一个serviceAccountName账户,它的作用是将 sa 和 secret 关联。

yaml
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  name: build-push-run
spec:
  taskRef:
    name: build-push
  workspaces:
    - name: git-directory
      persistentVolumeClaim:
        claimName: git-clone-pvc2
    - name: dockerconfig
      secret:
        secretName: docker-config-secret
  params:
    - name: image
      value: harbor.k8s.local/course/tekton-demo  # 替换为你的镜像地址
    - name: dockerfilePath
      value: Dockerfile  # Dockerfile 路径
    - name: gitCommitHash
      value: latest  # 替换为 Git 提交哈希值
  serviceAccountName: default

现在我们创建需要调用的 secret

这里我把我环境中的 docker config 文件,上传到了 master01 的 tmp 目录中,这样我能直接把它嵌入到 secret 中去。

bash
 kubectl create secret generic docker-config-secret \
  --from-file=.dockerconfigjson=/tmp/config.json \
  --type=kubernetes.io/dockerconfigjson

然后使用以下命令将 docker-config-secret 关联到 default sa

  • kubectl patch serviceaccount default: 这个命令是用来更新 default ServiceAccount 的。
  • -p '{"secrets": [{"name": "docker-config-secret"}]}': 这会将 docker-config-secret 作为 secrets 添加到 default ServiceAccount 中
bash
kubectl patch serviceaccount default \
  -p '{"secrets": [{"name": "docker-config-secret"}]}' \
  --namespace=default

测试执行

完成镜像构建并推送到镜像仓库

第二种 使用用户名密码

同理直接将用户名密码写入 secret ,然后创建 sa 关联到 secret 就可以了

创建 secret

bash
kubectl create secret docker-registry huawei-docker-config-secret \
  --docker-server=swr.cn-north-4.myhuaweicloud.com \
  --docker-username=cn-north-4@B1FDFSVXCVCCD4Z9VS \
  --docker-password=1asd123da3Ssdacasdfsdf5205123d1231faasdqweq19ad142bf0 \
  --namespace=defaultsa

创建 sa

yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:                                                          
  name: build-sa
  namespace: default
secrets:
- name: build-sa-token-gs4nl
- name: huawei-docker-config-secret

创建 Task

yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: build-push2
spec:
  description: 使用 docker 构建镜像
  params:
    - name: image
      description: 镜像地址
    - name: dockerfilePath
      description: Dockerfile 路径
    - name: gitCommitHash
      description: Git 提交哈希
  workspaces:
    - name: git-directory
      description: 克隆代码后存储的路径
  steps:
    - name: build-and-push
      image: registry.cn-beijing.aliyuncs.com/xxk8s/docker:l24910
      workingDir: $(workspaces.git-directory.path)
      env:
      - name: WORKSPACE_GIT_DIRECTORY_PATH
        value: $(workspaces.git-directory.path)
      - name: DOCKER_HOST
        value: tcp://docker-dind.kube-ops:2375

      script: |
        #!/bin/sh
        set -xeu

        # 配置 Git 的安全目录
        git config --global --add safe.directory ${WORKSPACE_GIT_DIRECTORY_PATH}/git_repo_latest

        # 切换到最新的 Git 克隆目录
        cd git_repo_latest

        # 构建并推送 Docker 镜像
        IMAGE="$(params.image)-$(params.gitCommitHash)"
        docker build -t ${IMAGE} -f $(params.dockerfilePath) .
        docker push ${IMAGE}

创建 TaskRun

yaml
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  name: build-push-run2
spec:
  taskRef:
    name: build-push2
  workspaces:
    - name: git-directory
      persistentVolumeClaim:
        claimName: git-clone-pvc2
  params:
    - name: image
      value: swr.cn-north-4.myhuaweicloud.com/bj-xinn/tekton-demo  # 替换为你的镜像地址
    - name: dockerfilePath
      value: Dockerfile  # Dockerfile 路径
    - name: gitCommitHash
      value: latest  # 替换为 Git 提交哈希值
  serviceAccountName: build-sa

测试执行

可以看到镜像已经成功上传华为云镜像仓库