配置自定义 Git 仓库

功能概述

artifacthub-shim 可以从 Git 仓库加载额外的 Tekton catalog 资源。仓库通过带标签的 ConfigMaps 声明。如果 Git 仓库是私有的,或者使用内部 CA,则其仓库条目可以引用同一被监视命名空间中的 Secret。

同一个 Git 仓库条目也可以声明 extraResources 目录。当 config.extraResourceSync.enabled=true 时,这些目录会以 ConfigMaps 的形式同步到集群。

每个嵌套的仓库 name 都会成为外部 catalog 名称,该名称会被 Artifact Hub API 路径、UI 路径以及 Tekton hub resolver 的 catalog 参数使用。请将其视为稳定标识符。

前提条件

  • 已安装并准备好 artifacthub-shim
  • config.enableConfigMapSourcestrue
  • 你可以在 artifacthub-shim 监视的命名空间中创建 ConfigMaps 和 Secrets。默认情况下,这就是安装命名空间。
  • 要从另一个命名空间注册全局可见的仓库,config.globalConfigMapSources.enabled 必须为 true。默认已启用。config.globalConfigMapSources.allowedNamespaces 可限制哪些命名空间可以将仓库提升为全局可见。
  • 要注册命名空间、项目或显式允许列表中的仓库,config.scopedConfigMapSources.enabled 必须为 true。默认已启用。
  • Git 仓库遵循预期的 catalog 布局。
  • 当你要导入 extraResources 目录时,必须启用运行时 ConfigMap 资源同步。默认仅允许 kube-public 命名空间。

仓库布局

path 字段指向 Git 仓库中某个资源类型目录。该路径下,每个 package 都有 version 目录。

task/
  run-script/
    0.1/
      README.md
      run-script.yaml
pipeline/
  build-deploy/
    0.2/
      README.md
      build-deploy.yaml
stepaction/
  echo-message/
    0.1/
      README.md
      echo-message.yaml

对于每个 version 目录,artifacthub-shim 会先查找 <package>.yaml<package>.yml。如果两者都不存在,则回退到单个 Tekton YAML 文件,其中 Kubernetes kind 与配置的源 kind 匹配。

Repository ConfigMap

每个 repository ConfigMap 都必须具有 artifacthub-shim.alauda.io/repository: "true" 标签和一个 repository.yaml 数据键。repository.yaml 负载必须包含一个 gitRepositories 列表。每个 gitRepositories[] 项声明一个 Git 源。每个嵌套的 repositories[] 项声明一个从该 Git 源加载的、外部可见的 catalog 仓库。如果 ConfigMap 中任何一项无效,artifacthub-shim 会拒绝整个 ConfigMap。

config.namespace 配置的主监视命名空间中的 ConfigMaps 会保留现有行为,并默认具有全局可见性。任何其他命名空间中的 ConfigMaps 默认仅在该命名空间内可见。将 artifacthub-shim.alauda.io/repository-visibility 设置为 globalprojectnamespace,即可选择显式作用域。项目成员关系仅根据所有者 Namespace 的 cpaas.io/project 标签推导。

artifacthub-shim.alauda.io/repository-visible-namespaces 注解优先于可见性标签。其逗号分隔值是一个精确的 Namespace 允许列表;条目会被去除首尾空格并去重,且可以跨项目。空值、无效的 Namespace 名称,或不包含任何现有 Namespace 的列表,会使整个 ConfigMap 作用域失效,并将其之前的内容从 serving index 中移除。当只有部分 Namespace 条目不存在时,这些条目会被忽略,其余已存在的 Namespaces 仍会继续接收该仓库。

apiVersion: v1
kind: ConfigMap
metadata:
  name: artifacthub-shim-team-a-catalogs
  namespace: artifacthub-shim-system
  labels:
    artifacthub-shim.alauda.io/repository: "true"
data:
  repository.yaml: |
    gitRepositories:
      - url: https://git.example.com/team-a/tekton-catalog.git
        revision: main
        repositories:
          - name: team-a-tasks
            displayName: Team A Tasks
            kind: task
            path: task
          - name: team-a-pipelines
            displayName: Team A Pipelines
            kind: pipeline
            path: pipeline
          - name: team-a-stepactions
            displayName: Team A StepActions
            kind: stepaction
            path: stepaction
        extraResources:
          - path: config

跨命名空间全局 Repository ConfigMap

当插件或管理员在与 artifacthub-shim 监视命名空间不同的命名空间中拥有 repository ConfigMap,但 catalog 仍应全局可见时,请使用此模式。默认情况下已启用全局 repository ConfigMap 发现功能,并覆盖所有命名空间。在启用此功能期间,chart 会授予 artifacthub-shim 对 ConfigMaps、引用的 Secrets 和 Events 的集群级读访问权限。

apiVersion: v1
kind: ConfigMap
metadata:
  name: team-b-global-catalogs
  namespace: team-b-system
  labels:
    artifacthub-shim.alauda.io/repository: "true"
    artifacthub-shim.alauda.io/repository-visibility: "global"
data:
  repository.yaml: |
    gitRepositories:
      - url: https://git.example.com/team-b/tekton-catalog.git
        revision: main
        credentialRef:
          name: team-b-git-credential
        repositories:
          - name: team-b-global-tasks
            displayName: Team B Global Tasks
            kind: task
            path: task

如果设置了 credentialRef.name,则会在与 repository ConfigMap 相同的命名空间中解析 Secret。跨命名空间源命名空间中的 Secret 变更会在下一次 repository 刷新时被拾取;更新 repository ConfigMap 也会立即触发刷新。

按命名空间作用域的 Repository ConfigMap

这是主监视命名空间之外的 repository ConfigMaps 的默认行为。只有来自 team-a 的 workloads 和感知命名空间的 UI 请求可以使用该 catalog。

metadata:
  namespace: team-a
  labels:
    artifacthub-shim.alauda.io/repository: "true"
    artifacthub-shim.alauda.io/repository-visibility: "namespace"

按项目作用域的 Repository ConfigMap

所有其 cpaas.io/project 标签等于所有者 Namespace 标签值的 Namespaces 都可以使用该 catalog。如果所有者没有 project 标签,则该作用域无效。

metadata:
  namespace: team-a
  labels:
    artifacthub-shim.alauda.io/repository: "true"
    artifacthub-shim.alauda.io/repository-visibility: "project"

精确 Namespace 允许列表

该注解会覆盖任何 globalprojectnamespace 标签:

metadata:
  namespace: team-a
  labels:
    artifacthub-shim.alauda.io/repository: "true"
    artifacthub-shim.alauda.io/repository-visibility: "project"
  annotations:
    artifacthub-shim.alauda.io/repository-visible-namespaces: team-a,team-c

作用域限定的 ConfigMaps 不得声明 extraResourcescredentialRef 始终会在 repository ConfigMap 所在的 Namespace 中解析 Secret,且不能引用其他 Namespace 中的 Secret。

感知命名空间的 UI API 会在搜索、分页、批量查询和内容读取之前过滤 Task、Pipeline 和 StepAction 记录。Hub ResolutionRequest 的创建也会由扩展的 validating webhook 进行检查。被拒绝的请求会返回 CATALOG_VISIBILITY_DENIED;未知 catalog 和内部策略错误会被放行,以便 Hub resolver 返回其原生结果。

支持的 kind 值:

KindTekton 资源
taskTask
pipelinePipeline
stepactionStepAction

支持的顶层 repository.yaml 字段:

字段是否必需描述
gitRepositories要从此 ConfigMap 注册的 Git 源列表。

支持的 gitRepositories[] 字段:

字段是否必需描述
urlGit 仓库 URL。
revision要检出分支、标签或提交。
credentialRef.name包含 Git 凭证的 Secret 名称。
repositories从该 Git 源加载的 catalog 仓库。除非设置了 extraResources,否则为必需。
extraResources从该 Git 源同步的 ConfigMap 资源目录。除非设置了 repositories,否则为必需。

支持的 gitRepositories[].repositories[] 字段:

字段是否必需描述
nameresolver 和 API 路径使用的稳定 catalog 名称。请将此值用作 hub resolver 的 catalog 参数。
displayName供人类阅读的 catalog 名称。
kindtaskpipelinestepaction 之一。
pathGit 仓库内相对的 catalog 路径。
disabledPackages仓库本地的 package 或 version 禁用规则。
optional当为 true 时,缺失或为空的 path 会以 Ready 状态发布,且包含零个 packages。默认值为 false
legacyCatalogAliases迁移期间用于解析到此仓库的历史 catalog 名称。API 响应仍会返回规范化的 name

可选 kind 路径和历史 catalog 别名

仅当仓库条目有意表示一个可能尚不存在的 kind 目录时,才使用 optional: true。这主要适用于迁移后的 Tekton Hub catalogs,其中旧 catalog 可能只有 task/、只有 pipeline/,或者混合覆盖不同 kind。对于手写的仓库条目,严格校验仍然是默认行为。

legacyCatalogAliases 用于在迁移期间保留旧的 resolver 引用。别名按 kind 作用域划分:某个 Pipeline 别名不会解析同名的 Tasks。自引用别名会被忽略。如果某个别名指向多个仓库,或与该 kind 的另一个规范仓库名称冲突,shim 只会禁用该别名,并保持所有规范仓库处于 Ready 状态。

迁移后的示例 catalog:

gitRepositories:
  - url: https://git.example.com/team-a/tekton-hub-catalog.git
    revision: main
    repositories:
      - name: team-a
        displayName: Team A Tasks
        kind: task
        path: task
        optional: true
      - name: team-a-pipelines
        displayName: Team A Pipelines
        kind: pipeline
        path: pipeline
        optional: true
        legacyCatalogAliases:
          - team-a
      - name: team-a-stepactions
        displayName: Team A StepActions
        kind: stepaction
        path: stepaction
        optional: true

在此配置下,仍然使用 catalog: team-a 的旧 Pipeline 引用会解析到规范仓库 team-a-pipelines。新的引用应直接使用 catalog: team-a-pipelines

支持的 gitRepositories[].extraResources[] 字段:

字段是否必需描述
pathGit 仓库内相对的资源目录路径。该目录会被递归扫描。

ConfigMap 资源同步

目前,extraResources 只会导入 apiVersion: v1kind: ConfigMap 的文档,并且这些文档必须通过将 metadata.labels["artifacthub-shim.alauda.io/import"] 设置为 "true" 来显式启用。请将此标签添加到存储在 Git 仓库中的 ConfigMap YAML。未加标签的 ConfigMaps、非 ConfigMap 资源以及无关文件都会被跳过。每个被导入的 ConfigMap 都必须设置 metadata.namemetadata.namespace。该 namespace 必须列在 config.extraResourceSync.allowedNamespaces 中;chart 默认值为 kube-public

apiVersion: v1
kind: ConfigMap
metadata:
  name: team-a-tool-image
  namespace: kube-public
  labels:
    artifacthub-shim.alauda.io/import: "true"
data:
  image: registry.example.com/team-a/tool:v1

资源路径必须始终位于 Git 仓库 checkout 范围内。资源扫描期间不会跟随 symbolic links。

资源同步控制器会自动为同步到集群内的 ConfigMaps 打上 artifacthub-shim 所有权标签,例如 artifacthub-shim.alauda.io/controller-namespaceartifacthub-shim.alauda.io/controller-nameartifacthub-shim.alauda.io/resource-set。如果某个同名 ConfigMap 已存在但不具备匹配的所有权标签,artifacthub-shim 会跳过它,且绝不会接管或覆盖它。

当两个资源源声明了同一个期望的 ConfigMap 时,冲突会按 ConfigMap 对象级别处理。同一来源中的其他 ConfigMaps 会继续同步。如果内置 catalog 声明了这些重复项中的一个,则以内置 catalog 版本为准;否则,重复的 ConfigMap 会被跳过,直到源 manifests 被改为唯一为止。

当某个已同步的 ConfigMap 从源目录中消失时,artifacthub-shim 会将其从集群中删除。若要在该 ConfigMap 从 Git 中移除后仍保留它,请向集群内的 ConfigMap 添加此注解:

metadata:
  annotations:
    artifacthub-shim.alauda.io/resource-policy: keep

支持的凭证

所引用的 Secret 可以包含以下一个或多个键:

Secret 键用途
usernameHTTPS 用户名。
passwordHTTPS 密码。
tokenHTTPS 令牌。当 password 为空时,会作为密码使用。
sshPrivateKeySSH 私钥。
ssh-privatekeySSH 私钥键名的另一种写法。
known_hostsSSH known hosts 内容。当设置了 sshPrivateKeyssh-privatekey 时必需。
ca.crt内部 HTTPS Git 服务器的 CA bundle。

每个 Git 仓库都可以引用不同的 Secret。

示例

公共 HTTPS 仓库

当 Git 仓库不需要认证时,请使用此模式。

apiVersion: v1
kind: ConfigMap
metadata:
  name: artifacthub-shim-public-tasks
  namespace: artifacthub-shim-system
  labels:
    artifacthub-shim.alauda.io/repository: "true"
data:
  repository.yaml: |
    gitRepositories:
      - url: https://git.example.com/platform/public-tekton-catalog.git
        revision: main
        repositories:
          - name: public-tasks
            displayName: Public Tasks
            kind: task
            path: task

带 Token 的 HTTPS 仓库

对于通过 HTTPS 接受 personal access token 或 deploy token 的 Git 提供方,请使用 token。当省略 username 时,artifacthub-shim 会在 Git 凭证提示中使用 oauth2 作为用户名。

apiVersion: v1
kind: Secret
metadata:
  name: team-a-token
  namespace: artifacthub-shim-system
type: Opaque
stringData:
  token: <git-token>
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: artifacthub-shim-team-a-tasks
  namespace: artifacthub-shim-system
  labels:
    artifacthub-shim.alauda.io/repository: "true"
data:
  repository.yaml: |
    gitRepositories:
      - url: https://git.example.com/team-a/tekton-catalog.git
        revision: main
        credentialRef:
          name: team-a-token
        repositories:
          - name: team-a-tasks
            displayName: Team A Tasks
            kind: task
            path: task

带用户名和密码的 HTTPS 仓库

当你的 Git 服务器需要用户名和密码组合时,请使用此模式。

apiVersion: v1
kind: Secret
metadata:
  name: team-b-basic-auth
  namespace: artifacthub-shim-system
type: Opaque
stringData:
  username: <git-username>
  password: <git-password>
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: artifacthub-shim-team-b-pipelines
  namespace: artifacthub-shim-system
  labels:
    artifacthub-shim.alauda.io/repository: "true"
data:
  repository.yaml: |
    gitRepositories:
      - url: https://git.example.com/team-b/tekton-catalog.git
        revision: release-1.0
        credentialRef:
          name: team-b-basic-auth
        repositories:
          - name: team-b-pipelines
            displayName: Team B Pipelines
            kind: pipeline
            path: pipeline

使用 known_hosts 的 SSH 仓库

用于 SSH 认证时,请使用 sshPrivateKeyssh-privatekey。Secret 还必须提供 known_hosts;默认启用严格的主机密钥验证。

apiVersion: v1
kind: Secret
metadata:
  name: team-c-ssh
  namespace: artifacthub-shim-system
type: Opaque
stringData:
  sshPrivateKey: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    <private-key>
    -----END OPENSSH PRIVATE KEY-----
  known_hosts: |
    git.example.com ssh-ed25519 <host-key>
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: artifacthub-shim-team-c-stepactions
  namespace: artifacthub-shim-system
  labels:
    artifacthub-shim.alauda.io/repository: "true"
data:
  repository.yaml: |
    gitRepositories:
      - url: ssh://git@git.example.com/team-c/tekton-catalog.git
        revision: main
        credentialRef:
          name: team-c-ssh
        repositories:
          - name: team-c-stepactions
            displayName: Team C StepActions
            kind: stepaction
            path: stepaction

带内部 CA 的 HTTPS 仓库

当 Git 服务器提供由内部 CA 签名的证书时,请使用 ca.crt。你可以在同一个 Secret 中将 ca.crttokenusernamepassword 组合使用。

apiVersion: v1
kind: Secret
metadata:
  name: internal-git-token
  namespace: artifacthub-shim-system
type: Opaque
stringData:
  token: <git-token>
  ca.crt: |
    -----BEGIN CERTIFICATE-----
    <ca-certificate>
    -----END CERTIFICATE-----
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: artifacthub-shim-internal-tasks
  namespace: artifacthub-shim-system
  labels:
    artifacthub-shim.alauda.io/repository: "true"
data:
  repository.yaml: |
    gitRepositories:
      - url: https://git.internal.example.com/devops/tekton-catalog.git
        revision: main
        credentialRef:
          name: internal-git-token
        repositories:
          - name: internal-tasks
            displayName: Internal Tasks
            kind: task
            path: task

与 Hub Resolver 一起使用

嵌套的 repositories[].name 是 hub resolver 使用的 catalog 值。例如,上面声明的 team-a-tasks 仓库会通过 catalog: team-a-tasks 来使用:

apiVersion: tekton.dev/v1
kind: TaskRun
metadata:
  name: run-team-a-task
spec:
  taskRef:
    resolver: hub
    params:
      - name: type
        value: artifact
      - name: catalog
        value: team-a-tasks
      - name: kind
        value: task
      - name: name
        value: run-script
      - name: version
        value: "0.1.0"
  params:
    - name: script
      value: echo docs-verify

验证

在应用 ConfigMap 和可选的 Secret 之后,请检查 repository ConfigMap 上的 Events:

kubectl describe configmap artifacthub-shim-team-a-catalogs \
  -n artifacthub-shim-system

期望的 Events:

  • RepositoryConfigAccepted 表示 repository.yaml 已被接受。
  • RepositorySourceReady 表示 repository source 已完成索引,现在对 DevOps Hub UI 和 hub resolver 客户端可见。

你也可以直接列出最近的 repository ConfigMap Events:

kubectl get events -n artifacthub-shim-system \
  --field-selector involvedObject.kind=ConfigMap,involvedObject.name=artifacthub-shim-team-a-catalogs

如果该 repository 没有变得可见,请先检查是否存在 RepositoryConfigInvalidRepositorySourceInvalidRepositorySourceDegraded Events。将 artifacthub-shim pod 日志作为辅助来源,以获取完整的 Git 或 manifest 解析细节。

对于持续存在的 Warning 状态,artifacthub-shim 会在每次刷新或资源同步尝试时再次记录该 Warning。Kubernetes 通常会将其保留为一个 Event,并增加计数和更新最后时间戳。如果 event TTL 清理移除了之前的 Event,那么下一次尝试可以再次创建它。

Kubernetes Events 仍然属于历史记录,在 event TTL 清理之前可能会保留较旧的 Warning 条目。在判断当前配置是否健康时,请优先查看最新的 repository Event 和 /api/v1/snapshot source 状态。

了解更多