你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

配置容器映像以使用 ARM 和 Bicep 执行部署

本文介绍如何生成自定义 Azure 资源管理器 (ARM) 和 Bicep 容器映像,以在 Azure 部署环境 (ADE) 中部署环境定义。

环境定义至少包含两个文件:模板文件(如 azuredeploy.jsonmain.bicep)和名为 environment.yaml 的清单文件。 ADE 使用容器部署环境定义,并本机支持 ARM 和 Bicep IaC 框架。

ADE 扩展性模型让你能够创建自定义容器映像以用于环境定义。 通过使用扩展性模型,你可以创建自己的自定义容器映像,并将其存储在容器注册表中,例如 DockerHub。 然后,可以在环境定义中引用这些映像来部署环境。

ADE 团队提供了一系列映像来帮助你入门,包括核心映像和 Azure 资源管理器 (ARM)/Bicep 映像。 可以在运行程序映像文件夹中访问这些示例映像。

先决条件

将容器映像与 ADE 配合使用

可以采用以下方法之一将容器映像与 ADE 配合使用:

  • 使用标准容器映像:对于简单场景,请使用 ADE 提供的标准 Bicep 容器映像。
  • 创建自定义容器映像:对于较复杂的场景,请创建满足特定要求的自定义容器映像。

无论选择哪种方法,都必须在你的环境定义中指定容器映像来部署 Azure 资源。

使用标准 Bicep 容器映像

ADE 原生支持 Bicep,因此可以通过将模板文件 (azuredeploy.json and environment.yaml) 添加到目录来配置为部署环境部署 Azure 资源的环境定义。 然后,ADE 使用标准 Bicep 容器映像来创建部署环境。

在 environment.yaml 文件中,运行器属性指定要使用的容器映像的位置。 若要使用在 Microsoft 工件注册表上发布的示例映像,请使用下表中列出的相应标识符运行器。

以下示例演示了引用示例 Bicep 容器映像的运行器:

    name: WebApp
    version: 1.0.0
    summary: Azure Web App Environment
    description: Deploys a web app in Azure without a datastore
    runner: Bicep
    templatePath: azuredeploy.json

可以在 ARM-Bicep 映像的 Runner-Images 文件夹下的 ADE 示例存储库中看到标准 Bicep 容器映像。

有关如何创建使用 ADE 容器映像部署 Azure 资源的环境定义的详细信息,请参阅添加和配置环境定义

创建自定义 Bicep 容器映像

创建自定义容器映像可以自定义部署来满足你的要求。 你可以基于 ADE 标准容器映像创建自定义映像。

完成映像自定义后,你必须生成映像并将其推送到容器注册表。

使用 Docker 创建和自定义容器映像

本示例介绍如何生成 Docker 映像来利用 ADE 部署并访问 ADE CLI,使你的映像基于 ADE 创作的映像之一。

ADE CLI 是一款工具,允许你使用 ADE 基础映像生成自定义映像。 可以使用 ADE CLI 自定义部署和删除,以适应你的工作流。 ADE CLI 预安装在示例映像上。 若要详细了解 ADE CLI,请参阅 CLI 自定义运行程序映像参考

要创建为 ADE 配置的映像,请执行以下步骤:

  1. 使用 FROM 语句,以 ADE 撰写的示例映像或所选映像为基础制作映像。
  2. 使用 RUN 语句安装映像所需的任何包。
  3. 在 Dockerfile 所在的同一级别创建脚本文件夹,将 deploy.shdelete.sh 文件存储在其中,并确保这些脚本在创建的容器中可发现和可执行。 部署必须使用 ADE 核心映像执行此步骤。

使用 FROM 语句选择示例容器映像

在创建的 DockerFile 中包括一个 FROM 语句,使新映像指向 Microsoft 工件注册表上托管的示例映像。

下面是引用示例核心映像的示例 FROM 语句:

FROM mcr.microsoft.com/deployment-environments/runners/core:latest

此语句拉取最近发布的核心映像,并使其成为你的自定义映像的基础。

在 Dockerfile 中安装 Bicep

可以使用 RUN 语句通过 Azure CLI 安装 Bicep 包,如以下示例所示:

RUN az bicep install

ADE 示例映像基于 Azure CLI 映像,并且预安装了 ADE CLI 和 JQ 包。 可以详细了解 Azure CLIJQ 包

若要在映像中安装所需的任何其他包,请使用 RUN 语句。

执行操作 shell 脚本

在示例映像中,将根据操作名称来确定和执行操作。 目前,支持的两个操作名称是 deploy 和 delete

若要设置自定义映像以利用此结构,请在名为 scripts 的 Dockerfile 级别指定一个文件夹,然后指定两个文件 deploy.sh 和 delete.sh。deploy shell 脚本在创建或重新部署环境时运行,delete shell 脚本在删除环境时运行。 可以在存储库中 ARM-Bicep 映像的 Runner-Images 文件夹下查看 shell 脚本的示例。

若要确保这些 shell 脚本是可执行的,请将以下行添加到 Dockerfile:

COPY scripts/* /scripts/
RUN find /scripts/ -type f -iname "*.sh" -exec dos2unix '{}' '+'
RUN find /scripts/ -type f -iname "*.sh" -exec chmod +x {} \;

创作用于部署 ARM 或 Bicep 模板的操作 shell 脚本

若要确保可以通过 ADE 成功部署 ARM 或 Bicep 基础结构,必须:

  • 将 ADE 参数转换为 ARM 可接受的参数
  • 解决在部署中使用的链接模板
  • 使用特权托管标识执行部署

在核心映像的入口点期间,为当前环境设置的任何参数都存储在变量 $ADE_OPERATION_PARAMETERS 下。 若要将它们转换为 ARM 可接受的参数,则可以使用 JQ 运行以下命令:

# format the parameters as arm parameters
deploymentParameters=$(echo "$ADE_OPERATION_PARAMETERS" | jq --compact-output '{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": (to_entries | if length == 0 then {} else (map( { (.key): { "value": .value } } ) | add) end) }' )

接下来,若要解析基于 ARM JSON 的模板中使用的任何链接模板,可以反编译主模板文件,该文件可解析用于许多 Bicep 模块的所有本地基础结构文件。 然后,将这些模块重新生成回单个 ARM 模板,并将链接模板作为嵌套模板嵌入到主 ARM 模板中。 此步骤仅在部署操作期间是必需的。 可以使用核心映像入口点期间设置的 $ADE_TEMPLATE_FILE 指定主模板文件,应使用重新编译的模板文件重置此变量。 请参阅以下示例:

if [[ $ADE_TEMPLATE_FILE == *.json ]]; then

    hasRelativePath=$( cat $ADE_TEMPLATE_FILE | jq '[.. | objects | select(has("templateLink") and (.templateLink | has("relativePath")))] | any' )

    if [ "$hasRelativePath" = "true" ]; then
        echo "Resolving linked ARM templates"

        bicepTemplate="${ADE_TEMPLATE_FILE/.json/.bicep}"
        generatedTemplate="${ADE_TEMPLATE_FILE/.json/.generated.json}"

        az bicep decompile --file "$ADE_TEMPLATE_FILE"
        az bicep build --file "$bicepTemplate" --outfile "$generatedTemplate"

        # Correctly reassign ADE_TEMPLATE_FILE without the $ prefix during assignment
        ADE_TEMPLATE_FILE="$generatedTemplate"
    fi
fi

若要提供部署在订阅中执行部署和删除资源所需的权限,请使用与 ADE 项目环境类型关联的特权托管标识。 如果部署需要特殊权限才能完成,例如特定角色,请将这些角色分配给项目环境类型的标识。 有时,在进入容器时,托管标识不会立即可用;你可以重试,直到登录成功。

echo "Signing into Azure using MSI"
while true; do
    # managed identity isn't available immediately
    # we need to do retry after a short nap
    az login --identity --allow-no-subscriptions --only-show-errors --output none && {
        echo "Successfully signed into Azure"
        break
    } || sleep 5
done

若要开始部署 ARM 或 Bicep 模板,请运行 az deployment group create 命令。 在容器中运行此命令时,请选择不替代任何过去部署的部署名称,并使用 --no-prompt true--only-show-errors 标志来确保部署不会在出现任何警告或等待用户输入时停止,如以下示例所示:

deploymentName=$(date +"%Y-%m-%d-%H%M%S")
az deployment group create --subscription $ADE_SUBSCRIPTION_ID \
    --resource-group "$ADE_RESOURCE_GROUP_NAME" \
    --name "$deploymentName" \
    --no-prompt true --no-wait \
    --template-file "$ADE_TEMPLATE_FILE" \
    --parameters "$deploymentParameters" \
    --only-show-errors

若要删除环境,请执行完整模式部署并提供一个空 ARM 模板,该模板会移除指定 ADE 资源组中的所有资源,如以下示例所示:

deploymentName=$(date +"%Y-%m-%d-%H%M%S")
az deployment group create --resource-group "$ADE_RESOURCE_GROUP_NAME" \
    --name "$deploymentName" \
    --no-prompt true --no-wait --mode Complete \
    --only-show-errors \
    --template-file "$DIR/empty.json"

可以通过运行以下命令来检查预配状态和详细信息。 ADE 使用一些特殊函数根据预配的详细信息读取和提供其他上下文,你可以在运行程序映像文件夹中找到这些详细信息。 一个简单的实现可能如下所示:

if [ $? -eq 0 ]; then # deployment successfully created
    while true; do

        sleep 1

        ProvisioningState=$(az deployment group show --resource-group "$ADE_RESOURCE_GROUP_NAME" --name "$deploymentName" --query "properties.provisioningState" -o tsv)
        ProvisioningDetails=$(az deployment operation group list --resource-group "$ADE_RESOURCE_GROUP_NAME" --name "$deploymentName")

        echo "$ProvisioningDetails"

        if [[ "CANCELED|FAILED|SUCCEEDED" == *"${ProvisioningState^^}"* ]]; then

            echo -e "\nDeployment $deploymentName: $ProvisioningState"

            if [[ "CANCELED|FAILED" == *"${ProvisioningState^^}"* ]]; then
                exit 11
            else
                break
            fi
        fi
    done
fi

最后,若要查看部署的输出并将其传递给 ADE,以便通过 Azure CLI 访问它们,可以运行以下命令:

deploymentOutput=$(az deployment group show -g "$ADE_RESOURCE_GROUP_NAME" -n "$deploymentName" --query properties.outputs)
if [ -z "$deploymentOutput" ]; then
    deploymentOutput="{}"
fi
echo "{\"outputs\": $deploymentOutput}" > $ADE_OUTPUTS

使自定义映像可供 ADE 访问

必须生成 Docker 映像并将其推送到容器注册表,以使其可在 ADE 中使用。 可以使用 Docker CLI 或使用 ADE 提供的脚本来生成映像。

请选择相应的选项卡来了解有关每种方法的详细信息。

在生成要推送到注册表的映像之前,请确保计算机上已安装 Docker 引擎。 然后,导航到 Dockerfile 的目录并运行以下命令:

docker build . -t {YOUR_REGISTRY}.azurecr.io/{YOUR_REPOSITORY}:{YOUR_TAG}

例如,如果要将映像保存在名为 customImage 的注册表中的存储库下,并使用 1.0.0 的标记版本进行上传,请运行:

docker build . -t {YOUR_REGISTRY}.azurecr.io/customImage:1.0.0

将 Docker 映像推送到注册表

若要使用自定义映像,需要设置可公开访问的映像注册表并启用匿名映像拉取。 这样,Azure 部署环境就可以访问要在容器中执行的自定义映像。

Azure 容器注册表是用于存储容器映像和类似生成工件的 Azure 产品/服务。

若要通过 Azure CLI、Azure 门户、PowerShell 命令等创建注册表,请遵循相应的快速入门

若要将注册表设置为启用匿名映像拉取,请在 Azure CLI 中运行以下命令:

az login
az acr login -n {YOUR_REGISTRY}
az acr update -n {YOUR_REGISTRY} --public-network-enabled true
az acr update -n {YOUR_REGISTRY} --anonymous-pull-enabled true

准备好将映像推送到注册表后,请运行以下命令:

docker push {YOUR_REGISTRY}.azurecr.io/{YOUR_IMAGE_LOCATION}:{YOUR_TAG}

将映像连接到环境定义

创作环境定义以在其部署中使用自定义映像时,请编辑清单文件(environment.yaml 或 manifest.yaml)上的 runner 属性。

runner: "{YOUR_REGISTRY}.azurecr.io/{YOUR_REPOSITORY}:{YOUR_TAG}"

若要详细了解如何创建使用 ADE 容器映像部署 Azure 资源的环境定义,请参阅添加和配置环境定义

访问操作日志和错误详细信息

ADE 将失败部署的错误详细信息存储在容器中的 $ADE_ERROR_LOG 文件中。

排查部署失败的问题:

  1. 登录到开发人员门户

  2. 确定部署失败的环境,然后选择“查看详细信息”

    显示部署失败错误详细信息(具体来说是存储帐户的名称无效)的屏幕截图。

  3. 在“错误详细信息”部分中查看“错误详细信息”。

    显示环境部署失败的屏幕截图,其中显示了“查看详细信息”按钮。

此外,可以使用 Azure CLI 通过以下命令查看环境的错误详细信息:

az devcenter dev environment show --environment-name {YOUR_ENVIRONMENT_NAME} --project {YOUR_PROJECT_NAME}

若要查看环境部署或删除的操作日志,请使用 Azure CLI 检索环境的最新操作,然后查看该操作 ID 的日志。

# Get list of operations on the environment, choose the latest operation
az devcenter dev environment list-operation --environment-name {YOUR_ENVIRONMENT_NAME} --project {YOUR_PROJECT_NAME}
# Using the latest operation ID, view the operation logs
az devcenter dev environment show-logs-by-operation --environment-name {YOUR_ENVIRONMENT_NAME} --project {YOUR_PROJECT_NAME} --operation-id {LATEST_OPERATION_ID}