为 Kubernetes 应用准备 Azure 容器技术资产
本文提供技术资源和建议,以帮助你在 Azure 市场上为 Kubernetes 应用程序创建容器产品/服务。
有关基于 Kubernetes 应用的容器产品/服务所需技术资产的综合示例,请参阅适用于 Kubernetes 的 Azure 市场容器产品/服务示例。
基础技术知识
设计、生成和测试这些资产需要一些时间,并在 Azure 平台和用于生成套餐的技术方面有一定的专业知识。
除了解决方案领域以外,工程团队还应该了解以下 Microsoft 技术:
- 基本了解 Azure 服务
- 如何设计和架构 Azure 应用程序
- Azure 资源管理器的实践知识
- JSON 的实践知识
- Helm 的实践知识
- createUiDefinition 的实践知识
- Azure 资源管理器 (ARM) 模板的实践知识
先决条件
你的应用程序必须基于 Helm 图表。
Helm 图表不应包含
.tgz
存档文件;所有文件都应解压缩。如果你有多个图表,则可以将其他 helm 图表作为子图包含在主 helm 图表之外。
所有映像引用和摘要详细信息必须包含在图表中。 在运行时无法下载其他图表或图像。
必须具有一个有效的发布租户,或者有权访问发布租户和合作伙伴中心帐户。
必须已创建属于上述活动发布租户的Azure 容器注册表(ACR)。 你将将云本机应用程序捆绑包(CNAB)上传到该捆绑包。 有关详细信息,请参阅创建Azure 容器注册表。
安装最新版本的 Azure CLI。
应用程序必须可部署到 Linux 环境。
映像必须没有漏洞。 有关指定漏洞扫描要求的指导,请参阅 容器认证疑难解答。 若要了解如何扫描漏洞,请参阅使用 Microsoft Defender 漏洞管理 的 Azure 漏洞评估。
如果手动运行打包工具,则需要安装本地计算机。 有关详细信息,请参阅适用于 Windows 或 Linux 的 Docker 文档上的 WSL 2 后端部分。 这仅在 Linux/Windows AMD64 计算机中受支持。
限制
- 容器市场仅支持基于 Linux 平台的 AMD64 映像。
- 容器市场产品/服务支持部署到 托管 AKS 和 已启用 Arc 的 Kubernetes 。 单个产品/服务只能面向一种群集类型,即托管 AKS 或已启用 Arc 的 Kubernetes。
- 已启用 Arc 的 Kubernetes 群集的产品/服务仅支持预定义的计费模型。 有关计费模型的详细信息,请参阅 “规划 Azure 容器产品/服务”。
- 不支持单个容器。
- 不支持链接的 Azure 资源管理器模板。
发布概述
在 Azure 市场上发布基于 Kubernetes 应用的容器产品/服务的第一步是将应用程序打包为云原生应用程序捆绑包 (CNAB)。 CNAB 由应用程序的项目组成,首先发布到专用Azure 容器注册表(ACR),后来推送到Microsoft拥有的公共 ACR,并用作合作伙伴中心中引用的单一项目。
在此处执行漏洞扫描以确保映像安全。 最后,将 Kubernetes 应用程序注册为 Azure Kubernetes 服务 (AKS) 群集的扩展类型。
发布产品/服务后,应用程序利用 AKS 功能的群集扩展来管理 AKS 群集中的应用程序生命周期。
授予对 Azure 容器注册表的访问权限
作为发布过程的一部分,Microsoft将 CNAB 从 ACR 复制到Microsoft拥有Azure 市场特定的 ACR。 映像将上传到可供所有人访问的公共注册表。 此步骤要求你向 Microsoft 授予对注册表的访问权限。 ACR 必须位于链接到合作伙伴中心帐户的同一Microsoft Entra 租户中。
Microsoft有一个第一方应用程序,负责使用 <id
/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/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/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 映像。如果你有多个图表,则可以将其他 helm 图表作为子图包含在主 helm 图表之外。 所有依赖的 Helm 图表图像引用都需要更新,应指向主图表
values.yaml
中包含的图像。引用图像时,可以使用标记或摘要。 但是,请务必注意,图像在内部重新标记,以指向Microsoft拥有的Azure 容器注册表(ACR)。 更新标记时,必须将新版 CNAB 提交到Azure 市场。 因此,更改可以反映在客户部署中。
可用的计费模型
有关所有可用的计费模型,请参阅 Azure Kubernetes 应用程序的许可选项。
根据计费模型进行更新
查看 可用的计费模型后,选择适合你的用例的计费模型,并完成以下步骤:
完成以下步骤,在 Per core、Per pod、Per 节点计费模型中添加标识符:
将计费标识符标签
azure-extensions-usage-release-identifier
添加到工作负荷 yaml 文件中的 Pod 规范。如果将工作负荷指定为部署或副本集或 Statefulset 或 Daemonsets 规范,请在 .spec.template.metadata.label 下添加此标签。
如果工作负载直接指定为 Pod 规范,请在 .metadata.label 下添加此标签。
对于 perCore 计费模型,请通过在容器资源清单中包含
resources:requests
字段来指定 CPU 请求。 此步骤仅适用于 perCore 计费模型。
在部署时,群集扩展功能将计费标识符值替换为扩展实例名称。
有关配置为部署 Azure 投票应用的示例,请参阅以下资源:
对于 自定义计量 计费模型,请在 helm 模板的 values.yaml 文件中添加下面列出的字段
- 应在 global.azure.identity 下添加 clientId
- planId 密钥应添加到 global.azure.marketplace 下。 planId
- 应在 global.azure.extension.resrouceId 下添加 resourceId
在部署时,群集扩展功能将这些字段替换为相应的值。 有关示例,请参阅 基于 Azure 投票自定义计量的应用。
验证 Helm 图表
为确保 Helm 图表有效,请测试它是否可安装在本地群集上。 还可以使用 helm install --generate-name --dry-run --debug
来检测某些模板生成错误。
创建并测试 createUiDefinition
createUiDefinition 是一个 JSON 文件,用于在部署应用程序时定义 Azure 门户的用户界面元素。 有关详细信息,请参阅:
或查看一个 UI 定义示例,该定义 要求输入数据作为新的或现有的群集选择,并将参数传递到应用程序中。
为应用程序创建 createUiDefinition.json 文件之后,需要测试用户体验。 为了简化测试,请将文件内容复制到 沙盒环境。 沙盒在当前的全屏门户体验中提供用户界面。 建议使用沙盒来预览用户界面。
创建 Azure 资源管理器 (ARM) 模板
ARM 模板定义要部署的 Azure 资源。 默认情况下,将为Azure 市场应用程序部署群集扩展资源。 或者,可以选择部署 AKS 群集。
目前只允许使用以下资源类型:
Microsoft.ContainerService/managedClusters
Microsoft.KubernetesConfiguration/extensions
例如,请参阅此示例 ARM 模板,该模板 旨在从之前链接的示例 UI 定义中获取结果,并将参数传递到应用程序中。
用户参数流
必须了解用户参数如何在你要创建和打包的整个项目中流动。 在 Azure 投票应用示例中,通过createUiDefinition.json文件创建 UI 时,最初定义了参数:
参数通过 outputs
节导出:
在此处,值将传递到 Azure 资源管理器 模板,并在部署期间传播到 Helm 图表:
最后,值将传递到 Helm 图表 values.yaml
中,如下所示。
注意
在此示例中,extensionResourceName
也会参数化并传递给群集扩展资源。 同样,也可以参数化其他扩展属性,例如为次要版本启用自动升级。 有关群集扩展属性的详细信息,请参阅可选参数。
创建清单文件
程序包清单是一个 yaml 文件,用于描述包及其内容,并告知打包工具要在何处查找依赖项目。
清单中使用的字段如下:
名称 | 数据类型 | 描述 |
---|---|---|
applicationName | 字符串 | 应用程序的名称 |
publisher | 字符串 | 发布服务器的名称 |
description | 字符串 | 包的简短说明 |
版本 | 采用 #.#.# 格式的字符串 |
描述应用程序包版本的版本字符串,可能与内部二进制文件的版本不匹配。 |
helmChart | 字符串 | 此 manifest.yaml 的相对本地目录,可在其中找到 Helm 图表 |
clusterARMTemplate | 字符串 | 本地路径,可在其中找到描述某个 AKS 群集的 ARM 模板,该群集符合限制字段中的要求 |
uiDefinition | 字符串 | 本地路径,可在其中找到描述 Azure 门户创建体验的 JSON 文件 |
registryServer | 字符串 | 要将最终 CNAB 捆绑包推送到的 ACR |
extensionRegistrationParameters | 集合 | 扩展注册参数的规范。 至少包含 defaultScope 作为参数。 |
defaultScope | 字符串 | 扩展安装的默认范围。 接受的值为 cluster 或 namespace 。 如果设置了 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 群集的投票应用程序的示例,请参阅 仅 ConnectedCluster 示例 。
有关支持Azure Kubernetes 服务(AKS)群集和已启用 Azure Arc 的 Kubernetes 群集的投票应用程序的示例,请参阅“已连接”和“托管群集”示例。
有关如何设置已启用 Azure Arc 的 Kubernetes 群集以验证应用程序的详细信息,请参阅 快速入门:将现有的 Kubernetes 群集连接到 Azure Arc。
使用容器打包工具
添加所有必需的项目后,运行打包工具container-package-app
以验证项目、生成包并将包上传到Azure 容器注册表。
由于 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>
接下来,运行 cpa verify
以循环访问项目并逐个验证它们并解决任何故障。 准备好打包并将 CNAB 上传到Azure 容器注册表时运行cpa buildbundle
。 该cpa buildbundle
命令运行验证过程,生成包,并将包上传到Azure 容器注册表。
cpa verify
cpa buildbundle
注意
仅当你想要覆盖现有标记时才使用 cpa buildbundle --force
。 如果已将此 CNAB 附加到Azure 市场产品/服务,请改为递增清单文件中的版本。
集成到 Azure 管道
有关如何集成到 container-package-app
Azure Pipeline 中的示例,请参阅 Azure Pipeline 示例