使用基于OCI的注册中心

从Helm 3开始,可以使用具有 OCI支持的容器注册中心来存储和共享chart包。从Helm v3.8.0开始,默认启用OCI支持。

v3.8.0版本之前对 OCI 的支持

OCI 支持在Helm v3.8.0版本从试验阶段过渡成为普遍可用。在之前版本中,对OCI支持会有不同的地方。如果你在v3.8.0之前的版本使用OCI,需要着重了解不同Helm版本之间OCI的变化。

在v3.8.0之前的版本启用OCI支持

Helm v3.8.0版本之前, OCI支持是试验性的且必须显式启用。

为了在之前版本中启用OCI试验性支持,需要在环境变量中设置HELM_EXPERIMENTAL_OCI,例如:

export HELM_EXPERIMENTAL_OCI=1

OCI在v3.8.0中的弃用和行为变化

Helm v3.8.0版本中,以下行为和特性与之前版本不同:

  • 在依赖中将chart设置为OCI时,版本号可以像其他依赖一样设置成范围。
  • 包含构建信息的SemVer tag可以被推送和使用。OCI注册中心的tag字符不支持+。如果有,Helm会将+ 转成 _
  • helm registry login 命令现在采用与Docker CLI相同的结构存储凭证。Helm和Docker CLI的注册表配置使用一样的路径。

OCI在v3.7.0中的弃用和行为变化

Helm v3.7.0版本包含了针对支持OCI的 HIP 6执行策略。因此以下行为和特性与之前版本不同:

  • 移除了 helm chart 子命令。
  • 移除了chart缓存(没有了 helm chart list 等等)。
  • OCI注册引用现在需要以 oci:// 开头。
  • 注册引用的基础名称必须和chart名称匹配。
  • 注册引用的tag必须和chart的语义版本匹配(比如没有latest这种tag)。
  • chart层的媒体类型从application/tar+gzip转换成了application/vnd.cncf.helm.chart.content.v1.tar+gzip

使用基于OCI的注册中心

基于OCI注册中心的Helm仓库

Helm 仓库是一种制作和分发打包好的Helm chart的方式。基于OCI的的注册中心包含0个或多个Helm仓库,且每个都会有0个或多个Helm chart。

使用托管的注册中心

以下是几种chart可以使用的托管容器注册中心,都支持OCI,例如:

参照托管平台提供的文档来创建和配置支持OCI的注册中心。

注: 你可以在开发电脑上运行基于OCI的注册中心 Docker Registry 或者 zot。在开发电脑上运行只能用于测试目的。

用于处理注册中心的命令

registry 子命令

login

登录到注册中心 (手动输入密码)

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

logout

从注册中心注销

$ helm registry logout localhost:5000
Logout succeeded

The push 子命令

上传chart到基于OCI的注册中心

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

push子命令只能用于helm package提前创建的.tgz文件。

使用helm push上传chart到OCI注册表时,引用必须以oci://开头,且不能包含基础名称或tag。

注册表引用的基础名称是由chart名称推断而来,tag是由chart语义版本推断而来。现在是强制要求。

某些注册表(如果指定)要求事先创建仓库或者命名空间,或者两者都需要创建。否则,helm push 会出现错误。

如果您已经创建了一个 源文件 (.prov), 且和.tgz文件在同一文件下,会通过push自动上传到注册表。会在 Helm chart manifest生成一个额外的层。

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

其他命令

oci://协议的支持同样适用于很多其他子命令。以下是完整列表:

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

注册表的基础名称(chart name)包含了涉及chart下载的任意类型的操作。(相对于helm push被省略的位置)。

下面是一些基于OCI的chart使用上述子命令的示例:

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

$ helm show all oci://localhost: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://localhost:5000/helm-charts/mychart --version 0.1.0
---
# Source: mychart/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
...

$ helm install myrelease oci://localhost: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://localhost: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:
...

指定依赖项

chart的依赖项可用从使用了dependency update命令的注册中心拉取。

Chart.yaml中给定的repository被指定为没有基础名称注册表引用:

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

这会在执行dependency update时获取oci://localhost:5000/myrepo/mychart:2.7.0

Helm chart manifest

在注册表中表示的Helm chart manifest示例(注意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
    }
  ]
}

从chart仓库迁移

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