Tekton Pipelines从安装到构建Java应用镜像

Tekton Pipelines从安装到构建Java应用镜像

Tekton 是一个功能强大且灵活的 Kubernetes 原生 CI/CD 框架。它通过声明式的方式定义流水线,实现云原生的构建、测试和部署。本文将从零开始安装 Tekton,理解核心概念,并通过一个完整的示例——从 Git 仓库克隆 Java 代码、使用 Maven 编译打包、再用 Kaniko 构建并推送容器镜像——来感受 Tekton 的实际工作流。

前提条件

  • 一个可用的 Kubernetes 集群(本文基于 v1.24+)
  • 已安装 kubectl 并配置好集群访问权限
  • 基本的容器和 Kubernetes 知识

1. 安装 Tekton

1.1 安装 Tekton Pipeline

Tekton Pipeline 是核心组件,提供 TaskPipeline 等自定义资源。使用以下命令安装最新版本:

kubectl apply --filename https://infra.tekton.dev/tekton-releases/pipeline/latest/release.yaml

如果需要安装特定旧版本,将 latest 替换为具体版本号:

kubectl apply --filename https://infra.tekton.dev/tekton-releases/pipeline/previous/<version_number>/release.yaml

验证安装:

kubectl get pods --namespace tekton-pipelines --watch

等待所有 Pod 进入 Running 状态后按 Ctrl+C 退出。

1.2 安装 Tekton Dashboard(可选)

Dashboard 提供可视化的界面,方便查看 TaskRun、PipelineRun 的日志和状态。

kubectl apply --filename https://infra.tekton.dev/tekton-releases/dashboard/latest/release.yaml

同样可以指定版本号:

kubectl apply --filename https://infra.tekton.dev/tekton-releases/dashboard/previous/<version_number>/release.yaml

1.3 安装 tkn CLI

tkn 是 Tekton 的命令行工具,可简化任务和流水线的管理。从 GitHub Releases 下载对应版本。例如在 Linux 上安装 v0.37.5:

yum install https://github.com/tektoncd/cli/releases/download/v0.37.5/tektoncd-cli-0.37.5_Linux-64bit.rpm

其他系统可下载二进制文件并放入 PATH

2. 核心概念速览

  • Task:一组步骤(Steps)的集合,每个步骤基于特定容器镜像执行命令。是最小的可复用单元。
  • TaskRun:Task 的一次具体执行,可传入参数、指定工作区(Workspace)等。
  • Pipeline:一个或多个 Task 的有序组合,可定义执行顺序、参数和资源。
  • PipelineRun:Pipeline 的具体执行实例。
  • ClusterTask:集群级别的 Task,对所有命名空间可见。
  • Workspace:为 Task 或 Pipeline 提供共享存储(如 PVC、emptyDir、Secret)的抽象,用于源代码传递、缓存或凭证挂载。

注意PipelineResource 原本用于定义输入/输出资源,但在新版本中已废弃,推荐使用 Workspace 和参数替代。

3. 实战流水线:Java 应用自动构建并推送镜像

我们将构建一个完整的 Pipeline,实现以下步骤:

  1. 从 Git 仓库(支持私有仓库)克隆源码
  2. 使用 Maven 编译并打包 JAR
  3. 使用 Kaniko 构建容器镜像并推送到阿里云容器镜像服务(或其他镜像仓库)

3.1 准备 Git 凭证 Secret

如果使用私有仓库,需要提供 .git-credentials.gitconfig 文件。创建一个临时目录并准备这两个文件:

# 示例 git-credentials.txt(实际信息请替换)
echo "https://your-username:your-pat@github.com" > git-credentials.txt

# .gitconfig 用于指定凭证助手
cat > gitconfig.txt << EOF
[credential]
	helper = store
EOF

kubectl create secret generic git-credentials \
  --from-file=.git-credentials=./git-credentials.txt \
  --from-file=.gitconfig=./gitconfig.txt

安全提示:对于生产环境,推荐使用 Kubernetes Secret 或外部密钥管理工具(如 Vault)存储敏感信息。

3.2 准备 Docker 凭证 Secret

登录镜像仓库(以阿里云为例):

docker login --username=your-aliyun-username crpi-xxxxx.cn-chengdu.personal.cr.aliyuncs.com

执行后会在 ~/.docker/config.json 中生成认证信息。直接将该文件创建为 Secret:

kubectl create secret generic docker-credentials --from-file=config.json=$HOME/.docker/config.json

3.3 定义各个 Task

我们使用社区官方提供的 Task,也可以根据需求调整。下面展示三个核心 Task 的关键部分(完整定义可从官方仓库获取)。

Task 1: git-clone(克隆仓库)

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: git-clone
  annotations:
    tekton.dev/deprecated: "true"   # 表示此 Task 未来可能被替换,但当前可用
spec:
  workspaces:
    - name: output
    - name: basic-auth        # 用于绑定 git-credentials Secret
      optional: true
  params:
    - name: url
      type: string
    - name: revision
      default: ""
    - name: deleteExisting
      default: "true"
    # ... 其他参数省略
  steps:
    - name: clone
      image: ghcr.io/tektoncd/github.com/tektoncd/pipeline/cmd/git-init:v0.40.2
      script: |
        # 脚本会使用 basic-auth workspace 中的凭证进行认证克隆
        /ko-app/git-init -url="$(params.url)" ...

Task 2: maven(Maven 编译)

apiVersion: tekton.dev/v1
kind: Task
metadata:
  name: maven
  labels:
    app.kubernetes.io/version: "0.4"
spec:
  workspaces:
    - name: source              # 包含项目源码
    - name: maven-settings      # 动态生成的 settings.xml
    - name: maven-local-repo    # 依赖缓存(可选)
  params:
    - name: GOALS
      type: array
      default: ["package"]
    - name: MAVEN_IMAGE
      default: "maven:3.8.8-eclipse-temurin-8"
    - name: MAVEN_MIRROR_URL
      default: ""
    # ... 代理、服务器认证等参数
  steps:
    - name: mvn-goals
      image: $(params.MAVEN_IMAGE)
      workingDir: $(workspaces.source.path)/$(params.CONTEXT_DIR)
      args: ["$(params.GOALS[*])"]
      script: |
        # 使用 Maven 命令并挂载 settings.xml
        /usr/bin/mvn -s $(workspaces.maven-settings.path)/settings.xml "$@" -Dmaven.repo.local=$(workspaces.maven-local-repo.path)/.m2
        # 输出 groupId、artifactId、version 作为 Results

此 Task 可以输出 group-idartifact-idversion 供后续 Task 使用。

Task 3: kaniko(构建并推送镜像)

apiVersion: tekton.dev/v1
kind: Task
metadata:
  name: kaniko
  annotations:
    tekton.dev/deprecated: "true"
spec:
  workspaces:
    - name: source
    - name: dockerconfig        # 绑定 docker-credentials Secret
      optional: true
      mountPath: /kaniko/.docker
  params:
    - name: IMAGE
      type: string
    - name: DOCKERFILE
      default: ./Dockerfile
    - name: CONTEXT
      default: ./
    - name: BUILDER_IMAGE
      default: gcr.io/kaniko-project/executor:v1.5.1
  results:
    - name: IMAGE_DIGEST
    - name: IMAGE_URL
  steps:
    - name: build-and-push
      image: $(params.BUILDER_IMAGE)
      args:
        - --dockerfile=$(params.DOCKERFILE)
        - --context=$(workspaces.source.path)/$(params.CONTEXT)
        - --destination=$(params.IMAGE)
        - --digest-file=$(results.IMAGE_DIGEST.path)
      securityContext:
        runAsUser: 0   # kaniko 需要 root 权限
    - name: write-url
      image: bash:5.1.4
      script: |
        printf "%s" "$(params.IMAGE)" | tee $(results.IMAGE_URL.path)

3.4 组装 Pipeline

下面的 Pipeline 串联上述三个 Task,并通过 Workspace 共享源代码、传递凭证和缓存。

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: clone-maven-build-push
spec:
  params:
    - name: repo-url
      type: string
    - name: image-reference
      type: string
  workspaces:
    - name: shared-data            # 存放源代码,Task 间共享
    - name: docker-credentials     # 推送到镜像仓库的认证信息
    - name: git-credentials        # 访问私有 Git 仓库的认证信息
    - name: maven-settings         # Maven 配置文件(Task 会动态生成)
    - name: maven-local-repo       # Maven 依赖缓存(可选)
  tasks:
    - name: fetch-source
      taskRef:
        name: git-clone
      workspaces:
        - name: output
          workspace: shared-data
        - name: basic-auth
          workspace: git-credentials
      params:
        - name: url
          value: $(params.repo-url)
        - name: deleteExisting
          value: "true"

    - name: maven-build
      runAfter: ["fetch-source"]
      taskRef:
        name: maven
      workspaces:
        - name: source
          workspace: shared-data
        - name: maven-settings
          workspace: maven-settings
        - name: maven-local-repo
          workspace: maven-local-repo
      params:
        - name: GOALS
          value: ["clean", "package", "-DskipTests"]
        - name: MAVEN_MIRROR_URL
          value: "https://maven.aliyun.com/repository/public"  # 加速国内下载
        - name: MAVEN_IMAGE
          value: "maven:3.8.8-eclipse-temurin-8"

    - name: build-push
      runAfter: ["maven-build"]
      taskRef:
        name: kaniko
      workspaces:
        - name: source
          workspace: shared-data
        - name: dockerconfig
          workspace: docker-credentials
      params:
        - name: IMAGE
          value: $(params.image-reference)
        - name: BUILDER_IMAGE
          # 可选:使用国内可拉取的 Kaniko 镜像
          value: registry.gitlab.com/gitlab-ci-utils/container-images/kaniko:debug

3.5 创建 PipelineRun 并执行

最后,创建一个 PipelineRun 实例,绑定具体的参数和 Workspace。

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  name: clone-maven-build-push-run
spec:
  pipelineRef:
    name: clone-maven-build-push
  podTemplate:
    securityContext:
      fsGroup: 65532   # 确保共享卷的权限
    env:
      # (可选)我的环境需要代理拉取Docker镜像
      - name: HTTP_PROXY
        value: "http://192.168.200.1:7890"
      - name: HTTPS_PROXY
        value: "http://192.168.200.1:7890"
      - name: NO_PROXY
        value: "localhost,127.0.0.1,.aliyuncs.com,10.0.0.0/8,192.168.0.0/16"
  workspaces:
    - name: shared-data
      volumeClaimTemplate:
        spec:
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 1Gi
    - name: docker-credentials
      secret:
        secretName: docker-credentials
    - name: git-credentials
      secret:
        secretName: git-credentials
    - name: maven-settings
      emptyDir: {}
    - name: maven-local-repo
      emptyDir: {}
  params:
    - name: repo-url
      value: https://github.com/your-org/your-java-app.git
    - name: image-reference
      value: crpi-xxxxx.cn-chengdu.personal.cr.aliyuncs.com/your-namespace/your-app:v1.0.0

使用 kubectl apply -f pipeline-run.yaml 启动流水线,然后通过以下命令监控进度:

tkn pipelinerun logs clone-maven-build-push-run -f

4. 常见问题与技巧

4.1 网络代理问题

如果 Kubernetes 节点无法直接访问外网(如 GitHub、Maven Central、Docker Hub),需要在 Pod 中设置代理。上面的 PipelineRun 已经通过 podTemplate.env 配置了代理。注意 NO_PROXY 中要加阿里云仓库域名和内网地址。

4.2 使用现有 PVC 加速构建

Maven 依赖每次下载会很慢,可以将 maven-local-repo 改为使用持久化 PVC:

workspaces:
  - name: maven-local-repo
    persistentVolumeClaim:
      claimName: maven-repo-pvc

提前创建好 PVC,可实现多流水线共享依赖缓存。

4.3 调试 Task

若 Task 执行失败,可以先查看具体 Step 的日志:

tkn taskrun logs <taskrun-name> --step <step-name>

也可以使用 kubectl describe 查看 Pod 事件。

4.4 避免每次都重新克隆代码

git-clone Task 中设置 deleteExisting: false 可以保留已有目录,但需小心脏数据残留。更好的做法是使用不同的 Workspace 路径或基于 revision 做增量 fetch。

5. 生态

可以根据自己的需求组合官方 Catalog 中的 Task,或编写自定义 Task。可以在 Github 或 ArtifactHub 下载可复用的资源配置清单。以下是本文中用到的 Tasks。

https://raw.githubusercontent.com/tektoncd/catalog/main/task/git-clone/0.9/git-clone.yaml
https://raw.githubusercontent.com/tektoncd/catalog/main/task/kaniko/0.7/kaniko.yaml
https://raw.githubusercontent.com/tektoncd/catalog/refs/heads/main/task/maven/0.4/maven.yaml

参考链接

posted @ 2026-04-28 16:54  wanghongwei-dev  阅读(71)  评论(0)    收藏  举报