使用基于 OCI 的注册表

从 Helm 3 开始,您可以使用支持 OCI 的容器注册表来存储和共享图表包。从 Helm v3.8.0 开始,默认情况下启用 OCI 支持。

v3.8.0 之前的 OCI 支持

OCI 支持已从 Helm v3.8.0 的实验性阶段毕业到一般可用性阶段。在之前的 Helm 版本中,OCI 支持的行为有所不同。如果您在 Helm v3.8.0 之前使用过 OCI 支持,那么了解不同 Helm 版本中的变化非常重要。

在 v3.8.0 之前启用 OCI 支持

在 Helm v3.8.0 之前,OCI 支持是实验性的,必须启用。

要为 v3.8.0 之前的 Helm 版本启用 OCI 实验性支持,请在您的环境中设置 HELM_EXPERIMENTAL_OCI。例如

export HELM_EXPERIMENTAL_OCI=1

v3.8.0 的 OCI 功能弃用和行为变更

发布 Helm v3.8.0 之后,以下功能和行为与之前的 Helm 版本不同

  • 在将依赖项中的图表设置为 OCI 时,版本可以设置为与其他依赖项相同的范围。
  • 包含构建信息的 SemVer 标签可以被推送和使用。OCI 注册表不支持 + 作为标签字符。Helm 在将 + 存储为标签时将其转换为 _
  • helm registry login 命令现在遵循与 Docker CLI 相同的结构来存储凭据。相同的注册表配置位置可以传递给 Helm 和 Docker CLI。

v3.7.0 的 OCI 功能弃用和行为变更

发布 Helm v3.7.0 包括对 HIP 6 的 OCI 支持的实现。因此,以下功能和行为与之前的 Helm 版本不同

  • helm chart 子命令已被移除。
  • 图表缓存已被移除(没有 helm chart list 等)。
  • OCI 注册表引用现在总是以 oci:// 为前缀。
  • 注册表引用的基名必须始终与图表的名称匹配。
  • 注册表引用的标签必须始终与图表的语义版本匹配(即没有 latest 标签)。
  • 图表层媒体类型已从 application/tar+gzip 切换到 application/vnd.cncf.helm.chart.content.v1.tar+gzip

使用基于 OCI 的注册表

基于 OCI 的注册表中的 Helm 库

一个 Helm 库 是一种容纳和分发打包的 Helm 图表的方式。基于 OCI 的注册表可以包含零个或多个 Helm 库,每个库可以包含零个或多个打包的 Helm 图表。

使用托管注册表

有几个支持 OCI 的托管容器注册表可用于您的 Helm 图表。例如

按照托管容器注册表提供商的文档创建和配置一个支持 OCI 的注册表。

注意:您可以在开发计算机上运行 Docker Registryzot,它们是基于 OCI 的注册表。在开发计算机上运行基于 OCI 的注册表仅应用于测试目的。

使用 sigstore 对基于 OCI 的图表进行签名

helm-sigstore 插件允许使用 Sigstore 使用与用于签名容器镜像的相同工具对 Helm 图表进行签名。这为经典的 图表库 支持的 基于 GPG 的出处 提供了一种替代方案。

有关使用 helm sigstore 插件的更多详细信息,请参见 该项目的文档

用于处理注册表的命令

registry 子命令

登录

登录到注册表(使用手动密码输入)

$ helm registry login -u myuser localhost:5000
Password:
Login succeeded

注销

从注册表注销

$ helm registry logout localhost:5000
Logout succeeded

push 子命令

将图表上传到基于 OCI 的注册表

$ helm push mychart-0.1.0.tgz oci://127.0.0.1:5000/helm-charts
Pushed: localhost:5000/helm-charts/mychart:0.1.0
Digest: sha256:ec5f08ee7be8b557cd1fc5ae1a0ac985e8538da7c93f51a51eff4b277509a723

push 子命令只能用于针对使用 helm package 预先创建的 .tgz 文件。

使用 helm push 将图表上传到 OCI 注册表时,引用必须以 oci:// 为前缀,并且不能包含基名或标签。

注册表引用基名从图表的名称推断出来,标签从图表的语义版本推断出来。这目前是一个严格的要求。

某些注册表要求在之前创建存储库和/或命名空间(如果指定)。否则,在 helm push 操作期间将产生错误。

如果您创建了一个 出处文件 (.prov),并且它与图表 .tgz 文件位于同一位置,那么它将在 push 时自动上传到注册表。这会导致 Helm 图表清单 上增加一层。

helm-push 插件 的用户(用于将图表上传到 ChartMuseum)可能会遇到问题,因为该插件与新的内置 push 冲突。从 v0.10.0 版本开始,该插件已重命名为 cm-push

其他子命令

oci:// 协议的支持也适用于其他各种子命令。以下列出了所有支持的子命令:

  • helm pull
  • helm show
  • helm template
  • helm install
  • helm upgrade

注册表引用的基名(图表名称)包含在任何涉及图表下载的操作中(与 helm push 不同,它省略了基名)。

以下是针对基于 OCI 的图表使用上面列出的子命令的一些示例

$ helm pull oci://127.0.0.1:5000/helm-charts/mychart --version 0.1.0
Pulled: localhost:5000/helm-charts/mychart:0.1.0
Digest: sha256:0be7ec9fb7b962b46d81e4bb74fdcdb7089d965d3baca9f85d64948b05b402ff

$ helm show all oci://127.0.0.1:5000/helm-charts/mychart --version 0.1.0
apiVersion: v2
appVersion: 1.16.0
description: A Helm chart for Kubernetes
name: mychart
...

$ helm template myrelease oci://127.0.0.1:5000/helm-charts/mychart --version 0.1.0
---
# Source: mychart/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
...

$ helm install myrelease oci://127.0.0.1:5000/helm-charts/mychart --version 0.1.0
NAME: myrelease
LAST DEPLOYED: Wed Oct 27 15:11:40 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
...

$ helm upgrade myrelease oci://127.0.0.1:5000/helm-charts/mychart --version 0.2.0
Release "myrelease" has been upgraded. Happy Helming!
NAME: myrelease
LAST DEPLOYED: Wed Oct 27 15:12:05 2021
NAMESPACE: default
STATUS: deployed
REVISION: 2
NOTES:
...

指定依赖项

可以使用 dependency update 子命令从注册表中拉取图表的依赖项。

Chart.yaml 中给定条目中的 repository 指定为注册表引用,不包含基名

dependencies:
  - name: mychart
    version: "2.7.0"
    repository: "oci://127.0.0.1:5000/myrepo"

当执行 dependency update 时,这将获取 oci://127.0.0.1:5000/myrepo/mychart:2.7.0

Helm 图表清单

注册表中表示的示例 Helm 图表清单(注意 mediaType 字段)

{
  "schemaVersion": 2,
  "config": {
    "mediaType": "application/vnd.cncf.helm.config.v1+json",
    "digest": "sha256:8ec7c0f2f6860037c19b54c3cfbab48d9b4b21b485a93d87b64690fdb68c2111",
    "size": 117
  },
  "layers": [
    {
      "mediaType": "application/vnd.cncf.helm.chart.content.v1.tar+gzip",
      "digest": "sha256:1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617",
      "size": 2487
    }
  ]
}

以下示例包含一个 出处文件(注意额外的层)

{
  "schemaVersion": 2,
  "config": {
    "mediaType": "application/vnd.cncf.helm.config.v1+json",
    "digest": "sha256:8ec7c0f2f6860037c19b54c3cfbab48d9b4b21b485a93d87b64690fdb68c2111",
    "size": 117
  },
  "layers": [
    {
      "mediaType": "application/vnd.cncf.helm.chart.content.v1.tar+gzip",
      "digest": "sha256:1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617",
      "size": 2487
    },
    {
      "mediaType": "application/vnd.cncf.helm.chart.provenance.v1.prov",
      "digest": "sha256:3e207b409db364b595ba862cdc12be96dcdad8e36c59a03b7b3b61c946a5741a",
      "size": 643
    }
  ]
}

从图表库迁移

从经典的 图表库(基于 index.yaml 的库)迁移就像使用 helm pull 一样简单,然后使用 helm push 将生成的 .tgz 文件上传到注册表。