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

将附加到 VM 的公共 IP 地址从“基本”升级到“标准”

重要

基本 SKU 公共 IP 将于 2025 年 9 月 30 日停用。 有关详细信息,请查看官方公告。 如果你当前使用的是基本 SKU 公共 IP,请确保在停用日期之前升级到标准 SKU 公共 IP。 本文将引导你完成升级过程。

若要详细了解基本 SKU 公共 IP 的停用情况和标准 SKU 公共 IP 的优势,请查看此处

升级概述

此脚本将附加到 VM 的任何公共 IP 地址从基本 SKU 升级到标准 SKU。 为了执行升级,公共 IP 地址分配方法在与 VM 取消关联之前设置为静态。 取消关联后,公共 IP SKU 将升级到“标准”,然后 IP 与 VM 重新关联。

由于公共 IP 分配在与 VM 分离之前设置为“静态”,因此即使是在脚本失败的情况下,IP 地址在升级过程中也不会更改。 在公共 IP 与 VM 分离之前,模块会仔细检查公共 IP 分配方法是否为“静态”。

模块将所有升级活动记录到名为 PublicIPUpgrade.log 的文件中,该文件是在执行模块的位置创建的(默认情况下)。

约束/不支持的方案

  • 具有与负载均衡器关联的 NIC 的 VM:由于与 VM 关联的负载均衡器和公共 IP SKU 必须匹配,因此如果 VM 的 NIC 也与负载均衡器关联(通过后端池或 NAT 池成员资格),则无法升级与 VM 关联的实例级公共 IP 地址。 使用脚本将基本负载均衡器升级到标准 SKU 同时升级负载均衡器和公共 IP。

  • 没有网络安全组的 VM:具有要升级的 IP 的 VM 必须有网络安全组 (NSG) 与使用公共 IP 的每个 IP 配置的子网相关联,或者与 NIC 直接关联。 这是因为标准 SKU 公共 IP “默认安全”,这意味着必须在 NSG 上显式允许流向公共 IP 的任何流量才能到达 VM。 默认情况下,基本 SKU 公共 IP 允许任何流量。 如果在没有 NSG 的情况下升级公共 IP SKU,会导致入站 Internet 流量进入之前允许的公共 IP,并在迁移后阻止基本 SKU。 请参阅:公共 IP SKU

  • 具有公共 IP 配置的虚拟机规模集:如果你有一个虚拟机规模集(统一模型)且每个实例都有公共 IP 配置,请注意这些配置不是公共 IP 资源,因此无法升级。 转而可移除基本 IP 配置,并使用 SKU 属性指定每个虚拟机规模集实例都需要标准 IP 配置,如此处所示。

先决条件

  • 安装最新版本的 PowerShell
  • 确保是否安装了最新的 Az PowerShell 模块(如果没有最新的 Az PowerShell 模块,请进行安装)

下载脚本

PowerShell 库下载迁移脚本。

PS C:\> Install-Module -Name AzureVMPublicIPUpgrade -Scope CurrentUser -Repository PSGallery -Force

使用模块

  1. 使用 Connect-AzAccount 连接到所需的 Microsoft Entra 租户和 Azure 订阅

    PS C:\> Connect-AzAccount -Tenant <TenantId> -Subscription <SubscriptionId>
    
  2. 查找附加且要升级的基本公共 IP 的 VM。 记下其名称和资源组名称。

  3. 检查模块参数:

    • VMName [string] 必需 - 此参数是 VM 的名称。
    • ResourceGroupName [string] 必需 - 此参数是 VM 的资源组,其中包含附加的要升级的基本公共 IP。
  4. 运行 Upgrade 命令。

脚本的示例用法

若要升级单个 VM,请将 VM 名称和资源组名称作为参数传递。

    Start-VMPublicIPUpgrade -VMName 'myVM' -ResourceGroupName 'myRG'

若要在不进行任何更改的情况下评估单个 VM 的升级操作,请添加 -WhatIf 参数。

    Start-VMPublicIPUpgrade -VMName 'myVM' -ResourceGroupName 'myRG' -WhatIf

若要升级资源组中的所有 VM,请跳过没有网络安全组的 VM。

    Get-AzVM -ResourceGroupName 'myRG' | Start-VMPublicIPUpgrade -skipVMMissingNSG

从失败的迁移中恢复

如果迁移由于暂时性问题(例如网络中断或客户端系统问题)而失败,可重新运行迁移,在目标状态下配置 VM 和公共 IP。 在执行时,脚本会输出恢复日志文件,用于确保正确重新配置 VM。 查看在执行脚本的位置创建的日志文件 PublicIPUpgrade.log

若要从失败的升级中恢复,请使用 -recoverFromFile 参数将恢复日志文件路径传递给脚本,并使用 -VMName-VMResourceGroup(或 -VMResourceID)参数标识要恢复的 VM,如本示例所示。

    Start-VMPublicIPUpgrade -RecoverFromFile ./PublicIPUpgrade_Recovery_2020-01-01-00-00.csv -VMName myVM -VMResourceGroup -rg-myrg

常见问题

迁移需要多长时间?VM 在其公共 IP 上有多长时间无法访问?

升级 VM 的公共 IP 所需的时间取决于与该 VM 关联的公共 IP 和网络接口的数量。 在测试中,具有单个 NIC 和公共 IP 的 VM 需要 1 到 2 分钟的时间来升级。 VM 上的每个 NIC 会使升级时间额外增加大约一分钟,每个公共 IP 使时间增加几秒。

是否可回滚到基本 SKU 公共 IP?

无法将公共 IP 地址从“标准”降级为“基本”。

是否可以在执行之前测试迁移?

如果没有完成操作,无法评估公共 IP 的升级情况。 不过,此脚本包含一个 -whatif 参数,它用于检查 VM 是否支持升级,并在不执行操作的情况下演练步骤。

脚本是否支持区域基本 SKU 公共 IP?

是,将区域基本 SKU 公共 IP 升级到区域标准 SKU 公共 IP 的过程是相同的,适用于脚本。

使用 Resource Graph 列出具有需要升级的公共 IP 的 VM

列出具有基本 SKU 公共 IP 地址的虚拟机的查询

此查询返回附加了基本 SKU 公共 IP 地址的虚拟机 ID 列表。

Resources
| where type =~ 'microsoft.compute/virtualmachines'
| project vmId = tolower(id), vmNics = properties.networkProfile.networkInterfaces
| join (
  Resources |
  where type =~ 'microsoft.network/networkinterfaces' |
  project nicVMId = tolower(tostring(properties.virtualMachine.id)), allVMNicID = tolower(id), nicIPConfigs = properties.ipConfigurations)
  on $left.vmId == $right.nicVMId
| join (
  Resources
  | where type =~ 'microsoft.network/publicipaddresses' and isnotnull(properties.ipConfiguration.id)
  | where sku.name == 'Basic' // exclude to find all VMs with Public IPs
  | project pipId = id, pipSku = sku.name, pipAssociatedNicId = tolower(tostring(split(properties.ipConfiguration.id, '/ipConfigurations/')[0])))
  on $left.allVMNicID == $right.pipAssociatedNicId
| project vmId, pipId, pipSku
az graph query -q "Resources | where type =~ 'microsoft.compute/virtualmachines' | project vmId = tolower(id), vmNics = properties.networkProfile.networkInterfaces | join (Resources | where type =~ 'microsoft.network/networkinterfaces' | project nicVMId = tolower(tostring(properties.virtualMachine.id)), allVMNicID = tolower(id), nicIPConfigs = properties.ipConfigurations) on \$left.vmId == \$right.nicVMId | join ( Resources | where type =~ 'microsoft.network/publicipaddresses' and isnotnull(properties.ipConfiguration.id) | where sku.name == 'Basic' | project pipId = id, pipSku = sku.name, pipAssociatedNicId = tolower(tostring(split(properties.ipConfiguration.id, '/ipConfigurations/')[0]))) on \$left.allVMNicID == \$right.pipAssociatedNicId | project vmId, pipId, pipSku"

后续步骤