虚拟机的可靠性

本文包含虚拟机的特定可靠性建议,以及有关具有可用性区域的 VM 区域复原的详细信息和跨区域灾难恢复和业务连续性

有关 Azure 可靠性的体系结构概述,请参阅《Azure 可靠性》。

可靠性建议

本部分包含针对实现复原能力和可用性的建议。 每个建议可归入以下两个类别之一:

  • 运行状况项涵盖配置项目和构成 Azure 工作负载的主要组件的正确功能等方面,例如 Azure 资源配置设置、对其他服务的依赖项等。

  • 风险项涵盖可用性和恢复要求、测试、监视、部署和其他项目(如果未解决,则会增加环境中出现问题的可能性)等方面。

可靠性建议优先级矩阵

每项建议都根据以下优先级矩阵进行标记:

映像 优先级 说明
需要立即修复。
在 3-6 个月内修复。
需要审查。

可靠性建议摘要

类别 优先级 建议
高可用性 使用 Azure 虚拟机规模集 Flex 在两个或以上 VM 上运行生产工作负载
跨可用性区域部署 VM 或将虚拟机规模集与区域配合使用
使用可用性集将 VM 迁移到虚拟机规模集 Flex
对 VM 磁盘使用托管磁盘
灾难恢复 使用 Azure Site Recovery 复制 VM
使用 Azure 备份服务备份 VM 上的数据
性能 在数据磁盘上托管应用程序和数据库数据
生产 VM 应使用 SSD 磁盘
启用加速网络 (AccelNet)
启用 AccelNet 后,必须手动更新 GuestOS NIC 驱动程序
管理 VM-9:监视处于已停止状态的 VM
使用 VM 的维护配置
安全性 VM 不应具有直接关联的公共 IP
虚拟网络接口具有关联的 NSG
仅应为网络虚拟设备启用 IP 转发
对 VM 磁盘的网络访问应设置为“禁用公共访问并启用专用访问”
默认启用磁盘加密和静态数据加密
联网 应在虚拟网络级别配置客户 DNS 服务器
存储 应仅在群集服务器中启用共享磁盘
遵从性 确保 VM 符合 Azure 策略
监视 启用 VM 见解
为所有 Azure 资源配置诊断设置

高可用性

使用虚拟机规模集 Flex 在两个或以上 VM 上运行生产工作负载

若要防止应用程序工作负载因磁盘或 VM 暂时不可用而停机,建议使用虚拟机规模集 Flex 在两个或以上 VM 上运行生产工作负载。

若要运行生产工作负载,可以使用:

  • Azure 虚拟机规模集来创建并管理一组负载均衡的 VM。 可以根据需求或定义的计划自动增减 VM 实例的数目。

  • 可用性区域。 有关可用性区域和 VM 的详细信息,请参阅《可用性区域支持》。

// Azure Resource Graph Query
// Find all VMs that are not associated with a VMSS Flex instance
resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| where isnull(properties.virtualMachineScaleSet.id)
| project recommendationId="vm-1", name, id, tags

跨可用性区域部署 VM 或将虚拟机规模集与区域配合使用*

创建 VM 时,请使用可用性区域来保护应用程序和数据免受数据中心故障(虽然不太可能出现)的影响。 有关 VM 可用性区域的详细信息,请参阅本文档中的《可用性区域支持》。

有关如何在创建 VM 时启用可用性区域支持,请参阅《创建可用性区域支持》。

有关如何将现有虚拟机迁移到可用性区域支持的信息,请参阅迁移到可用性区域支持

// Azure Resource Graph Query
// Find all VMs that are not assigned to a Zone
Resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| where isnull(zones)
| project recommendationId="vm-2", name, id, tags, param1="No Zone"

使用可用性集将 VM 迁移到虚拟机规模集 Flex

通过将工作负载从 VM 迁移到虚拟机规模集 Flex,实现工作负载现代化。

使用虚拟机规模集 Flex,可以通过以下两种方式之一部署虚拟机:

  • 跨区域
  • 在同一区域中,但自动跨容错域 (FD) 和更新域 (UD)。

在 N 层应用程序中,建议将每个应用程序层放入其自己的虚拟机规模集 Flex 中。

// Azure Resource Graph Query
// Find all VMs using Availability Sets
resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| where isnotnull(properties.availabilitySet)
| project recommendationId = "vm-3", name, id, tags, param1=strcat("availabilitySet: ",properties.availabilitySet.id)

对 VM 磁盘使用托管磁盘*

为了可用性集中的 VM 有更好的可靠性,请使用托管磁盘。 托管磁盘彼此之间充分隔离,可避免出现单一故障点。 此外,托管磁盘不受存储帐户中创建的 VHD 的 IOPS 限制。

// Azure Resource Graph Query
// Find all VMs that are not using Managed Disks
Resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| where isnull(properties.storageProfile.osDisk.managedDisk)
| project recommendationId = "vm-5", name, id, tags

灾难恢复

使用 Azure Site Recovery 复制 VM

使用 Site Recovery 复制 Azure VM 时,所有 VM 磁盘将以异步方式持续复制到目标区域。 恢复点每隔几分钟创建一次,这为你提供了恢复点目标 (RPO)(以分钟为单位)。 可以开展灾难恢复演练任意次,这不会影响生产应用程序或正在进行的复制。

如需了解如何运行灾难恢复演练,请参阅《运行测试故障转移》。

// Azure Resource Graph Query
// Find all VMs that do NOT have replication with ASR enabled
// Run query to see results.
resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| project name, id, tags
| join kind=leftouter (
    recoveryservicesresources
    | where type =~ 'Microsoft.RecoveryServices/vaults/replicationFabrics/replicationProtectionContainers/replicationProtectedItems'
    | where properties.providerSpecificDetails.dataSourceInfo.datasourceType =~ 'AzureVm'
    | project id=properties.providerSpecificDetails.dataSourceInfo.resourceId
    | extend name=strcat_array(array_slice(split(id, '/'), 8, -1), '/')
) on name
| where isnull(id1)
| project-away id1
| project-away name1
| project recommendationId = "vm-4", name, id, tags
| order by id asc

使用 Azure 备份服务备份 VM 上的数据

Azure 备份服务提供简单、安全且经济高效的解决方案来备份数据,并从 Microsoft Azure 云恢复数据。 详细信息请参阅《什么是 Azure 备份服务》。

// Azure Resource Graph Query
// Find all VMs that do NOT have Backup enabled
// Run query to see results.
resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| project name, id, tags
| join kind=leftouter (
    recoveryservicesresources
    | where type =~ 'Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems'
    | where properties.dataSourceInfo.datasourceType =~ 'Microsoft.Compute/virtualMachines'
    | project idBackupEnabled=properties.sourceResourceId
    | extend name=strcat_array(array_slice(split(idBackupEnabled, '/'), 8, -1), '/')
) on name
| where isnull(idBackupEnabled)
| project-away idBackupEnabled
| project-away name1
| project recommendationId = "vm-7", name, id, tags
| order by id asc

性能

在数据磁盘上托管应用程序和数据库数据

数据磁盘是附加到 VM 的托管磁盘。 使用数据磁盘存储应用程序数据或其他需要保留的数据。 数据磁盘注册为 SCSI 驱动器并且带有所选择的字母标记。 将数据托管在数据磁盘上可以轻松备份或还原数据。 还可以迁移磁盘,而无需移动整个 VM 和操作系统。 此外,还可以选择不同类型、大小和性能的磁盘 SKU 以满足自身需求。 有关数据磁盘的详细信息,请参阅《数据磁盘》。

// Azure Resource Graph Query
// Find all VMs that only have OS Disk
Resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| where array_length(properties.storageProfile.dataDisks) < 1
| project recommendationId = "vm-6", name, id, tags

生产 VM 应使用 SSD 磁盘

高级 SSD 磁盘为 I/O 密集型应用程序和生产工作负载提供高性能、低延迟的磁盘支持。 标准 SSD 磁盘是一种经济高效的存储选择,针对需要在较低 IOPS 级别下保持性能一致性的工作负载进行了优化。

建议你:

  • 对于开发/测试方案和不太重要的工作负载,请使用标准 HDD 磁盘,这可以最大程度地降低成本。
  • 对于具有高级功能的 VM,请使用高级 SSD 磁盘取代标准 HDD 磁盘。 对于为所有操作系统磁盘和数据磁盘使用高级存储的单实例 VM,Azure 保证 VM 的连接性至少达到 99.9%。

如果要从标准 HDD 升级到高级 SSD 磁盘,请考虑以下问题:

  • 升级需要 VM 重启,此过程需要 3-5 分钟才能完成。
  • 如果 VM 是任务关键型生产 VM,请对比高级磁盘的成本和改善后的可用性。

有关 Azure 托管磁盘和磁盘类型的详细信息,请参阅《Azure 托管磁盘类型》。

// Azure Resource Graph Query
// Find all disks with StandardHDD sku attached to VMs
Resources
| where type =~ 'Microsoft.Compute/disks'
| where sku.name == 'Standard_LRS' and sku.tier == 'Standard'
| where managedBy != ""
| project recommendationId = "vm-8", name, id, tags, param1=strcat("managedBy: ", managedBy)

启用加速网络 (AccelNet)

使用 AccelNet 可以实现对 VM 的单根 I/O 虚拟化 (SR-IOV),大幅提升其网络性能。 这种高性能路径会绕过数据路径中的主机,为受支持 VM 类型上最苛刻的网络工作负载降低延迟、抖动和 CPU 利用率。

有关加速网络的详细信息,请参阅《加速网络

// Azure Resource Graph Query
// Find all VM NICs that do not have Accelerated Networking enabled
resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| mv-expand nic = properties.networkProfile.networkInterfaces
| project name, id, tags, lowerCaseNicId = tolower(nic.id), vmSize = tostring(properties.hardwareProfile.vmSize)
| join kind = inner (
    resources
    | where type =~ 'Microsoft.Network/networkInterfaces'
    | where properties.enableAcceleratedNetworking == false
    | project nicName = split(id, "/")[8], lowerCaseNicId = tolower(id)
    )
    on lowerCaseNicId
| summarize nicNames = make_set(nicName) by name, id, tostring(tags), vmSize
| extend param1 = strcat("NicName: ", strcat_array(nicNames, ", ")), param2 = strcat("VMSize: ", vmSize)
| project recommendationId = "vm-10", name, id, tags, param1, param2
| order by id asc

启用 AccelNet 后,必须手动更新 GuestOS NIC 驱动程序

启用 AccelNet 后,GuestOS 中的默认 Azure 虚拟网络接口将替换为 Mellanox 接口。 因此,GuestOS NIC 驱动程序由第三方供应商 Mellanox 提供。 尽管 Azure 维护的市场映像随最新版本的 Mellanox 驱动程序一起提供,但部署 VM 后,需要每隔六个月手动更新 GuestOS NIC 驱动程序。

// cannot-be-validated-with-arg

Management

查看处于已停止状态的 VM

VM 实例有不同的状态,包括预配状态和电源状态。 如果 VM 处于已停止状态,则 VM 可能面临问题或不再被需要,可以将其删除以降低成本。

// Azure Resource Graph Query
// Find all VMs that are NOT running
Resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| where properties.extended.instanceView.powerState.displayStatus != 'VM running'
| project recommendationId = "vm-9", name, id, tags

使用 VM 的维护配置

如要确保在计划期间更新/中断 VM,请使用维护配置设置来规划和管理更新。 有关使用维护配置管理 VM 更新的详细信息,请参阅《使用维护配置管理 VM 更新》。

// Azure Resource Graph Query
// Find VMS that do not have maintenance configuration assigned
Resources
| extend resourceId = tolower(id)
| project name, location, type, id, tags, resourceId, properties
| where type =~ 'Microsoft.Compute/virtualMachines'
| join kind=leftouter (
maintenanceresources
| where type =~ "microsoft.maintenance/configurationassignments"
| project planName = name, type, maintenanceProps = properties
| extend resourceId = tostring(maintenanceProps.resourceId)
) on resourceId
| where isnull(maintenanceProps)
| project recommendationId = "vm-22",name, id, tags
| order by id asc

安全性

VM 不应具有直接关联的公共 IP

如果 VM 需要出站 Internet 连接,建议使用 NAT 网关或 Azure 防火墙。 NAT 网关或 Azure 防火墙有助于提高服务的安全性和复原能力,因为这两种服务都具有更高的可用性和源网络地址转换 (SNAT) 端口。 对于入站 Internet 连接,建议使用负载均衡解决方案,例如 Azure 负载均衡器和应用程序网关。

// Azure Resource Graph Query
// Find all VMs with PublicIPs directly associated with them
Resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| where isnotnull(properties.networkProfile.networkInterfaces)
| mv-expand nic=properties.networkProfile.networkInterfaces
| project name, id, tags, nicId = nic.id
| extend nicId = tostring(nicId)
| join kind=inner (
    Resources
    | where type =~ 'Microsoft.Network/networkInterfaces'
    | where isnotnull(properties.ipConfigurations)
    | mv-expand ipconfig=properties.ipConfigurations
    | extend publicIp = tostring(ipconfig.properties.publicIPAddress.id)
    | where publicIp != ""
    | project name, nicId = tostring(id), publicIp
) on nicId
| project recommendationId = "vm-12", name, id, tags
| order by id asc

VM 网络接口具有关联的网络安全组 (NSG)*

建议将 NSG 关联到子网或网络接口,但不要同时关联两者。 由于关联到子网的 NSG 中的规则可能与关联到网络接口的 NSG 中的规则冲突,因此可能会出现意外的通信问题需要排除故障。 有关详细信息,请参阅《子网内流量》。

// Azure Resource Graph Query
// Provides a list of virtual machines and associated NICs that do have an NSG associated to them and also an NSG associated to the subnet.
Resources
| where type =~ 'Microsoft.Network/networkInterfaces'
| where isnotnull(properties.networkSecurityGroup)
| mv-expand ipConfigurations = properties.ipConfigurations, nsg = properties.networkSecurityGroup
| project nicId = tostring(id), subnetId = tostring(ipConfigurations.properties.subnet.id), nsgName=split(nsg.id, '/')[8]
| parse kind=regex subnetId with '/virtualNetworks/' virtualNetwork '/subnets/' subnet
    | join kind=inner (
        Resources
        | where type =~ 'Microsoft.Network/NetworkSecurityGroups' and isnotnull(properties.subnets)
        | project name, resourceGroup, subnet=properties.subnets
        | mv-expand subnet
        | project subnetId=tostring(subnet.id)
    ) on subnetId
    | project nicId
| join kind=leftouter (
    Resources
    | where type =~ 'Microsoft.Compute/virtualMachines'
    | where isnotnull(properties.networkProfile.networkInterfaces)
    | mv-expand nic=properties.networkProfile.networkInterfaces
    | project vmName = name, vmId = id, tags, nicId = nic.id, nicName=split(nic.id, '/')[8]
    | extend nicId = tostring(nicId)
) on nicId
| project recommendationId = "vm-13", name=vmName, id = vmId, tags, param1 = strcat("nic-name=", nicName)

仅应为网络虚拟设备启用 IP 转发

IP 转发使虚拟机网络接口能够:

  • 接收未针对分配给任一网络接口 IP 配置的 IP 地址的网络流量。

  • 使用与分配给某一网络接口 IP 配置的源 IP 地址不同的地址发送网络流量。

必须为附加到接收转发流量 VM 的每个网络接口启用 IP 转发设置。 无论 VM 上附加了一个还是多个网络接口,都可转发流量。 尽管 IP 转发是一项 Azure 设置,但 VM 还是必须运行可以转发流量的应用程序,例如防火墙、WAN 优化和负载均衡应用程序。

如需了解如何启用或禁用 IP 转发,请参阅《启用或禁用 IP 转发》。

// Azure Resource Graph Query
// Find all VM NICs that have IPForwarding enabled. This feature is usually only required for Network Virtual Appliances
Resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| where isnotnull(properties.networkProfile.networkInterfaces)
| mv-expand nic=properties.networkProfile.networkInterfaces
| project name, id, tags, nicId = nic.id
| extend nicId = tostring(nicId)
| join kind=inner (
    Resources
    | where type =~ 'Microsoft.Network/networkInterfaces'
    | where properties.enableIPForwarding == true
    | project nicId = tostring(id)
) on nicId
| project recommendationId = "vm-14", name, id, tags
| order by id asc

对 VM 磁盘的网络访问应设置为“禁用公共访问并启用专用访问”

建议将 VM 磁盘网络访问设置为“禁用公共访问并启用专用访问”,并创建专用终结点。 如需了解如何创建专用终结点,请参阅《创建专用终结点》。

// Azure Resource Graph Query
// Find all Disks with "Enable public access from all networks" enabled
resources
| where type =~ 'Microsoft.Compute/disks'
| where properties.publicNetworkAccess == "Enabled"
| project id, name, tags, lowerCaseDiskId = tolower(id)
| join kind = leftouter (
    resources
    | where type =~ 'Microsoft.Compute/virtualMachines'
    | project osDiskVmName = name, lowerCaseOsDiskId = tolower(properties.storageProfile.osDisk.managedDisk.id)
    | join kind = fullouter (
        resources
        | where type =~ 'Microsoft.Compute/virtualMachines'
        | mv-expand dataDisks = properties.storageProfile.dataDisks
        | project dataDiskVmName = name, lowerCaseDataDiskId = tolower(dataDisks.managedDisk.id)
        )
        on $left.lowerCaseOsDiskId == $right.lowerCaseDataDiskId
    | project lowerCaseDiskId = coalesce(lowerCaseOsDiskId, lowerCaseDataDiskId), vmName = coalesce(osDiskVmName, dataDiskVmName)
    )
    on lowerCaseDiskId
| summarize vmNames = make_set(vmName) by name, id, tostring(tags)
| extend param1 = iif(isempty(vmNames[0]), "VMName: n/a", strcat("VMName: ", strcat_array(vmNames, ", ")))
| project recommendationId = "vm-17", name, id, tags, param1
| order by id asc

默认启用磁盘加密和静态数据加密

托管磁盘可以使用多种加密类型,包括 Azure 磁盘加密 (ADE)、服务器端加密 (SSE) 和主机加密。

  • Azure 磁盘加密有助于保护数据,使组织能够信守在安全性与合规性方面作出的承诺。
  • 将 Azure 托管磁盘(OS 和数据磁盘)上存储的数据保存到存储群集时,Azure 磁盘存储服务器端加密(也称为静态加密或 Azure 存储加密)会自动对这些数据进行加密。
  • 主机加密可确保将存储在托管 VM 的 VM 主机上的数据静态加密,并以加密形式将其传送到存储群集。
  • 机密磁盘加密将磁盘加密密钥绑定到 VM 的 TPM,并且只允许 VM 访问受保护的磁盘内容。

有关托管磁盘加密选项的详细信息,请参阅《托管磁盘加密选项概述》。

// under-development

网络

应在虚拟网络级别配置客户 DNS 服务器

在虚拟网络中配置 DNS 服务器,以避免整个环境中的名称解析不一致。 有关 Azure 虚拟网络资源名称解析的详细信息,请参阅《VM 和云服务的名称解析》。

// Azure Resource Graph Query
// Find all VM NICs that have DNS Server settings configured in any of the NICs
Resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| where isnotnull(properties.networkProfile.networkInterfaces)
| mv-expand nic=properties.networkProfile.networkInterfaces
| project name, id, tags, nicId = nic.id
| extend nicId = tostring(nicId)
| join kind=inner (
    Resources
    | where type =~ 'Microsoft.Network/networkInterfaces'
    | project name, id, dnsServers = properties.dnsSettings.dnsServers
    | extend hasDns = array_length(dnsServers) >= 1
    | where hasDns != 0
    | project name, nicId = tostring(id)
) on nicId
| project recommendationId = "vm-15", name, id, tags
| order by id asc

存储

应仅在群集服务器中启用共享磁盘

Azure 共享磁盘Azure 托管磁盘的一项功能,可同时将托管磁盘附加到多个 VM。 将托管磁盘附加到多个 VM 时,可以向 Azure 部署新的群集应用程序或迁移现有的群集应用程序。 共享磁盘仅应用于将磁盘分配给群集的多个 VM 成员的情况。

如需详细了解如何为托管磁盘启用共享磁盘,请参阅《启用共享磁盘》。

// Azure Resource Graph Query
// Find all Disks configured to be Shared. This is not an indication of an issue, but if a disk with this configuration is assigned to two or more VMs without a proper disk control mechanism (like a WSFC) it can lead to data loss
resources
| where type =~ 'Microsoft.Compute/disks'
| where isnotnull(properties.maxShares)
| project id, name, tags, lowerCaseDiskId = tolower(id), diskState = tostring(properties.diskState)
| join kind = leftouter (
    resources
    | where type =~ 'Microsoft.Compute/virtualMachines'
    | project osDiskVmName = name, lowerCaseOsDiskId = tolower(properties.storageProfile.osDisk.managedDisk.id)
    | join kind = fullouter (
        resources
        | where type =~ 'Microsoft.Compute/virtualMachines'
        | mv-expand dataDisks = properties.storageProfile.dataDisks
        | project dataDiskVmName = name, lowerCaseDataDiskId = tolower(dataDisks.managedDisk.id)
        )
        on $left.lowerCaseOsDiskId == $right.lowerCaseDataDiskId
    | project lowerCaseDiskId = coalesce(lowerCaseOsDiskId, lowerCaseDataDiskId), vmName = coalesce(osDiskVmName, dataDiskVmName)
    )
    on lowerCaseDiskId
| summarize vmNames = make_set(vmName) by name, id, tostring(tags), diskState
| extend param1 = strcat("DiskState: ", diskState), param2 = iif(isempty(vmNames[0]), "VMName: n/a", strcat("VMName: ", strcat_array(vmNames, ", ")))
| project recommendationId = "vm-16", name, id, tags, param1, param2
| order by id asc

合规性

确保 VM 符合 Azure 策略

为了所运行的应用程序,请务必确保虚拟机 (VM) 安全。 保护 VM 可以添加一个或多个 Azure 服务和功能,这些服务和功能涵盖保护对 VM 的访问和保护数据存储。 有关如何保护 VM 和应用程序安全的详细信息,请参阅《Azure 虚拟机的 Azure Policy 合规检查》。

// Azure Resource Graph Query
// Find all VMs in "NonCompliant" state with Azure Policies
PolicyResources
| where type =~ "Microsoft.PolicyInsights/policyStates" and properties.resourceType =~ "Microsoft.Compute/virtualMachines" and properties.complianceState =~ "NonCompliant"
| project
    policyAssignmentName = properties.policyAssignmentName,
    policyDefinitionName = properties.policyDefinitionName,
    lowerCasePolicyDefinitionIdOfPolicyState = tolower(properties.policyDefinitionId),
    lowerCaseVmIdOfPolicyState = tolower(properties.resourceId)
| join kind = leftouter (
    PolicyResources
    | where type =~ "Microsoft.Authorization/policyDefinitions"
    | project lowerCasePolicyDefinitionId = tolower(id), policyDefinitionDisplayName = properties.displayName
    )
    on $left.lowerCasePolicyDefinitionIdOfPolicyState == $right.lowerCasePolicyDefinitionId
| project policyAssignmentName, policyDefinitionName, policyDefinitionDisplayName, lowerCaseVmIdOfPolicyState
| join kind = leftouter (
    Resources
    | where type =~ "Microsoft.Compute/virtualMachines"
    | project vmName = name, vmId = id, vmTags = tags, lowerCaseVmId = tolower(id)
    )
    on $left.lowerCaseVmIdOfPolicyState == $right.lowerCaseVmId
| extend
    param1 = strcat("AssignmentName: ", policyAssignmentName),
    param2 = strcat("DefinitionName: ", policyDefinitionDisplayName),  // Align to Azure portal's term.
    param3 = strcat("DefinitionID: ", policyDefinitionName)            // Align to Azure portal's term.
| project recommendationId = "vm-18", name = vmName, id = vmId, tags = vmTags, param1, param2, param3

监视

启用 VM 见解

启用 VM 见解以更深入地了解虚拟机的运行状况和性能。 VM 见解通过监视 VM 和虚拟机规模集的运行进程和对其他资源的依赖关系,提供有关 VM 和虚拟机规模集的性能和运行状况的信息。 VM 见解可以通过识别性能瓶颈和网络问题来帮助提供重要应用程序的可预测性能和可用性。 见解还有助于了解某个问题是否与其他依赖项相关。

// Azure Resource Graph Query
// Check for VMs without Azure Monitoring Agent extension installed, missing Data Collection Rule or Data Collection Rule without performance enabled.
Resources
| where type == 'microsoft.compute/virtualmachines'
| project idVm = tolower(id), name, tags
| join kind=leftouter (
    InsightsResources
    | where type =~ "Microsoft.Insights/dataCollectionRuleAssociations" and id has "Microsoft.Compute/virtualMachines"
    | project idDcr = tolower(properties.dataCollectionRuleId), idVmDcr = tolower(substring(id, 0, indexof(id, "/providers/Microsoft.Insights/dataCollectionRuleAssociations/"))))
on $left.idVm == $right.idVmDcr
| join kind=leftouter (
    Resources
    | where type =~ "Microsoft.Insights/dataCollectionRules"
    | extend
        isPerformanceEnabled = iif(properties.dataSources.performanceCounters contains "Microsoft-InsightsMetrics" and properties.dataFlows contains "Microsoft-InsightsMetrics", true, false),
        isMapEnabled = iif(properties.dataSources.extensions contains "Microsoft-ServiceMap" and properties.dataSources.extensions contains "DependencyAgent" and properties.dataFlows contains "Microsoft-ServiceMap", true, false)//,
    | where isPerformanceEnabled or isMapEnabled
    | project dcrName = name, isPerformanceEnabled, isMapEnabled, idDcr = tolower(id))
on $left.idDcr == $right.idDcr
| join kind=leftouter (
    Resources
        | where type == 'microsoft.compute/virtualmachines/extensions' and (name contains 'AzureMonitorWindowsAgent' or name contains 'AzureMonitorLinuxAgent')
        | extend idVmExtension = tolower(substring(id, 0, indexof(id, '/extensions'))), extensionName = name)
on $left.idVm == $right.idVmExtension
| where isPerformanceEnabled != 1 or (extensionName != 'AzureMonitorWindowsAgent' and extensionName != 'AzureMonitorLinuxAgent')
| project recommendationId = "vm-20", name, id = idVm, tags, param1 = strcat('MonitoringExtension:', extensionName), param2 = strcat('DataCollectionRuleId:', idDcr), param3 = strcat('isPerformanceEnabled:', isPerformanceEnabled)

为所有 Azure 资源配置诊断设置

默认情况下,平台指标会自动发送到 Azure Monitor 指标,无需配置。 平台日志为 Azure 资源及其所依赖的 Azure 平台提供详细的诊断和审核信息,日志类型如下:

  • 资源日志,在路由到目标之前不会被收集。
  • 活动日志,单独存在,但可路由到其他位置。

每个 Azure 资源都需有自身的诊断设置,其设置定义了以下条件:

  • ,要发送到设置规定目标的指标和日志数据。 可用类型因资源类型而异。
  • 目标:要发送到的一个或多个目标。

一个诊断设置只能为每个目标定义一种类型。 若要将数据发送到多个特定的目标类型(例如,两个不同的 Log Analytics 工作区),请创建多个设置。 每个资源最多可以有五个诊断设置。

更多信息请参阅《Azure Monitor 的诊断设置》。

// Azure Resource Graph Query
// Find all Virtual Machines without diagnostic settings enabled/with diagnostic settings enabled but not configured both performance counters and event logs/syslogs.
resources
| where type =~ "microsoft.compute/virtualmachines"
| project name, id, tags, lowerCaseVmId = tolower(id)
| join kind = leftouter (
    resources
    | where type =~ "Microsoft.Compute/virtualMachines/extensions" and properties.publisher =~ "Microsoft.Azure.Diagnostics"
    | project
        lowerCaseVmIdOfExtension = tolower(substring(id, 0, indexof(id, "/extensions/"))),
        extensionType = properties.type,
        provisioningState = properties.provisioningState,
        storageAccount = properties.settings.StorageAccount,
        // Windows
        wadPerfCounters = properties.settings.WadCfg.DiagnosticMonitorConfiguration.PerformanceCounters.PerformanceCounterConfiguration,
        wadEventLogs = properties.settings.WadCfg.DiagnosticMonitorConfiguration.WindowsEventLog,
        // Linux
        ladPerfCounters = properties.settings.ladCfg.diagnosticMonitorConfiguration.performanceCounters.performanceCounterConfiguration,
        ladSyslog = properties.settings.ladCfg.diagnosticMonitorConfiguration.syslogEvents
    | extend
        // Windows
        isWadPerfCountersConfigured = iif(array_length(wadPerfCounters) > 0, true, false),
        isWadEventLogsConfigured = iif(isnotnull(wadEventLogs) and array_length(wadEventLogs.DataSource) > 0, true, false),
        // Linux
        isLadPerfCountersConfigured = iif(array_length(ladPerfCounters) > 0, true, false),
        isLadSyslogConfigured = isnotnull(ladSyslog)
    | project
        lowerCaseVmIdOfExtension,
        extensionType,
        provisioningState,
        storageAccount,
        isPerfCountersConfigured = case(extensionType =~ "IaaSDiagnostics", isWadPerfCountersConfigured, extensionType =~ "LinuxDiagnostic", isLadPerfCountersConfigured, false),
        isEventLogsConfigured = case(extensionType =~ "IaaSDiagnostics", isWadEventLogsConfigured, extensionType =~ "LinuxDiagnostic", isLadSyslogConfigured, false)
    )
    on $left.lowerCaseVmId == $right.lowerCaseVmIdOfExtension
| where isempty(lowerCaseVmIdOfExtension) or provisioningState !~ "Succeeded" or not(isPerfCountersConfigured and isEventLogsConfigured)
| extend
    param1 = strcat("DiagnosticSetting: ", iif(isnotnull(extensionType), strcat("Enabled, partially configured (", extensionType, ")"), "Not enabled")),
    param2 = strcat("ProvisioningState: ", iif(isnotnull(provisioningState), provisioningState, "n/a")),
    param3 = strcat("storageAccount: ", iif(isnotnull(storageAccount), storageAccount, "n/a")),
    param4 = strcat("PerformanceCounters: ", case(isnull(isPerfCountersConfigured), "n/a", isPerfCountersConfigured, "Configured", "Not configured")),
    param5 = strcat("EventLogs/Syslogs: ", case(isnull(isEventLogsConfigured), "n/a", isEventLogsConfigured, "Configured", "Not configured"))
| project recommendationId = "vm-21", name, id, tags, param1, param2, param3, param4, param5

可用性区域支持

Azure 可用性区域是每个 Azure 地区内的至少三个在物理上独立的数据中心组。 每个区域中的数据中心都配备了独立的电源、冷却系统和网络基础结构。 在本地区域发生故障的情况下,设计可用性区域,以便一个区域受到影响时,其余两个区域支持区域服务、容量和高可用性。

故障范围包括软件和硬件故障,以及地震、洪水和火灾等事件。 容错是通过 Azure 服务的冗余和逻辑隔离来实现的。 有关 Azure 中可用性区域的详细信息,请参阅地区和可用性区域

已启用 Azure 可用性区域的服务旨在提供适当级别的可靠性和灵活性。 可以通过两种方式进行相关配置。 可以采用区域冗余配置,实现跨区域自动复制,也可以采用区域性配置,将实例固定到特定区域。 还可以将这些方法结合。 有关区域与区域冗余体系结构的详细信息,请参阅有关使用可用性区域和区域的建议

虚拟机支持可用性区域,每个受支持的 Azure 区域有三个可用性区域,它们也是区域冗余和区域性的。 有关详细信息,请参阅可用性区域支持。 客户负责配置和迁移其虚拟机以实现可用性。

若要详细了解可用性区域就绪情况选项,请参阅:

先决条件

SLA 改进

由于可用性区域在物理上是独立的,并且提供不同的电源、网络和冷却,因此 SLA(服务级别协议)会增加。 有关详细信息,请参阅虚拟机的 SLA

创建启用可用性区域的资源

通过以下部署选项创建虚拟机 (VM),并启用可用性区域:

区域故障转移支持

可以使用 Site Recovery 服务将虚拟机设置为故障转移到另一个区域。 有关详细信息,请参阅 Site Recovery

容错

虚拟机可以故障转移到群集中的另一台服务器,而 VM 的操作系统将在新服务器上重启。 应参考灾难恢复的故障转移过程,在恢复规划中收集虚拟机,并运行灾难恢复演练,以确保其容错解决方案能够成功。

有关详细信息,请参阅站点恢复过程

区域故障体验

在发生区域范围的中断期间,性能会短时间下降,直到虚拟机服务的自我修复功能重新平衡基础容量,以根据正常区域做出调整。 自我修复不依赖于区域还原;预计 Azure 托管服务自助修复状态会使用来自其他区域的容量来补偿丢失的区域。

还应为整个区域发生中断的可能性做好准备。 如果整个区域出现服务中断,会暂时无法使用数据的本地冗余副本。 如果启用了异地复制,则会在其他区域额外存储 Azure 存储 blob 和表的三个副本。 当发生全面区域中断或发生主要区域无法恢复的灾难时,Azure 会将所有 DNS 条目重新映射到异地复制区域。

区域服务中断准备和恢复

在部署 Azure 虚拟机应用程序的整个区域的服务中断期间,为 Azure 虚拟机提供以下指导:

低延迟设计

设计低延迟虚拟机解决方案时,可以使用跨区域(次要区域)、跨订阅(预览版)和跨局部区域(预览版)。 有关这些选项的详细信息,请参阅支持的还原方法

重要

通过选择退出区域感知部署,你放弃对基础故障的隔离保护。 使用不支持可用性区域的 SKU 或选择退出可用性区域配置会强制依赖于不符合局部区域放置和隔离的资源(包括这些资源的基础依赖项)。 不应期望这些资源在局部区域停机情形中幸存下来。 利用此类资源的解决方案应定义一个灾难恢复策略,并在另一个区域中配置解决方案的恢复。

安全部署技术

选择可用性区域隔离时,应将安全部署技术用于应用程序代码和应用程序升级。 除了配置 Azure Site Recovery,并为 VM 实现以下任一安全部署技术:

由于 Azure 定期执行计划性维护更新,因此在极少数情况下,这些更新需要重启虚拟机才能将所需的更新应用于底层基础结构。 要了解更多,请参阅计划性维护期间的可用性注意事项

升级另一个区域中的下一组节点之前,应执行以下任务:

迁移到可用性区域支持

若要了解如何将 VM 迁移到可用性区域支持,请参阅将虚拟机和虚拟机规模集迁移到可用性区域支持

跨区域灾难恢复和业务连续性

灾难恢复 (DR) 是指从会导致故障时间和数据丢失的高影响事件(例如自然灾害或部署失败)中恢复。 不管灾难的原因是什么,最好的补救措施就是一个定义全面且经过测试的 DR 计划,以及一个主动支持 DR 的应用程序设计。 在开始考虑创建灾难恢复计划之前,请参阅设计灾难恢复策略的建议

在 DR 方面,Azure 使用共同责任模型。 在共担责任模型中,Azure 会确保基线基础结构和平台服务可用。 同时,许多 Azure 服务不会自动复制数据,也不会从失败区域回退以交叉复制到另一个启用的区域。 对于这些服务,你负责设置适用于工作负载的灾难恢复计划。 大多数在 Azure 平台即服务 (PaaS) 产品/服务上运行的服务都提供支持 DR 的功能和指导,你可以使用特定于服务的功能来支持快速恢复,从而帮助制定 DR 计划。

可以使用跨区域还原通过配对区域还原 Azure VM。 通过跨区域还原,如果备份在次要区域中完成,则可以还原所选恢复点的所有 Azure VM。 有关跨区域还原的详细信息,请参阅还原选项中的跨区域表行条目。

多区域地理位置中的灾难恢复

对于区域范围的服务中断,Microsoft 会努力还原虚拟机服务。 但是,仍然必须依靠应用程序特有的其他备份方法才能达到最高级别的可用性。 有关详细信息,请参阅灾难恢复的数据策略部分。

服务中断检测、通知和管理

虚拟机的硬件或物理基础结构可能会意外失败。 意外故障可能包括本地网络故障、本地磁盘故障或其他机架级故障。 检测到此类故障时,Azure 平台会自动将虚拟机迁移(恢复)到同一数据中心内的正常物理机。 在修复过程中,虚拟机会经历停机(重启),在某些情况下会丢失临时驱动器。 始终会保留附加的 OS 和数据磁盘。

有关虚拟机服务中断的更多详细信息,请参阅灾难恢复指南

设置灾难恢复和中断检测

为虚拟机设置灾难恢复时,请了解 Azure Site Recovery 提供的功能。 使用以下方法为虚拟机启用灾难恢复:

单区域地理位置中的灾难恢复

设置好灾难恢复后,Azure VM 就可以持续复制到不同的目标区域。 如果发生服务中断,可将 VM 故障转移到次要区域,然后在次要区域中对其进行访问。

使用 Site Recovery 复制 Azure VM 时,所有 VM 磁盘将以异步方式持续复制到目标区域。 恢复点每隔几分钟创建一次,这为你提供了恢复点目标 (RPO)(以分钟为单位)。 可以开展灾难恢复演练任意次,这不会影响生产应用程序或正在进行的复制。 有关详细信息,请参阅运行灾难恢复到 Azure 的演练

有关详细信息,请参阅 Azure VM 体系结构组件区域配对

容量和主动灾难恢复复原能力

Azure 及其客户按共担责任模型运营。 共担责任意味着,对于客户启用的 DR(客户负责的服务),必须为其部署和控制的任何服务解决 DR 问题。 为了确保恢复是主动的,应始终预先部署辅助资源,因为对于那些尚未预先分配的资源,无法在影响发生时保证容量。

对于部署虚拟机,可以在虚拟机规模集上使用灵活的业务流程模式。 所有 VM 大小都适配灵活的业务流程模式。 灵活业务流程模式还会将 VM 分散到某个地理区域或可用性区域的多个容错域中,从而提供高可用性保证(最多支持 1000 个 VM)。

后续步骤