ARM模板部署后容器实例仅首次运行,如何使其每次部署都启动?
我完全懂你遇到的麻烦:首次部署时容器实例能正常跑起来创建文件共享,但后续部署时,因为容器组资源没有属性变化,ARM的增量部署模式不会触发它重新启动,要是文件共享不小心被删了,根本没法自动重建。下面给你几个实用的解决方案:
核心问题拆解
ARM默认用增量部署模式,只会更新那些属性有变化的资源。你的容器组在首次部署成功后,没有任何属性改动,所以后续部署时Azure不会重新启动它;再加上你设置了restartPolicy: OnFailure,只有容器运行失败时才会重启,成功运行过一次后就会保持停止状态,自然没法再次执行创建共享的命令。
另外要提一句:az storage share create本身是幂等的——如果文件共享已经存在,命令只会返回提示信息不会报错,所以我们可以放心地让它每次部署都执行一遍。
解决方案1:用forceUpdateTag强制容器组重新部署
这是最直接也最推荐的方法:给容器组添加forceUpdateTag属性,每次部署时改变这个标签的值,让ARM认为容器组有变更,从而重新部署并启动容器执行命令。
你可以在模板里加一个可选参数,或者直接用动态生成的值(比如当前时间戳)来当这个标签:
模板关键修改点
- 在
parameters中新增(也可以直接用变量实现):
"forceUpdateTag": { "type": "string", "defaultValue": "[utcNow()]", "metadata": { "description": "Tag to force container group redeployment on each deployment" } }
- 在容器组的
properties里添加forceUpdateTag:
"properties": { "forceUpdateTag": "[parameters('forceUpdateTag')]", "containers": [ // 原容器配置保持不变 ], "restartPolicy": "OnFailure", "osType": "Linux" }
这样每次部署时,utcNow()会生成新的时间戳,ARM就会重新部署容器组,容器会再次执行创建文件共享的命令——就算共享已经存在也没关系,命令会安全返回,不会报错。
解决方案2:动态生成容器组名称(不推荐)
另一种思路是让容器组的名称每次部署都不一样,比如加入唯一字符串:
"containerGroupName": "[concat('createshare-containerinstance-', uniquestring(deployment().name, utcNow()))]"
但这种方法会每次创建新的容器组,旧的容器组会留在资源组里,需要额外清理,所以不如forceUpdateTag来得优雅。
修改后的完整模板
{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "storageAccountType": { "type": "string", "defaultValue": "Standard_LRS", "allowedValues": [ "Standard_LRS", "Standard_GRS", "Standard_ZRS" ], "metadata": { "description": "Storage Account type" } }, "storageAccountName": { "type": "string", "defaultValue": "[uniquestring(resourceGroup().id)]", "metadata": { "description": "Storage Account Name" } }, "fileShareName": { "type": "string", "metadata": { "description": "File Share Name" } }, "containerInstanceLocation": { "type": "string", "defaultValue": "[parameters('location')]", "allowedValues": [ "westus", "eastus", "westeurope", "southeastaisa", "westus2" ], "metadata": { "description": "Container Instance Location" } }, "location": { "type": "string", "defaultValue": "[resourceGroup().location]", "metadata": { "description": "Location for all resources." } }, "forceUpdateTag": { "type": "string", "defaultValue": "[utcNow()]", "metadata": { "description": "Tag to force container group redeployment on each deployment" } } }, "variables": { "image": "microsoft/azure-cli", "cpuCores": "1.0", "memoryInGb": "1.5", "containerGroupName": "createshare-containerinstance", "containerName": "createshare" }, "resources": [ { "type": "Microsoft.Storage/storageAccounts", "name": "[parameters('storageAccountName')]", "apiVersion": "2017-10-01", "location": "[parameters('location')]", "sku": { "name": "[parameters('storageAccountType')]" }, "kind": "Storage", "properties": {} }, { "name": "[variables('containerGroupName')]", "type": "Microsoft.ContainerInstance/containerGroups", "apiVersion": "2018-02-01-preview", "location": "[parameters('containerInstanceLocation')]", "dependsOn": [ "[concat('Microsoft.Storage/storageAccounts/', parameters('storageAccountName'))]" ], "properties": { "forceUpdateTag": "[parameters('forceUpdateTag')]", "containers": [ { "name": "[variables('containerName')]", "properties": { "image": "[variables('image')]", "command": [ "az", "storage", "share", "create", "--name", "[parameters('fileShareName')]" ], "environmentVariables": [ { "name": "AZURE_STORAGE_KEY", "value": "[listKeys(parameters('storageAccountName'),'2017-10-01').keys[0].value]" }, { "name": "AZURE_STORAGE_ACCOUNT", "value": "[parameters('storageAccountName')]" } ], "resources": { "requests": { "cpu": "[variables('cpuCores')]", "memoryInGb": "[variables('memoryInGb')]" } } } } ], "restartPolicy": "OnFailure", "osType": "Linux" } } ] }
修改后的模板每次部署都会因为forceUpdateTag的变化,强制重启容器组执行创建命令,完美解决你遇到的问题——就算文件共享被误删,下次部署也会自动重建。
内容的提问来源于stack exchange,提问作者David Gard

