为 Kubernetes 应用准备 Azure 容器技术资产

本文提供技术资源和建议,以帮助你在 Azure 市场上为 Kubernetes 应用程序创建容器产品/服务。

有关基于 Kubernetes 应用的容器产品/服务所需技术资产的综合示例,请参阅适用于 Kubernetes 的 Azure 市场容器产品/服务示例

基础技术知识

设计、生成和测试这些资产需要一些时间,并在 Azure 平台和用于生成套餐的技术方面有一定的专业知识。

除了解决方案领域以外,工程团队还应该了解以下 Microsoft 技术:

先决条件

  • 你的应用程序必须基于 Helm 图表。

  • 如果你有多个图表,则可以将其他 helm 图表作为子图包含在主 helm 图表之外。

  • 所有映像引用和摘要详细信息必须包含在图表中。 在运行时无法下载其他图表或图像。

  • 必须具有一个有效的发布租户,或者有权访问发布租户和合作伙伴中心帐户。

  • 必须已创建属于上述活动发布租户的Azure 容器注册表(ACR)。 你将将云本机应用程序捆绑包(CNAB)上传到该捆绑包。 有关详细信息,请参阅创建Azure 容器注册表

  • 安装最新版本的 Azure CLI。

  • 应用程序必须可部署到 Linux 环境。

  • 映像必须没有漏洞。 若要了解如何扫描漏洞,请参阅使用 Microsoft Defender 漏洞管理 的 Azure 漏洞评估。

  • 如果手动运行打包工具,则需要安装本地计算机。 有关详细信息,请参阅适用于 WindowsLinux 的 Docker 文档上的 WSL 2 后端部分。 这仅在 Linux/Windows AMD64 计算机中受支持。

限制

  • 容器市场仅支持基于 Linux 平台的 AMD64 映像。
  • 只能使用托管 AKS。
  • 不支持单个容器。
  • 不支持链接的 Azure 资源管理器模板。

发布概述

在 Azure 市场上发布基于 Kubernetes 应用的容器产品/服务的第一步是将应用程序打包为云原生应用程序捆绑包 (CNAB)。 CNAB 由应用程序的项目组成,首先发布到专用Azure 容器注册表(ACR),后来推送到 Microsoft 拥有的公共 ACR,并用作合作伙伴中心中引用的单一项目。

在此处执行漏洞扫描以确保映像安全。 最后,将 Kubernetes 应用程序注册为 Azure Kubernetes 服务 (AKS) 群集的扩展类型。

发布产品/服务后,应用程序利用 AKS 功能的群集扩展来管理 AKS 群集中的应用程序生命周期。

A diagram showing the three stages of bundle processing, flowing from 'Copy the bundle to a Microsoft-owned registry' to 'Vulnerability scanning' to 'Extension type registration'.

授予对 Azure 容器注册表的访问权限

作为发布过程的一部分,Microsoft 将 CNAB 从 ACR 复制到 Microsoft 拥有Azure 市场特定的 ACR。 映像将上传到可供所有人访问的公共注册表。 此步骤要求你向 Microsoft 授予对注册表的访问权限。 ACR 必须位于链接到合作伙伴中心帐户的同一个 Microsoft Entra 租户中。

Microsoft 有一方应用程序,负责使用 <a0id/a0> 处理此过程。 首先,基于应用程序创建一个服务主体:

注意

如果帐户无权创建服务主体,az ad sp create 会返回一条错误消息,其中显示“权限不足,无法完成该操作”。 请与 Microsoft Entra 管理员联系以创建服务主体。

az login

验证应用程序是否已存在服务主体:

az ad sp show --id 32597670-3e15-4def-8851-614ff48c1efa 

如果上一个命令未返回任何结果,请创建新的服务主体:

az ad sp create --id 32597670-3e15-4def-8851-614ff48c1efa

记下该服务主体的 ID 以便在后续步骤中使用。

接下来,获取注册表的完整 ID:

az acr show --name <registry-name> --query "id" --output tsv

输出应如下所示:

...
},
"id": "/subscriptions/ffffffff-ff6d-ff22-77ff-ffffffffffff/resourceGroups/myResourceGroup/providers/Microsoft.ContainerRegistry/registries/myregistry",
...

接下来,创建一个角色分配,以授予服务主体使用前面获取的值从注册表中拉取内容的能力:

若要分配 Azure 角色,必须具有:

az role assignment create --assignee <sp-id> --scope <registry-id> --role acrpull

最后,在用于创建 Azure 容器注册表的同一订阅上注册 Microsoft.PartnerCenterIngestion 资源提供程序:

az provider register --namespace Microsoft.PartnerCenterIngestion --subscription <subscription-id> --wait

在继续操作之前,监视注册并确认注册已完成:

az provider show -n Microsoft.PartnerCenterIngestion --subscription <subscription-id>

收集项目以满足包格式要求

每个 CNAB 都由以下项目组成:

  • Helm 图表
  • CreateUiDefinition
  • ARM 模板
  • 清单文件

更新 Helm 图表

确保 Helm 图表遵守以下规则:

  • 所有映像名称和引用都已参数化并在 values.yaml 中表示为 global.azure.images 引用。 更新 Helm 图表模板文件 deployment.yaml 以指向这些图像。 这可确保可以更新映像块以引用Azure 市场的 ACR 映像。 Screenshot showing the extended adding tag support reference example.Screenshot showing adding image reference.

  • 如果你有多个图表,则可以将其他 helm 图表作为子图包含在主 helm 图表之外。 然后更新每个依赖图像引用,以指向主图表 values.yaml中包含的图像。

  • 引用图像时,可以使用标记或摘要。 但是,请务必注意,映像在内部重新标记,指向 Microsoft 拥有的Azure 容器注册表(ACR)。 更新标记时,必须将新版 CNAB 提交到Azure 市场。 因此,更改可以反映在客户部署中。

    Screenshot showing adding tag support reference example.

可用的计费模型

有关所有可用的计费模型,请参阅 Azure Kubernetes 应用程序的许可选项。

根据计费模型进行更新

查看 可用的计费模型后,选择适合你的用例的计费模型,并完成以下步骤:

完成以下步骤,在 Per core、Per podPer 节点计费模型中添加标识符

  • 将计费标识符标签azure-extensions-usage-release-identifier添加到工作负荷 yaml 文件中的 Pod 规范

    • 如果将工作负荷指定为部署或副本集或 Statefulset 或 Daemonsets 规范,请在 .spec.template.metadata.label添加此标签。

    • 如果工作负载直接指定为 Pod 规范,请在 .metadata.label添加此标签。

      A screenshot of a properly formatted billing identifier label in a deployment.yaml file. The content resembles the sample depoyment.yaml file linked in this article.

      A screenshot of a properly formatted billing identifier label in a statefulsets.yaml file. The content resembles the sample statefulsets.yaml file linked in this article.

      A screenshot of CPU resource requests in a daemonsets.yaml file. The content resembles the sample daemonsets.yaml file linked in this article.

      A screenshot of CPU resource requests in a pods.yaml file. The content resembles the sample pods.yaml file linked in this article.

  • 对于 perCore 计费模型,请通过在容器资源清单中包含resources:requests字段来指定 CPU 请求。 此步骤仅适用于 perCore 计费模型。

    A screenshot of CPU resource requests in a pods.yaml file. The content resembles the sample per core billing model file linked in this article.

在部署时,群集扩展功能将计费标识符值替换为扩展实例名称。

有关配置为部署 Azure 投票应用的示例,请参阅以下资源:

对于 自定义计量 计费模型,请在 helm 模板的 values.yaml 文件中添加下面列出的字段

  • 应在 global.azure.identity 下添加 clientId
  • planId 密钥应添加到 global.azure.marketplace 下。 planId
  • 应在 global.azure.extension.resrouceId 下添加 resourceId

Screenshot of custom metering billing.

在部署时,群集扩展功能将这些字段替换为相应的值。 有关示例,请参阅 基于 Azure 投票自定义计量的应用

创建测试参数文件

测试参数文件是与 ARM 模板一起使用的 JSON,用于将资源部署到 Azure。 对于可部署到托管群集的应用程序或扩展(AKS),我们需要为部署验证指定参数文件。 测试参数文件应包含允许成功测试部署的值。

注意

并非所有参数都需要包含在参数文件中,而只是没有默认值的参数。 有关指南,请参阅 此处

下面是一个示例测试参数文件:

Sample test parameter file. 创建测试参数文件后,将其添加到清单文件:

Example of created test parameter file.

注意

对于测试参数文件不适用于应用程序的情况(例如:应用程序需要机密来部署,例如 API 密钥或应用程序部署在连接的群集上),则提供跳过部署标志,以便跳过部署测试。

验证 Helm 图表

为确保 Helm 图表有效,请测试它是否可安装在本地群集上。 还可以使用 helm install --generate-name --dry-run --debug 来检测某些模板生成错误。

创建并测试 createUiDefinition

createUiDefinition 是一个 JSON 文件,用于在部署应用程序时定义 Azure 门户的用户界面元素。 有关详细信息,请参阅:

为应用程序创建 createUiDefinition.json 文件之后,需要测试用户体验。 为了简化测试,请将文件内容复制到 沙盒环境。 沙盒在当前全屏门户体验中提供用户界面。 建议使用沙盒来预览用户界面。

创建 Azure 资源管理器 (ARM) 模板

ARM 模板定义要部署的 Azure 资源。 默认情况下,将为Azure 市场应用程序部署群集扩展资源。 或者,可以选择部署 AKS 群集。

目前只允许使用以下资源类型:

  • Microsoft.ContainerService/managedClusters
  • Microsoft.KubernetesConfiguration/extensions

例如,请参阅此示例 ARM 模板,该模板 旨在从之前链接的示例 UI 定义中获取结果,并将参数传递到应用程序中。

用户参数流

必须了解用户参数如何在你要创建和打包的整个项目中流动。 在 Azure 投票应用示例中,通过createUiDefinition.json文件创建 UI 时,最初定义了参数:

A screenshot of the createUiDefinition example linked in this article. Definitions for 'value1' and 'value2' are shown.

参数通过 outputs 节导出:

A screenshot of the createUiDefinition example linked in this article. Output lines for application title, 'value1', and 'value2' are shown.

在此处,值将传递到 Azure 资源管理器 模板,并在部署期间传播到 Helm 图表:

A screenshot of the Azure Resource Manager template example linked in this article. Under 'configurationSettings', the parameters for application title, 'value1', and 'value2' are shown.

最后,值将传递到 Helm 图表 values.yaml 中,如下所示。

A screenshot of the Helm chart example linked in this article. Values for application title, 'value1', and 'value2' are shown.

注意

在此示例中,extensionResourceName 也会参数化并传递给群集扩展资源。 同样,也可以参数化其他扩展属性,例如为次要版本启用自动升级。 有关群集扩展属性的详细信息,请参阅可选参数

创建清单文件

程序包清单是一个 yaml 文件,用于描述包及其内容,并告知打包工具要在何处查找依赖项目。

清单中使用的字段如下:

名称 数据类型 描述
applicationName 字符串 应用程序的名称
publisher 字符串 发布服务器的名称
description 字符串 包的简短说明
版本 采用 #.#.# 格式的字符串 描述应用程序包版本的版本字符串,可能与内部二进制文件的版本不匹配。
helmChart 字符串 manifest.yaml 的相对本地目录,可在其中找到 Helm 图表
clusterARMTemplate 字符串 本地路径,可在其中找到描述某个 AKS 群集的 ARM 模板,该群集符合限制字段中的要求
uiDefinition 字符串 本地路径,可在其中找到描述 Azure 门户创建体验的 JSON 文件
registryServer 字符串 要将最终 CNAB 捆绑包推送到的 ACR
extensionRegistrationParameters 集合 扩展注册参数的规范。 至少包含 defaultScope 作为参数。
defaultScope 字符串 扩展安装的默认范围。 接受的值为 clusternamespace。 如果设置了 cluster 范围,则每个群集只允许一个扩展实例。 如果选择了 namespace 范围,则每个命名空间只允许一个实例。 由于 Kubernetes 群集可以包含多个命名空间,因此可以存在多个扩展实例。
命名空间 字符串 (可选)指定扩展安装到的命名空间。 当 defaultScope 设置为 cluster 时,此属性是必需的。 有关命名空间命名限制,请参阅命名空间和 DNS
supportedClusterTypes 集合 (可选)指定应用程序支持的群集类型。 允许的类型为 “managedClusters”、“connectedClusters”。 “managedClusters”是指Azure Kubernetes 服务(AKS)群集。 “connectedClusters”是指已启用 Azure Arc 的 Kubernetes 群集。 如果未提供 supportedClusterTypes,则默认支持“managedClusters”的所有分发。 如果提供了 supportedClusterTypes,并且未提供给定的顶级群集类型,则该群集类型的所有分发版和 Kubernetes 版本都被视为不受支持。 对于每个群集类型,请指定具有以下属性的一个或多个分布的列表:
-分布
- distributionSupported
- unsupportedVersions
分发 列出 对应于群集类型的分布数组。 提供特定分发版的名称。 将值设置为 [“All”] 以指示支持所有分发。
distributionSupported 布尔 一个布尔值,表示是否支持指定的分布。 如果为 false,则提供 UnsupportedVersions 会导致错误。
unsupportedVersions 列出 不支持的指定分发版的版本列表。 支持的运算符:
- 不支持“=”给定版本。 例如,“=1.2.12”
- 不支持>“”大于给定版本的所有版本。 例如,“>1.1.13”
- 不支持<“”低于给定版本的所有版本。 例如,“<1.3.14”
- "..."范围中的所有版本都不受支持。 例如,“1.1.2...1.1.15”(包括右侧值并排除左侧值)

有关为投票应用配置的示例,请参阅以下清单文件示例

构建应用程序

将 createUiDefinition、ARM 模板和清单文件放在应用程序的 Helm 图表旁边。

有关正确结构化目录的示例,请参阅 Azure Vote 示例

有关支持已启用 Azure Arc 的 Kubernetes 群集的投票应用程序的示例,请参阅仅连接edCluster 示例

有关支持Azure Kubernetes 服务(AKS)群集和已启用 Azure Arc 的 Kubernetes 群集的投票应用程序的示例,请参阅连接托管群集示例

有关如何设置已启用 Azure Arc 的 Kubernetes 群集以验证应用程序的详细信息,请参阅快速入门:将现有 Kubernetes 群集连接到 Azure Arc

使用容器打包工具

添加所有必需的项目后,运行打包工具 container-package-app

由于 CNAB 是一种新的格式并且具有学习曲线,因此我们创建了一个 Docker 映像,用于 container-package-app 成功运行打包工具所需的引导环境和工具。

可以通过两种方式使用打包工具。 可以手动使用它,或将它集成到部署管道中。

手动运行打包工具

可以从 mcr.microsoft.com/container-package-app:latest 中拉取打包工具的最新映像。

以下 Docker 命令拉取最新的打包工具映像并装载一个目录。

假设 ~\<path-to-content> 是包含要打包内容的目录,则以下 docker 命令将装载 ~/<path-to-content>/data 容器中。 请务必将 ~/<path-to-content> 替换为你自己的应用所在位置。

docker pull mcr.microsoft.com/container-package-app:latest

docker run -it -v /var/run/docker.sock:/var/run/docker.sock -v ~/<path-to-content>:/data --entrypoint "/bin/bash" mcr.microsoft.com/container-package-app:latest 

container-package-app 容器 shell 中运行以下命令。 请务必将 <registry-name> 替换为你的 ACR 名称:

export REGISTRY_NAME=<registry-name>

az login 

az acr login -n $REGISTRY_NAME 

cd /data/<path-to-content>

若要对 ACR 进行身份验证,有两个选项。 一个选项是使用 az login 如前所示,第二个选项是通过 docker 运行 docker login 'yourACRname'.azurecr.io。 输入用户名和密码(用户名应该是 ACR 名称,密码是Azure 门户中提供的生成的密钥),然后运行。

docker login <yourACRname.azurecr.io>

Screenshot of docker login command in CLI.

接下来,运行 cpa verify 以迭代项目并逐个验证它们。 解决任何错误,并在准备好打包 CNAB 并将其上传到 Azure 容器注册表时运行 cpa buildbundle。 该 cpa buildbundle 命令还会在生成之前运行验证过程

cpa verify

Screenshot of cpa verify command in CLI.

cpa buildbundle 

注意

仅当你想要覆盖现有标记时才使用 cpa buildbundle --force。 如果已将此 CNAB 附加到Azure 市场产品/服务,请改为递增清单文件中的版本。

集成到 Azure 管道

有关如何集成到 container-package-app Azure Pipeline 中的示例,请参阅 Azure Pipeline 示例

疑难解答

后续步骤