【问题标题】:Deploying Web App for containers using ARM templates使用 ARM 模板为容器部署 Web 应用
【发布时间】:2018-09-04 19:25:20
【问题描述】:

我一直在尝试将我的资源自动部署到 Azure 上的资源组。现在我正在使用 ARM 模板,到目前为止,我能够使用模板创建 App Insights 和 App Service Plan。看起来是这样的:

{
   "apiVersion": "2015-05-01",
   "name": "[variables('servicePlan')]",
   "kind": "linux",
   "type": "Microsoft.Web/serverfarms",
   "location": "[resourceGroup().location]",
   "tags": {
           "displayName": "BTC Push Notification Settings HostingPlan"
    },
    "sku": {
           "name": "[variables('skuNamePlan')]",
           "capacity": "[variables('skuSizePlan')]"
    },
    "properties": {
            "name": "[variables('servicePlan')]"
    }
},
{
    "apiVersion": "2015-05-01",
    "name": "[variables('appInsights')]",
    "type": "Microsoft.Insights/components",
    "location": "southcentralus",
    "tags": {
            "[concat('hidden-link:', resourceGroup().id, '/providers/Microsoft.Web/sites/', variables('appInsights'))]": "Resource",
            "displayName": "BTC Push Notification Settings App Insights"
     },
     "properties": {
            "applicationId": "[variables('appInsights')]"
        }
 }

我很难为容器创建 Web 应用程序并使用 ARM 模板将其指向我的 docker 映像。我已经手动完成了它并且它有效,同样我通过azure-cli 完成它就像这个az webapp create --resource-group ExampleGroupAlpina --plan myAppServicePlan --name DockerContainer --deployment-container-image-name this-is-my-image/sample-docker 并且它也有效。如果有人能建议使用 ARM 模板为容器创建这个 Web 应用程序,我将不胜感激。

【问题讨论】:

  • 如果可能的话,你可以接受并且答案是正确的,以便答案可以帮助其他正在寻找它的人。

标签: json azure arm-template


【解决方案1】:

对我来说,这些其他答案都不起作用。在 Azure 支持和这些其他答案的帮助下,我想出了以下模板,该模板成功地创建了一个应用服务计划,其中包含运行 Azure 容器存储库中的自定义 Docker 映像的容器的 Linux 应用服务:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "environment":{
      "type": "string"
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Location (region) for all resources."
      }
    },   
    "appServiceSku": {
      "type": "string",
      "defaultValue": "B1",
      "metadata": {
        "description": "The SKU of App Service Plan "
      }
    },
    "dockerImageName": {
      "type": "string",
      "defaultValue": "_MY_REGISTRY_USERNAME_.azurecr.io/_MY_NAMESPACE_/_MY_DOCKER_IMAGE_NAME_:_TAG_"
    },
    "dockerRegistryUrl": {
      "type": "string",
      "defaultValue": "https://_MY_REGISTRY_USERNAME_.azurecr.io"
    },
    "dockerRegistryUsername": {
      "type": "string",
      "defaultValue": "_MY_REGISTRY_USERNAME_"
    },
    "dockerRegistryPassword": {
      "type": "string",
      "defaultValue": "_MY_REGISTRY_PSW_"
    },
    "_artifactsLocation": {
      "type": "string"
    },
    "_artifactsLocationSasToken": {
      "type": "securestring"
    }
  },
  "variables": {
    "name": "projectname-",
    "webAppPortalName": "[concat(variables('name'), parameters('environment'), '-webapp')]",
    "appServicePlanName": "[concat(variables('name'), parameters('environment'),'-hosting')]",
  "resources": [       
    {
      "apiVersion": "2017-08-01",
      "type": "Microsoft.Web/serverfarms",
      "kind": "linux",
      "name": "[variables('appServicePlanName')]",
      "location": "[parameters('location')]",
      "comments": "This app service plan is used for the web app and slots.",
      "properties": {
        "reserved": true
      },
      "dependsOn": [],
      "sku": {
        "name": "[parameters('appServiceSku')]"
      }
    },
    {
      "type": "Microsoft.Web/sites",
      "apiVersion": "2016-08-01",
      "name": "[variables('webAppPortalName')]",
      "kind": "app,linux,container",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]"
      ],
      "properties": {
        "name": "[variables('webAppPortalName')]",
        "siteConfig": {
          "linuxFxVersion": "[concat('DOCKER|', parameters('dockerImageName'))]",
          "alwaysOn": true,
          "appSettings": [
            {
              "name": "WEBSITES_ENABLE_APP_SERVICE_STORAGE",
              "value": "false"
            },
            {
              "name": "DOCKER_REGISTRY_SERVER_URL",
              "value": "[parameters('dockerRegistryUrl')]"
            },
            {
              "name": "DOCKER_REGISTRY_SERVER_USERNAME",
              "value": "[parameters('dockerRegistryUsername')]"
            },
            {
              "name": "DOCKER_REGISTRY_SERVER_PASSWORD",
              "value": "[parameters('dockerRegistryPassword')]"
            }
          ]
        },
        "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]"
      }
    }
  ]
}

_artifactsLocation_artifactsLocationSasToken 不需要值,但不知何故需要包含它们。与其他答案的主要区别在于应用服务计划的properties 中包含reserved 属性。

希望这可以减轻这给我带来的一些麻烦!

【讨论】:

  • 我可以在不需要_artifactsLocation 的情况下进行部署,显然只有在使用链接模板时才需要此字段。此外,linuxFxVersionDeploy Azure App Service 任务自动生成,因此无需添加。这会导致 DOCKER_CUSTOM_IMAGE_NAME 应用设置被设置为 linuxFxVersion 的值。
  • 这个答案对我不起作用,我得到“参数 LinuxFxVersion 的值无效。”提交类似的内容时:“linuxFxVersion”:“username.azurecr.io/namespace/imagename:latest”
【解决方案2】:

以下 ARM 模板对我有用。

  • 它允许指定私有 Azure 容器注册表的身份验证详细信息。
  • 还要确保 docker 镜像名称遵循以下模式:_MY_REGISTRY_USERNAME_-on.azurecr.io/_MY_NAMESPACE_/_MY_DOCKER_IMAGE_NAME_:latest

我像这样运行az 命令:

az group deployment create \
  --name "deployAzureApp" \
  --resource-group <MY_RESOURCE_GROUP_NAME> \
  --template-file <MY_ARM_JSON_TEMPLATE>.json  --verbose --debug

这是 Azure 资源管理器 (ARM) JSON 模板:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "appName": {
      "type": "String",
      "defaultValue": "_MY_APP_NAME_"
    },
    "dockerImageName": {
      "type": "String",
      "defaultValue": "_MY_REGISTRY_USERNAME_-on.azurecr.io/_MY_NAMESPACE_/_MY_DOCKER_IMAGE_NAME_:latest"
    },
    "dockerRegistryUrl": {
      "type": "String",
      "defaultValue": "https://_MY_REGISTRY_USERNAME_-on.azurecr.io"
    },
    "dockerRegistryUsername": {
      "type": "String",
      "defaultValue": "_MY_REGISTRY_USERNAME_"
    },
    "dockerRegistryPassword": {
      "type": "String",
      "defaultValue": "_MY_REGISTRY_PSW_"
    },
    "servicePlanName": {
      "type": "String",
      "defaultValue": "_MY_SERVICE_PLAN_NAME_"
    },
    "appLocation": {
      "type": "String",
      "defaultValue": "_MY_REGION_"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Web/sites",
      "apiVersion": "2016-08-01",
      "name": "[parameters('appName')]",
      "kind": "app,linux,container",
      "location": "[parameters('appLocation')]",
      "properties": {
        "name": "[parameters('appName')]",
        "siteConfig": {
          "linuxFxVersion": "[concat('DOCKER|', parameters('dockerImageName'))]",
          "alwaysOn": true,
          "appSettings": [
            {
              "name": "WEBSITES_ENABLE_APP_SERVICE_STORAGE",
              "value": "false"
            },
            {
              "name": "DOCKER_REGISTRY_SERVER_URL",
              "value": "[parameters('dockerRegistryUrl')]"
            },
            {
              "name": "DOCKER_REGISTRY_SERVER_USERNAME",
              "value": "[parameters('dockerRegistryUsername')]"
            },
            {
              "name": "DOCKER_REGISTRY_SERVER_PASSWORD",
              "value": "[parameters('dockerRegistryPassword')]"
            }
          ]
        },
        "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('servicePlanName'))]"
      }
    }
  ]
}

【讨论】:

  • 这个答案对我不起作用,我得到“参数 LinuxFxVersion 的值无效。”提交类似的内容时:“linuxFxVersion”:“username.azurecr.io/namespace/imagename:latest”
  • 你还记得图片回购详情前面的DOCKER|吗?据我所知,仍然有效。
  • 为什么注册地址_MY_REGISTRY_USERNAME_-on.azurecr.io中有-on@
  • @zolty13 是私有 Docker 注册表名称的占位符
【解决方案3】:

关于Azure Web App for Container,其实和模板中的Azure Web App只有一点不同。重点是kind类型。

Azure 网络应用:

"kind": "app"

用于容器的 Azure Web 应用:

"kind": "app,linux,container",

因此,您可以使用模板创建 Azure Web App for Container,只需使用 app,linux,container 设置类型。

更新

我做了测试,发现网站类型并不是最重要的。关键是网站的属性:

"siteConfig": {
                    "linuxFxVersion": "DOCKER|nginx"
                },

模板会像下面这样,而且做得很好。

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "webAppName": {
            "type": "string",
            "metadata": {
                "description": "Base name of the resource such as web app name and app service plan "
            },
            "minLength": 2
        },
        "sku": {
            "type": "string",
            "defaultValue": "S1",
            "metadata": {
                "description": "The SKU of App Service Plan "
            }
        },
        "location": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]",
            "metadata": {
                "description": "Location for all resources."
            }
        }
    },
    "variables": {
        "webAppPortalName": "[concat(parameters('webAppName'), '-webapp')]",
        "appServicePlanName": "[concat('AppServicePlan-', parameters('webAppName'))]"
    },
    "resources": [
        {
            "apiVersion": "2017-08-01",
            "type": "Microsoft.Web/serverfarms",
            "kind": "linux",
            "name": "[variables('appServicePlanName')]",
            "location": "[parameters('location')]",
            "comments": "This app service plan is used for the web app and slots.",
            "properties": {},
            "dependsOn": [],
            "sku": {
                "name": "[parameters('sku')]"
            }
        },
        {
            "apiVersion": "2016-08-01",
            "type": "Microsoft.Web/sites",
            "name": "[variables('webAppPortalName')]",
            "location": "[parameters('location')]",
            "comments": "This is the web app, also the default 'nameless' slot.",
            "properties": {
                "name": "[parameters('webAppName')]",
                "siteConfig": {
                    "appCommandLine": "",
                    "linuxFxVersion": "DOCKER|nginx"
                },
                "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]"
            },
            "dependsOn": [
                "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]"
            ]
        }
    ]
}

【讨论】:

  • 感谢您指出这一点,但是,它不适用于 docker,除非您将 "linuxFxVersion": "[concat('DOCKER|', parameters('dockerCustomImageName'))]" 添加到 Web 应用程序的属性中。此外,您必须指定其他属性,例如passwordusernameurl
  • @RustamUmarov 是的,我做了测试并更新了答案。
  • 请把"linuxFxVersion": "DOCKER|nginx"编辑成"linuxFxVersion": "[concat('DOCKER|', parameters('dockerCustomImageName'))]"
  • @CharlesXu-MSFT 从私有 Azure 容器注册表中提取 docker 映像时如何执行此操作? JSON/ARM 语法如何向 Azure 容器注册表提供身份验证详细信息?
【解决方案4】:

据我观察,linuxFxVersion 问题取决于托管 Web 应用的应用服务计划。对我有帮助的是将应用服务计划资源的属性对象上的 reserved 属性设置为 true

Microsoft doumentationreserved 设置的评价:

如果 Linux 应用服务计划为 true,否则为 false。

它没有说明它的默认值,但从我观察到它的 false

这就是我的应用服务计划资源 ARM 模板的样子。

{
  "type": "Microsoft.Web/serverfarms",
  "apiVersion": "2019-08-01",
  "name": "[variables('appServicePlanName')]",
  "location": "[parameters('location')]",
  "sku": {
    "name": "[parameters('appServicePlanSkuName')]",
    "tier": "[parameters('appServicePlanSkuTier')]",
    "size": "[parameters('appServicePlanSkuSize')]",
    "family": "[parameters('appServicePlanSkuFamily')]",
    "capacity": "[parameters('appServicePlanSkuCapacity')]"
  },
  "kind": "linux",
  "properties": {
    "name": "[variables('appServicePlanName')]",
    "reserved": true
  }
}

【讨论】:

  • 这是众所周知的问题。经常被人忘记储备是必要的。如果你想使用 windows 容器 linuxFxVersion 是没有必要的。相反,您可能需要 windowsFxVersion
【解决方案5】:

上面的模板现在不起作用,将显示以下日志-

[error]BadRequest: {
  "Code": "BadRequest",
  "Message": "The parameter LinuxFxVersion has an invalid value.",
  "Target": null,
  "Details": [
    {
      "Message": "The parameter LinuxFxVersion has an invalid value."
    },
    {
      "Code": "BadRequest"
    },
    {
      "ErrorEntity": {
        "ExtendedCode": "01007",
        "MessageTemplate": "The parameter {0} has an invalid value.",
        "Parameters": [
          "LinuxFxVersion"
        ],
        "Code": "BadRequest",
        "Message": "The parameter LinuxFxVersion has an invalid value."
      }
    }
  ],
  "Innererror": null
}

要解决这个问题,我们可以按照以下博客中的说明进行两步部署过程 Updated Solution

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-11
    • 2020-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多