将 Helm 图表推送和提取到 Azure 容器注册表

若要快速地管理和部署适用于 Kubernetes 的应用程序,可以使用开放源代码 Helm 包管理器。 在使用 Helm 的情况下,应用程序包会定义为图表,这些图表会收集并存储到 Helm 图表存储库中。

本文介绍如何使用 Helm 3 命令并将图表存储为OCI 项目,以在 Azure 容器注册表中托管 Helm 图表存储库。 在许多情况下,你需要为你开发的应用程序生成并上传自己的图表。 有关如何生成自己的 Helm 图表的详细信息,请参阅图表模板开发人员指南。 还可以从另一个 Helm 存储库存储现有的 Helm 图表。

重要

本文已使用 Helm 3 命令进行了更新。 Helm 3.7 包含对 Helm CLI 命令的更改,以及 Helm 3 早期版本中引入的 OCI 支持。 按照设计,helm 会随版本一起升级。 建议使用 3.7.2 或更高版本。

要使用 Helm 3 还是 Helm 2?

若要存储、管理和安装 Helm 图表,请使用 Helm CLI 中的命令。 主要 Helm 版本包括 Helm 3 和 Helm 2。 有关版本差异的详细信息,请参阅版本常见问题解答

Helm 3 应用于在 Azure 容器注册表中托管 Helm 图表。 使用 Helm 3 可以:

  • 在 Azure 容器注册表中存储和管理存储库中的 Helm 图表
  • 将 Helm 图表作为 OCI 项目存储在注册表中。 Azure 容器注册表为 OCI 项目提供包括 Helm 图表在内的 GA 支持。
  • 使用 helm registry loginaz acr login 命令向注册表进行身份验证。
  • 使用 helm 命令在注册表中推送、拉取和管理 Helm 图表
  • 使用 helm install 从注册表将 chart 安装到 Kubernetes 群集。

功能支持

Azure 容器注册表支持特定 Helm 图表管理功能,具体取决于你使用的是 Helm 3(当前)还是 Helm 2(不推荐使用)。

功能 Helm 2 Helm 3
使用 az acr helm 命令管理图表
将图表存储为 OCI 项目
使用 az acr repository 命令和 Azure 门户中的“存储库”边栏选项卡管理图表

注意

从 Helm 3 开始,将弃用与 Helm 2 客户端一起使用的 az acr helm 命令。 在删除命令之前,将至少提前 3 个月发出通知。

图表版本兼容性

以下 Helm 图表版本可以存储在 Azure 容器注册表中,并可通过 Helm 2 和 Helm 3 客户端进行安装。

版本 Helm 2 Helm 3
apiVersion v1
apiVersion v2

从 Helm 2 迁移到 Helm 3

如果以前使用 Helm 2 和 Azure 容器注册表存储和部署了图表,我们建议迁移到 Helm 3。 请参阅:

先决条件

本文中的方案需要以下资源:

  • Azure 订阅中有一个 Azure 容器注册表。 如果需要,请使用 Azure 门户Azure CLI 创建一个注册表。
  • Helm 客户端 3.7 或更高版本 - 运行 helm version 可查找当前版本。 有关如何安装和升级 Helm 的详细信息,请参阅安装 Helm。 如果从早期版本的 Helm 3 升级,请查看发行说明
  • 要在其中安装 Helm 图表的 Kubernetes 群集。 如果需要,可以使用 Azure CLIAzure PowerShellMicrosoft Azure 门户创建 AKS 群集。
  • Azure CLI 2.0.71 或更高版本 - 运行 可查看版本。 如果需要进行安装或升级,请参阅安装 Azure CLI

设置 Helm 客户端

使用 helm version 命令来验证已安装 Helm 3:

helm version

注意

指示的版本必须至少为 3.8.0,因为早期版本中的 OCI 支持是试验性的。

为目标注册表设置以下环境变量。 ACR_NAME 是注册表资源名称。 如果 ACR 注册表 URL 为 myregistry.azurecr.cn,则将 ACR_NAME 设置为 myregistry

ACR_NAME=<container-registry-name>

创建示例图表

使用以下命令创建测试图表:

mkdir helmtest

cd helmtest
helm create hello-world

在此简单示例中,请将目录切换到 templates 文件夹,并先删除其中的内容:

cd hello-world/templates
rm -rf *

templates 文件夹中,通过运行以下命令,创建一个名为 configmap.yaml 的文件:

cat <<EOF > configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: hello-world-configmap
data:
  myvalue: "Hello World"
EOF

有关创建和运行此示例的详细信息,请参阅 Helm 文档中的入门

将 chart 保存到本地存档

将目录切换到 hello-world 子目录。 然后,运行 helm package 以将 chart 保存到本地存档。

在以下示例中,chart 使用 Chart.yaml 中的名称和版本进行保存。

cd ..
helm package .

输出类似于:

Successfully packaged chart and saved it to: /my/path/hello-world-0.1.0.tgz

向注册表进行身份验证

运行 helm registry login 以向注册表进行身份验证。 你可以传递适用于你的方案的注册表凭据,例如服务主体凭据、用户标识或存储库范围的令牌。

  • 使用 Microsoft Entra 的具有拉取和推送权限的服务主体(AcrPush 角色)向注册表进行身份验证。

    SERVICE_PRINCIPAL_NAME=<acr-helm-sp>
    ACR_REGISTRY_ID=$(az acr show --name $ACR_NAME --query id --output tsv)
    PASSWORD=$(az ad sp create-for-rbac --name $SERVICE_PRINCIPAL_NAME \
            --scopes $(az acr show --name $ACR_NAME --query id --output tsv) \
             --role acrpush \
            --query "password" --output tsv)
    USER_NAME=$(az identity show -n $SERVICE_PRINCIPAL_NAME -g $RESOURCE_GROUP_NAME --subscription $SUBSCRIPTION_ID --query "clientId" -o tsv)
    
  • 使用个人 Microsoft Entra 标识进行身份验证,以使用 AD 令牌推送和拉取 Helm chart。

    USER_NAME="00000000-0000-0000-0000-000000000000"
    PASSWORD=$(az acr login --name $ACR_NAME --expose-token --output tsv --query accessToken)
    
  • 使用存储库范围内的令牌进行身份验证(预览版)

    USER_NAME="helmtoken"
    PASSWORD=$(az acr token create -n $USER_NAME \
                    -r $ACR_NAME \
                    --scope-map _repositories_admin \
                    --only-show-errors \
                    --query "credentials.passwords[0].value" -o tsv)
    
  • 然后,将凭据提供给 helm registry login

    helm registry login $ACR_NAME.azurecr.cn \
      --username $USER_NAME \
      --password $PASSWORD
    

将 chart 作为 OCI 项目推送到注册表

在 Helm 3 CLI 中运行 helm push 命令,以将 chart 存档推送到完全限定的目标存储库。 请分隔图表名称中的单词,并且仅使用小写字母和数字。 在以下示例中,目标存储库命名空间为 helm/hello-world,chart 被标记为 0.1.0

helm push hello-world-0.1.0.tgz oci://$ACR_NAME.azurecr.cn/helm

成功推送后,输出将类似于:

Pushed: <registry>.azurecr.cn/helm/hello-world:0.1.0
digest: sha256:5899db028dcf96aeaabdadfa5899db02589b2899b025899b059db02

在存储库中列出图表

与 Azure 容器注册表中存储的映像一样,可以使用 az acr repository 命令来显示托管图表、图表标记和清单的存储库。

例如,运行 az acr repository show 可以查看在上一步骤中创建的存储库的属性:

az acr repository show \
  --name $ACR_NAME \
  --repository helm/hello-world

输出类似于:

{
  "changeableAttributes": {
    "deleteEnabled": true,
    "listEnabled": true,
    "readEnabled": true,
    "writeEnabled": true
  },
  "createdTime": "2021-10-05T12:11:37.6701689Z",
  "imageName": "helm/hello-world",
  "lastUpdateTime": "2021-10-05T12:11:37.7637082Z",
  "manifestCount": 1,
  "registry": "mycontainerregistry.azurecr.cn",
  "tagCount": 1
}

运行 az acr manifest list-metadata 命令以查看存储在存储库中的图表的详细信息。 例如:

az acr manifest list-metadata \
  --registry $ACR_NAME \
  --name helm/hello-world

输出(在此示例中已缩略)显示 configMediaTypeapplication/vnd.cncf.helm.config.v1+json

[
  {
    [...]
    "configMediaType": "application/vnd.cncf.helm.config.v1+json",
    "createdTime": "2021-10-05T12:11:37.7167893Z",
    "digest": "sha256:0c03b71c225c3ddff53660258ea16ca7412b53b1f6811bf769d8c85a1f0663ee",
    "imageSize": 3301,
    "lastUpdateTime": "2021-10-05T12:11:37.7167893Z",
    "mediaType": "application/vnd.oci.image.manifest.v1+json",
    "tags": [
      "0.1.0"
    ]

安装 Helm 图表

运行 helm install 以安装已推送到注册表的 Helm chart。 使用 --version 参数传递 chart 标记。 指定版本名称(例如 myhelmtest)或传递 参数。 例如:

helm install myhelmtest oci://$ACR_NAME.azurecr.cn/helm/hello-world --version 0.1.0

成功安装图表后,输出将类似于:

NAME: myhelmtest
LAST DEPLOYED: Tue Oct  4 16:59:51 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

若要验证安装,请运行 helm get manifest 命令。

helm get manifest myhelmtest

该命令将返回 configmap.yaml 模板文件中的 YAML 数据。

运行 helm uninstall 以卸载群集上的图表版本:

helm uninstall myhelmtest

将 chart 拉取到本地存档

可以选择使用 helm pull 将 chart 从容器注册表拉取到本地存档。 使用 --version 参数传递 chart 标记。 如果当前路径存在本地存档,则此命令会覆盖它。

helm pull oci://$ACR_NAME.azurecr.cn/helm/hello-world --version 0.1.0

从注册表中删除图表

若要从容器注册表中删除图表,请使用 az acr repository delete 命令。 运行以下命令,并在出现提示时确认操作:

az acr repository delete --name $ACR_NAME --image helm/hello-world:0.1.0

迁移注册表以存储 Helm OCI 项目

如果之前是使用 Helm 2 和 az acr helm 命令将 Azure 容器注册表设置为图表存储库,建议az acr helm到 Helm 3 客户端。 然后,按照以下步骤将图表存储为注册表中的 OCI 项目。

重要

  • 完成从 Helm 2 样式(基于 index.yaml)的图表存储库到 OCI 项目存储库的迁移后,请使用 Helm CLI 和 az acr repository 命令管理这些图表。 请参阅本文的先前部分。
  • 使用 helm searchhelm repo list 等 Helm 命令无法发现 Helm OCI 项目存储库。 有关用于将图表存储为 OCI 项目的 Helm 命令的详细信息,请参阅 Helm 文档

启用 OCI 支持(在 Helm v3.8.0 中默认情况下已启用)

确保你使用的是 Helm 3 客户端:

helm version

如果使用的是 Helm v3.8.0 或更高版本,则此功能在默认情况下已启用。 如果使用的是较低版本,则可以通过设置环境变量来启用 OCI 支持:

export HELM_EXPERIMENTAL_OCI=1

列出当前图表

列出注册表中当前存储的图表,此处命名为 myregistry:

helm search repo myregistry

输出显示图表和图表版本:

NAME                            CHART VERSION   APP VERSION     DESCRIPTION                                       
myregistry/ingress-nginx        3.20.1          0.43.0          Ingress controller for Kubernetes...
myregistry/wordpress            9.0.3           5.3.2           Web publishing platform for building...
[...]

在本地拉取 chart 存档

对于存储库中的每个 chart,请在本地拉取 chart 存档,并记下文件名:

helm pull myregisry/ingress-nginx
ls *.tgz

将创建一个本地 chart 存档,例如 ingress-nginx-3.20.1.tgz

将 chart 作为 OCI 项目推送到注册表

登录到注册表:

az acr login --name $ACR_NAME

将每个 chart 存档推送到注册表。 示例:

helm push ingress-nginx-3.20.1.tgz oci://$ACR_NAME.azurecr.cn/helm

推送图表后,确认其存储在注册表中:

az acr repository list --name $ACR_NAME

推送完所有图表后,可以选择从注册表中删除 Helm 2 样式的图表存储库。 这样做可以减少注册表中的存储:

helm repo remove $ACR_NAME

后续步骤