适用于 Linux 的虚拟机扩展和功能

Azure 虚拟机 (VM) 扩展是小型应用程序,可在 Azure VM 上提供部署后配置和自动化任务。 例如,如果某个虚拟机需要安装软件、防病毒保护或在其上运行脚本,便可以使用 VM 扩展。

可以使用 Azure CLI、PowerShell、Azure 资源管理器模板(ARM 模板)和 Azure 门户运行 Azure VM 扩展。 可将扩展与新 VM 部署捆绑在一起,也可以针对任何现有系统运行扩展。

本文提供 Azure VM 扩展的概述、使用的先决条件,以及有关如何检测、管理和删除这些扩展的指导。 本文提供的是概况信息,因为有许多 VM 扩展可用。 每个扩展可能具有独特的配置和自己的文档。

用例和示例

每个 Azure VM 扩展都有特定的用例。 示例包括:

除了进程特定的扩展外,“自定义脚本”扩展也可用于 Windows 和 Linux 虚拟机。 使用适用于 Linux 的自定义脚本扩展可以在 VM 上运行任何 Bash 脚本。 在设计需要本机 Azure 工具无法提供的配置的 Azure 部署时,自定义脚本很有用。

先决条件

Azure Linux 代理

若要处理 VM 上的扩展,需要安装 Azure Linux 代理。 有些单独的扩展附带先决条件,例如,有权访问资源或依赖项。

Azure Linux 代理可管理 Azure VM 与 Azure 结构控制器之间的交互。 该代理负责部署和管理 Azure VM 的许多功能层面,包括运行 VM 扩展。

Azure 市场映像上都预安装了 Azure Linux 代理。 也可以在受支持的操作系统上手动安装该代理。

代理在多个操作系统上运行。 但是,扩展框架有一个针对扩展所使用的操作系统的限制。 某些扩展并非在所有操作系统上均受支持,可能会发出错误代码 51(“不受支持的 OS”)。 请查看相应的扩展文档来了解支持情况。

网络访问

可从 Azure 存储扩展存储库下载扩展包。 将扩展状态上传内容发布到 Azure 存储。

如果使用受支持的 Azure Linux 代理版本,则不需要允许对 VM 区域中 Azure 存储的访问。 可以使用该代理将通信重定向到 Azure 结构控制器,以进行代理通信。 如果使用不受支持的代理版本,则需要允许从 VM 对该区域中的 Azure 存储进行出站访问。

重要

如果使用来宾防火墙阻止了对专用 IP 地址 168.63.129.16 的访问,则即使使用受支持的代理版本或配置了出站访问,扩展也会失败。

代理只可用于下载扩展包和报告状态。 例如,如果扩展安装需要从 GitHub 下载脚本(自定义脚本扩展),或需要访问 Azure 存储(Azure 备份),则需要打开其他防火墙或网络安全组 (NSG) 端口。 不同的扩展具有不同的要求,因为它们本身就是应用程序。 对于需要访问 Azure 存储的扩展,可以使用 Azure NSG 服务标记来允许访问。

为了重定向代理流量请求,Azure Linux 代理有代理服务器支持。 但是,此代理服务器支持不应用扩展。 必须配置每个单独的扩展来使用代理。

发现 VM 扩展

有许多 VM 扩展可与 Azure VM 配合使用。 若要查看完整列表,请使用 az vm extension image list。 以下示例列出“chinanorth”位置的所有可用扩展 :

az vm extension image list --location chinanorth --output table

运行 VM 扩展

Azure VM 扩展在现有的 VM 上运行。 需要在已部署的 VM 上进行配置更改或恢复连接时,这很有用。 VM 扩展还可以与 ARM 模板部署捆绑在一起。 将扩展与 ARM 模板配合使用,在部署后无需干预即可部署和配置 Azure VM。

可使用以下方法针对现有 VM 运行扩展。

Azure CLI

可以使用 az vm extension set 命令针对现有 VM 运行 Azure VM 扩展。 下面的示例针对名为 myResourceGroup 的资源组中名为 myVM 的 VM 运行自定义脚本扩展 。 将示例资源组名称、VM 名称和要运行的脚本 (https://raw.githubusercontent.com/me/project/hello.sh) 替换为你自己的信息。

az vm extension set \
  --resource-group myResourceGroup \
  --vm-name myVM \
  --name customScript \
  --publisher Microsoft.Azure.Extensions \
  --settings '{"fileUris": ["https://raw.githubusercontent.com/me/project/hello.sh"],"commandToExecute": "./hello.sh"}'

扩展正确运行时,输出类似于以下示例:

info:    Executing command vm extension set
+ Looking up the VM "myVM"
+ Installing extension "CustomScript", VM: "mvVM"
info:    vm extension set command OK

Azure PowerShell

可以使用 Set-AzVMExtension 命令针对现有 VM 运行 Azure VM 扩展。 下面的示例针对名为 myResourceGroup 的资源组中名为 myVM 的 VM 运行自定义脚本扩展 。 将示例资源组名称、VM 名称和要运行的脚本 (https://raw.githubusercontent.com/me/project/hello.sh) 替换为你自己的信息。

$Params = @{
    ResourceGroupName  = 'myResourceGroup'
    VMName             = 'myVM'
    Name               = 'CustomScript'
    Publisher          = 'Microsoft.Azure.Extensions'
    ExtensionType      = 'CustomScript'
    TypeHandlerVersion = '2.1'
    Settings          = @{fileUris = @('https://raw.githubusercontent.com/me/project/hello.sh'); commandToExecute = './hello.sh'}
}
Set-AzVMExtension @Params

扩展正确运行时,输出类似于以下示例:

RequestId IsSuccessStatusCode StatusCode ReasonPhrase
--------- ------------------- ---------- ------------
                         True         OK OK

Azure 门户

可通过 Azure 门户将 VM 扩展应用到现有 VM。 在门户中选择该 VM,然后依次选择“扩展”和“添加” 。 从可用扩展的列表中选择所需扩展,并按向导中的说明操作。

下图展示了如何从 Azure 门户安装适用于 Linux 的自定义脚本扩展:

安装适用于 Linux 的自定义脚本扩展的对话框的屏幕截图。

Azure 资源管理器模板

可以将 VM 扩展添加到 ARM 模板,通过部署该模板来运行扩展。 使用模板部署扩展时,可以创建完全配置的 Azure 部署。

例如,以下 JSON 取自一个完整的 ARM 模板,该模板会在每个 VM 上部署一组负载均衡的 VM、一个 Azure SQL 数据库,然后安装一个 .NET Core 应用程序。 VM 扩展负责安装软件。

{
    "apiVersion": "2015-06-15",
    "type": "extensions",
    "name": "config-app",
    "location": "[resourceGroup().location]",
    "dependsOn": [
    "[concat('Microsoft.Compute/virtualMachines/', concat(variables('vmName'),copyindex()))]"
    ],
    "tags": {
    "displayName": "config-app"
    },
    "properties": {
    "publisher": "Microsoft.Azure.Extensions",
    "type": "CustomScript",
    "typeHandlerVersion": "2.1",
    "autoUpgradeMinorVersion": true,
    "settings": {
        "fileUris": [
        "https://raw.githubusercontent.com/Microsoft/dotnet-core-sample-templates/master/dotnet-core-music-linux/scripts/config-music.sh"
        ]
    },
    "protectedSettings": {
        "commandToExecute": "[concat('sudo sh config-music.sh ',variables('musicStoreSqlName'), ' ', parameters('adminUsername'), ' ', parameters('sqlAdminPassword'))]"
    }
    }
}

有关创建 ARM 模板的详细信息,请参阅 Azure 资源管理器模板中的虚拟机

帮助保护 VM 扩展数据

运行 VM 扩展时,可能需要包括敏感信息,例如凭据、存储帐户名称和访问密钥。 许多 VM 扩展包括受保护的配置,该配置对数据进行加密并且仅在目标 VM 内才对数据进行解密。 每个扩展都有特定的受保护配置架构,会在特定于扩展的文档中详细介绍每个配置架构。

以下示例显示了适用于 Linux 的自定义脚本扩展的一个实例。 要运行的命令包含一组凭据。 在此示例中,不会加密要运行的命令。

{
  "apiVersion": "2015-06-15",
  "type": "extensions",
  "name": "config-app",
  "location": "[resourceGroup().location]",
  "dependsOn": [
    "[concat('Microsoft.Compute/virtualMachines/', concat(variables('vmName'),copyindex()))]"
  ],
  "tags": {
    "displayName": "config-app"
  },
  "properties": {
    "publisher": "Microsoft.Azure.Extensions",
    "type": "CustomScript",
    "typeHandlerVersion": "2.1",
    "autoUpgradeMinorVersion": true,
    "settings": {
      "fileUris": [
        "https://raw.githubusercontent.com/Microsoft/dotnet-core-sample-templates/master/dotnet-core-music-linux/scripts/config-music.sh"
      ],
      "commandToExecute": "[concat('sudo sh config-music.sh ',variables('musicStoreSqlName'), ' ', parameters('adminUsername'), ' ', parameters('sqlAdminPassword'))]"
    }
  }
}

commandToExecute 属性移到 protected 配置可以帮助保护执行字符串,如以下示例中所示:

{
  "apiVersion": "2015-06-15",
  "type": "extensions",
  "name": "config-app",
  "location": "[resourceGroup().location]",
  "dependsOn": [
    "[concat('Microsoft.Compute/virtualMachines/', concat(variables('vmName'),copyindex()))]"
  ],
  "tags": {
    "displayName": "config-app"
  },
  "properties": {
    "publisher": "Microsoft.Azure.Extensions",
    "type": "CustomScript",
    "typeHandlerVersion": "2.1",
    "autoUpgradeMinorVersion": true,
    "settings": {
      "fileUris": [
        "https://raw.githubusercontent.com/Microsoft/dotnet-core-sample-templates/master/dotnet-core-music-linux/scripts/config-music.sh"
      ]
    },
    "protectedSettings": {
      "commandToExecute": "[concat('sudo sh config-music.sh ',variables('musicStoreSqlName'), ' ', parameters('adminUsername'), ' ', parameters('sqlAdminPassword'))]"
    }
  }
}

如何更新代理和扩展

代理和扩展使用相同的自动更新机制。

当更新可用且启用了自动更新时,只有在扩展发生更改或其他 VM 模型发生更改后,才会在 VM 上安装更新,例如:

  • 数据磁盘数
  • 扩展
  • 扩展标记
  • 启动诊断容器
  • 来宾 OS 机密
  • VM 大小
  • 网络配置文件

发布者在不同的时间向不同的区域推出更新,因此,不同区域中的 VM 可能使用不同的版本。

注意

某些更新可能不需要附加的防火墙规则。 请参阅网络访问

代理更新

Linux VM 代理将预配代理代码和扩展处理代码包含在一个包中 。 不能拆分这些代码。

如果要使用 cloud-init 在 Azure 上预配,可以禁用预配代理。

代理的受支持版本可以使用自动更新。 唯一可以更新的代码是扩展处理代码,不是预配代理代码。 预配代理代码是一次性运行的代码。

扩展处理代码负责:

  • 与 Azure 结构通信。
  • 处理 VM 扩展操作,例如安装、报告状态、更新各个扩展和删除扩展。 更新包含扩展处理代码的安全修补程序、bug 修复和增强功能。

安装代理时,创建父守护程序。 然后,此父进程生成一个用于处理扩展的子进程。 如果代理有可用的更新,会下载该更新。 父进程停止子进程,升级它,然后重新启动它。 如果存在更新问题,父进程回滚到以前的子版本。

父进程无法自动更新。 父进程仅可通过发行版包更新来更新。

若要查看运行的版本,请查看 waagent,如下所示:

waagent --version

输出类似于以下示例:

WALinuxAgent-2.2.45 running on <Linux Distro>
Python: 3.6.9
Goal state agent: 2.7.1.0

在前面的示例输出中,父进程或“部署包的版本”是 WALinuxAgent-2.2.45Goal state agent 值是自动更新版本。

强烈建议始终启用自动更新代理:AutoUpdate.Enabled=y。 如果未启用自动更新,则需要始终手动更新代理,且不会获得 bug 修复和安全修补程序。

扩展更新

当扩展更新可用且启用了自动更新时,在发生对 VM 模型的更改后,Azure Linux 代理会下载并升级扩展。

扩展自动更新以次要版本或修补程序的形式提供 。 预配扩展时,可以选择安装或不安装次要版本更新。 以下示例演示如何在 ARM 模板中使用 "autoUpgradeMinorVersion": true, 自动升级次要版本:

    "publisher": "Microsoft.Azure.Extensions",
    "type": "CustomScript",
    "typeHandlerVersion": "2.1",
    "autoUpgradeMinorVersion": true,
    "settings": {
        "fileUris": [
        "https://raw.githubusercontent.com/Microsoft/dotnet-core-sample-templates/master/dotnet-core-music-linux/scripts/config-music.sh"
        ]
    },

若要获取最新的次要版本 bug 修复,强烈建议始终在扩展部署中选择自动更新。 无法选择不安装包含安全或关键 bug 修复的修补程序更新。

如果你禁用自动更新或需要升级主版本,请使用 az vm extension setSet-AzVMExtension 并指定目标版本。

如何识别扩展更新

在 VM 上使用 autoUpgradeMinorVersion 识别是否设置了扩展

如果使用 autoUpgradeMinorVersion 预配了扩展,则可以从 VM 模型查看信息。 若要检查,请使用 az vm show 并提供资源组和 VM 名称,如下所示:

az vm show --resource-group myResourceGroup --name myVM

以下示例输出显示 autoUpgradeMinorVersion 设置为 true

  "resources": [
    {
      "autoUpgradeMinorVersion": true,
      "forceUpdateTag": null,
      "id": "/subscriptions/guid/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachines/myVM/extensions/customScript",

确定 autoUpgradeMinorVersion 事件发生的时间

若要查看何时对扩展执行了更新,请查看 VM 上的代理日志,路径为 /var/log/waagent.log

在下面的示例中,VM 已安装 Microsoft.OSTCExtensions.LinuxDiagnostic-2.3.9025。 为 Microsoft.OSTCExtensions.LinuxDiagnostic-2.3.9027 提供了修补程序。

INFO [Microsoft.OSTCExtensions.LinuxDiagnostic-2.3.9027] Expected handler state: enabled
INFO [Microsoft.OSTCExtensions.LinuxDiagnostic-2.3.9027] Decide which version to use
INFO [Microsoft.OSTCExtensions.LinuxDiagnostic-2.3.9027] Use version: 2.3.9027
INFO [Microsoft.OSTCExtensions.LinuxDiagnostic-2.3.9027] Current handler state is: NotInstalled
INFO [Microsoft.OSTCExtensions.LinuxDiagnostic-2.3.9027] Download extension package
INFO [Microsoft.OSTCExtensions.LinuxDiagnostic-2.3.9027] Unpack extension package
INFO Event: name=Microsoft.OSTCExtensions.LinuxDiagnostic, op=Download, message=Download succeeded
INFO [Microsoft.OSTCExtensions.LinuxDiagnostic-2.3.9027] Initialize extension directory
INFO [Microsoft.OSTCExtensions.LinuxDiagnostic-2.3.9027] Update settings file: 0.settings
INFO [Microsoft.OSTCExtensions.LinuxDiagnostic-2.3.9025] Disable extension.
INFO [Microsoft.OSTCExtensions.LinuxDiagnostic-2.3.9025] Launch command:diagnostic.py -disable
...
INFO Event: name=Microsoft.OSTCExtensions.LinuxDiagnostic, op=Disable, message=Launch command succeeded: diagnostic.py -disable
INFO [Microsoft.OSTCExtensions.LinuxDiagnostic-2.3.9027] Update extension.
INFO [Microsoft.OSTCExtensions.LinuxDiagnostic-2.3.9027] Launch command:diagnostic.py -update
2017/08/14 20:21:57 LinuxAzureDiagnostic started to handle.

代理权限

若要执行任务,代理需要作为根运行

排查 VM 扩展的问题

每个 VM 扩展可能都有特定的故障排除步骤。 例如,使用自定义脚本扩展时,可在运行该扩展的 VM 上于本地找到脚本执行的详细信息。

以下故障排除操作适用于所有 VM 扩展:

  • 若要查看 Azure Linux 代理日志,请在 /var/log/waagent.log 中查看预配扩展时的活动。

  • 在 /var/log/azure/extensionName 中查看扩展日志,以便获取详细信息。<>

  • 有关错误代码、已知问题和其他特定于扩展的信息,请查看特定于扩展的文档中的故障排除部分。

  • 查看系统日志。 检查其他可能影响了扩展的操作,例如,长时间安装另一个需要包管理器独占访问权限的应用程序。

扩展失败的常见原因

  • 扩展有 20 分钟的运行时间。 (自定义脚本和 Chef 除外,它们的运行时间为 90 分钟。)如果部署超过此时间,则会标记为超时。 超时的原因可能包括 VM 资源不足、在扩展尝试预配时其他 VM 配置或启动任务消耗了大量资源。

  • 不满足先决条件的最低要求。 某些扩展依赖于 VM SKU,例如 HPC 映像。 扩展可能需要满足特定的网络访问要求,例如,能够与 Azure 存储或公共服务通信。 其他可能的示例包括访问包存储库、磁盘空间耗尽或安全限制。

  • 包管理器独占访问权限。 在某些情况下,长时间运行的 VM 配置可能与扩展安装相冲突,因为两者都需要包管理器独占访问权限。

查看扩展状态

针对 VM 运行 VM 扩展后,请使用 az vm get-instance-view 返回扩展状态,如下所示:

az vm get-instance-view \
    --resource-group myResourceGroup \
    --name myVM \
    --query "instanceView.extensions"

输出类似于以下示例:

  {
    "name": "customScript",
    "statuses": [
      {
        "code": "ProvisioningState/failed/0",
        "displayStatus": "Provisioning failed",
        "level": "Error",
        "message": "Enable failed: failed to execute command: command terminated with exit status=127\n[stdout]\n\n[stderr]\n/bin/sh: 1: ech: not found\n",
        "time": null
      }
    ],
    "substatuses": null,
    "type": "Microsoft.Azure.Extensions.CustomScript",
    "typeHandlerVersion": "2.1.6"
  }

此外,还可以在 Azure 门户中找到扩展执行状态。 选择该 VM,然后依次选择“扩展”和所需的扩展。

重新运行 VM 扩展

在某些情况下,可能需要重新运行 VM 扩展。 如果要重新运行扩展,可以先删除扩展,然后使用所选执行方法重新运行扩展。

若要删除扩展,请使用 az vm extension delete,如下所示:

az vm extension delete \
    --resource-group myResourceGroup \
    --vm-name myVM \
    --name customScript

也可以在 Azure 门户中删除扩展:

  1. 选择 VM。
  2. 选择“扩展”。
  3. 选择该扩展。
  4. 选择“卸载”。

常见 VM 扩展参考

扩展名称 说明
适用于 Linux 的自定义脚本扩展 针对 Azure 虚拟机运行脚本。
VMAccess 扩展 重新获取对 Azure 虚拟机的访问权限。 还可使用它来管理用户和凭据
Azure 诊断扩展 管理 Azure 诊断。

后续步骤

有关 VM 扩展的详细信息,请参阅 Azure 虚拟机扩展和功能