使用 OCI 仓库中的 Helm Chart 部署/升级

本指南展示了一个实际的 CD 流程,其中您的 Helm chart 已经推送到 OCI 注册表(例如 Harbor)。

您将使用 Tekton Pipeline 将该 chart 拉取/安装到您的 Kubernetes 集群中。

您将构建一个可复用的 Pipeline,名为 helm-oci-deploy,它将:

  1. 认证您的 OCI 注册表
  2. 直接从 OCI chart 引用运行 helm upgrade --install
  3. 可选地应用额外的 values 文件和 --set 覆盖参数
  4. 支持使用 Kubeconfig Secret 或 ServiceAccount

前提条件

  • 一个 Kubernetes 集群(本地测试可使用 minikube)。
  • 集群中已安装 Tekton Pipelines。
  • 一个 Helm 3.8+ 容器镜像(支持 OCI 的 Helm v3)。
  • 一个包含您要部署的 OCI chart 引用和版本的 OCI 注册表,例如:
    • oci://registry.example.com/charts/myapp
    • 版本如 1.2.3(必须存在于注册表中)
  • 作为 kubernetes.io/dockerconfigjson 类型的 Secret,用于您的 OCI 注册表的凭证:
    • 创建一个类型为 kubernetes.io/dockerconfigjson 的 Kubernetes Secret(示例如下)。
  • Helm 的集群访问凭证(任选其一):
    • 挂载 Kubeconfig Secret,
    • 在具有足够 RBAC 权限的 ServiceAccount 下运行 Task。

逐步操作指南

第 1 步:创建注册表凭证 Secret

您需要为您的 OCI 注册表创建一个类型为 kubernetes.io/dockerconfigjson 的注册表凭证 Secret。

您可以参考 Prepare Registry Credential

第 2 步:创建集群访问凭证

您需要为 Helm 创建集群访问凭证。

您可以参考 Prepare Cluster Access Credential

第 3 步:准备 helm 镜像

您需要一个 Helm 3.8+ 容器镜像(支持 OCI 的 Helm v3)来运行 helm 命令。

您可以参考 Discover Tool Image

搜索时请指定镜像标签为 helm,例如:-l operator.tekton.dev/tool-image=helm

第 4 步:定义 Pipeline

该 Pipeline 使用 helm upgrade --install 直接从 OCI chart 引用安装/升级 release。

Helm 3.8+ 支持通过 oci://...--version 引用 chart,这使得步骤无状态且快速。 如果您更喜欢预先拉取 chart,可以使用 helm pull 到临时目录,然后从 .tgz 路径安装。

您可以使用 --wait 阻塞直到 Kubernetes 报告 release 的资源就绪(或操作超时)。 配合 --timeout 控制 Helm 等待的最长时间。

通常会结合 --atomic 使用,如果等待失败或超时会自动回滚,避免留下半升级状态的 release。

请将 <helm-image> 替换为您的 Helm 镜像。

apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
  name: helm-oci-deploy
spec:
  description: Clone repo, package Helm chart, and push to an OCI registry.
  params:
    - name: oci_chart
      type: string
      description: OCI chart 引用,例如 oci://registry.example.com/charts/myapp
    - name: version
      type: string
      description: 要安装/升级到的 chart 版本(必须存在于注册表中)
    - name: release_name
      type: string
      description: Helm release 名称
    - name: namespace
      type: string
      description: 目标命名空间
      default: default
    - name: extra_args
      type: string
      description: 额外的 helm 参数(例如 "--atomic --timeout 5m --set key=val -f values.yaml")
      default: ""
  workspaces:
    - name: registry-creds
      description: 包含分发注册表配置的 workspace,路径为 config.json(用于 OCI 认证)
      optional: true
    - name: kubeconfig
      description: 包含 kubeconfig 文件的 workspace,路径为 ./kubeconfig
      optional: true
  tasks:
    - name: helm
      taskRef:
        resolver: hub
        params:
          - name: catalog
            value: catalog
          - name: kind
            value: task
          - name: name
            value: run-script
          - name: version
            value: "0.1"
      workspaces:
        - name: config
          workspace: kubeconfig
        - name: secret
          workspace: registry-creds
      params:
        - name: image
          ## 替换为您的 Helm 镜像
          value: <helm-image>
        - name: script
          value: |
            if [ "$(workspaces.secret.bound)" = "true" ]; then
              echo "使用注册表凭证,路径:$(workspaces.secret.path)"
              export HELM_REGISTRY_CONFIG=$(workspaces.secret.path)/.dockerconfigjson
            fi

            if [ "$(workspaces.config.bound)" = "true" ]; then
              echo "使用 kubeconfig,路径:$(workspaces.config.path)"
              export KUBECONFIG=$(workspaces.config.path)/kubeconfig
            fi

            echo "开始升级/安装 release..."
            echo "  Release:   $(params.release_name)"
            echo "  Namespace: $(params.namespace)"
            echo "  Chart:     $(params.oci_chart):$(params.version)"

            # 直接从 OCI 安装(无需先 helm pull)
            helm upgrade --install "$(params.release_name)" "$(params.oci_chart)" \
              --version "$(params.version)" \
              --namespace "$(params.namespace)" --create-namespace \
              $(params.extra_args)

            echo "完成。"

第 5 步:使用 PipelineRun 运行

  • Helm 的集群访问凭证(任选其一):
    • 挂载 Kubeconfig Secret,
    • 在具有足够 RBAC 权限的 ServiceAccount 下运行 Task。

请选择一种集群访问凭证。

apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
  generateName: helm-oci-deploy-
spec:
  workspaces:
    - name: registry-creds
      secret:
        secretName: registry-creds

    ## 如果选择使用 kubeconfig Secret
    # - name: kubeconfig
    #   secret:
    #     secretName: <kubeconfig-secret-name>

  params:
    - name: oci_chart
      value: oci://registry.example.com/charts/myapp
    - name: version
      value: "1.1.0"
    - name: release_name
      value: myapp
    - name: namespace
      value: my-namespace
  pipelineRef:
    name: helm-oci-deploy

  ## 如果选择使用 ServiceAccount
  # taskRunTemplate:
  #   serviceAccountName: <service-account-name>

故障排查

  • helm: command not found:确保您的 image 中确实包含 Helm 二进制文件。
  • unauthorized: authentication required:确保 Secret 正确且已挂载到 registry-creds。确认 HELM_REGISTRY_CONFIG 设置为该路径。
  • Error: chart "myapp" version "x.y.z" not found:该版本不存在于 OCI 仓库,或 oci_chart 路径错误。请核实已推送的标签/版本和路径。
  • failed to create resource: (…RBAC…) forbidden:kubeconfig/ServiceAccount 缺少权限。请授予创建/更新 chart 管理资源所需的角色。

后续步骤