Guida introduttiva: Creare un set di scalabilità di macchine virtuali Windows con un modello di Resource Manager

Si applica a: ✔️ macchine virtuali Windows ✔️ set di scalabilità uniformi

Nota

L'articolo seguente è relativo ai set di scalabilità di macchine virtuali uniformi. È consigliabile usare set di scalabilità di macchine virtuali flessibili per i nuovi carichi di lavoro. Altre informazioni su questa nuova modalità di orchestrazione sono disponibili nella Panoramica dei set di scalabilità di macchine virtuali flessibili.

Un set di scalabilità di macchine virtuali consente di distribuire e gestire un set di macchine virtuali con scalabilità automatica. È possibile ridimensionare manualmente il numero di VM nel set di scalabilità o definire regole di scalabilità automatica in base all'uso delle risorse, ad esempio la CPU, alla richiesta di memoria o al traffico di rete. Un servizio Azure Load Balancer distribuisce quindi il traffico alle istanze di macchina virtuale nel set di scalabilità. In questa guida di avvio rapido si crea un set di scalabilità di macchine virtuali e si distribuisce un'applicazione di esempio con un modello di Azure Resource Manager.

Un modello di Azure Resource Manager è un file JSON (JavaScript Object Notation) che definisce l'infrastruttura e la configurazione del progetto. Il modello utilizza la sintassi dichiarativa. Si descrive la distribuzione prevista senza scrivere la sequenza di comandi di programmazione necessari per creare la distribuzione.

I modelli di Azure Resource Manager consentono di distribuire gruppi di risorse correlate. In un singolo modello è possibile creare il set di scalabilità di macchine virtuali, installare le applicazioni e configurare le regole di scalabilità automatica. Con l'uso di variabili e parametri, questo modello può essere riutilizzato per creare altri set di scalabilità o aggiornare i set esistenti. È possibile distribuire i modelli tramite il portale di Azure, l'interfaccia della riga di comando di Azure, Azure PowerShell oppure le pipeline di integrazione continua/distribuzione continua (CI/CD).

Se l'ambiente soddisfa i prerequisiti e si ha familiarità con l'uso dei modelli di Resource Manager, selezionare il pulsante Distribuisci in Azure. Il modello verrà aperto nel portale di Azure.

Pulsante per distribuire il modello di Resource Manager in Azure.

Prerequisiti

Se non si ha una sottoscrizione di Azure, creare un account gratuito prima di iniziare.

Rivedere il modello

Il modello usato in questo avvio rapido proviene dai modelli di avvio rapido di Azure.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.29.47.4906",
      "templateHash": "11422221168065527308"
    }
  },
  "parameters": {
    "vmssName": {
      "type": "string",
      "minLength": 3,
      "maxLength": 61,
      "metadata": {
        "description": "String used as a base for naming resources. Must be 3-61 characters in length and globally unique across Azure. A hash is prepended to this string for some resources, and resource-specific information is appended."
      }
    },
    "vmSku": {
      "type": "string",
      "defaultValue": "Standard_D2s_v3",
      "metadata": {
        "description": "Size of VMs in the VM Scale Set."
      }
    },
    "windowsOSVersion": {
      "type": "string",
      "defaultValue": "2022-datacenter-azure-edition",
      "allowedValues": [
        "2019-DataCenter-GenSecond",
        "2016-DataCenter-GenSecond",
        "2022-datacenter-azure-edition"
      ],
      "metadata": {
        "description": "The Windows version for the VM. This will pick a fully patched image of this given Windows version. Allowed values: 2008-R2-SP1, 2012-Datacenter, 2012-R2-Datacenter & 2016-Datacenter, 2019-Datacenter."
      }
    },
    "securityType": {
      "type": "string",
      "defaultValue": "TrustedLaunch",
      "allowedValues": [
        "Standard",
        "TrustedLaunch"
      ],
      "metadata": {
        "description": "Security Type of the Virtual Machine."
      }
    },
    "instanceCount": {
      "type": "int",
      "defaultValue": 3,
      "minValue": 1,
      "maxValue": 100,
      "metadata": {
        "description": "Number of VM instances (100 or less)."
      }
    },
    "singlePlacementGroup": {
      "type": "bool",
      "defaultValue": true,
      "metadata": {
        "description": "When true this limits the scale set to a single placement group, of max size 100 virtual machines. NOTE: If singlePlacementGroup is true, it may be modified to false. However, if singlePlacementGroup is false, it may not be modified to true."
      }
    },
    "adminUsername": {
      "type": "string",
      "defaultValue": "vmssadmin",
      "metadata": {
        "description": "Admin username on all VMs."
      }
    },
    "adminPassword": {
      "type": "securestring",
      "metadata": {
        "description": "Admin password on all VMs."
      }
    },
    "_artifactsLocation": {
      "type": "string",
      "defaultValue": "[deployment().properties.templateLink.uri]",
      "metadata": {
        "description": "The base URI where artifacts required by this template are located. For example, if stored on a public GitHub repo, you'd use the following URI: https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/201-vmss-windows-webapp-dsc-autoscale/."
      }
    },
    "_artifactsLocationSasToken": {
      "type": "securestring",
      "defaultValue": "",
      "metadata": {
        "description": "The sasToken required to access _artifactsLocation.  If your artifacts are stored on a public repo or public storage account you can leave this blank."
      }
    },
    "powershelldscZip": {
      "type": "string",
      "defaultValue": "DSC/InstallIIS.zip",
      "metadata": {
        "description": "Location of the PowerShell DSC zip file relative to the URI specified in the _artifactsLocation, i.e. DSC/IISInstall.ps1.zip"
      }
    },
    "webDeployPackage": {
      "type": "string",
      "defaultValue": "WebDeploy/DefaultASPWebApp.v1.0.zip",
      "metadata": {
        "description": "Location of the  of the WebDeploy package zip file relative to the URI specified in _artifactsLocation, i.e. WebDeploy/DefaultASPWebApp.v1.0.zip"
      }
    },
    "powershelldscUpdateTagVersion": {
      "type": "string",
      "defaultValue": "1.0",
      "metadata": {
        "description": "Version number of the DSC deployment. Changing this value on subsequent deployments will trigger the extension to run."
      }
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Location for all resources."
      }
    },
    "platformFaultDomainCount": {
      "type": "int",
      "defaultValue": 1,
      "metadata": {
        "description": "Fault Domain count for each placement group."
      }
    }
  },
  "variables": {
    "vmScaleSetName": "[toLower(substring(format('vmssName{0}', uniqueString(resourceGroup().id)), 0, 9))]",
    "longvmScaleSet": "[toLower(parameters('vmssName'))]",
    "addressPrefix": "10.0.0.0/16",
    "subnetPrefix": "10.0.0.0/24",
    "vNetName": "[format('{0}vnet', variables('vmScaleSetName'))]",
    "publicIPAddressName": "[format('{0}pip', variables('vmScaleSetName'))]",
    "subnetName": "[format('{0}subnet', variables('vmScaleSetName'))]",
    "loadBalancerName": "[format('{0}lb', variables('vmScaleSetName'))]",
    "publicIPAddressID": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]",
    "lbProbeID": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('loadBalancerName'), 'tcpProbe')]",
    "natPoolName": "[format('{0}natpool', variables('vmScaleSetName'))]",
    "bePoolName": "[format('{0}bepool', variables('vmScaleSetName'))]",
    "lbPoolID": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('loadBalancerName'), variables('bePoolName'))]",
    "natStartPort": 50000,
    "natEndPort": 50119,
    "natBackendPort": 3389,
    "nicName": "[format('{0}nic', variables('vmScaleSetName'))]",
    "ipConfigName": "[format('{0}ipconfig', variables('vmScaleSetName'))]",
    "frontEndIPConfigID": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('loadBalancerName'), 'loadBalancerFrontEnd')]",
    "osType": {
      "publisher": "MicrosoftWindowsServer",
      "offer": "WindowsServer",
      "sku": "[parameters('windowsOSVersion')]",
      "version": "latest"
    },
    "securityProfileJson": {
      "uefiSettings": {
        "secureBootEnabled": true,
        "vTpmEnabled": true
      },
      "securityType": "[parameters('securityType')]"
    },
    "imageReference": "[variables('osType')]",
    "webDeployPackageFullPath": "[uri(parameters('_artifactsLocation'), format('{0}{1}', parameters('webDeployPackage'), parameters('_artifactsLocationSasToken')))]",
    "powershelldscZipFullPath": "[uri(parameters('_artifactsLocation'), format('{0}{1}', parameters('powershelldscZip'), parameters('_artifactsLocationSasToken')))]"
  },
  "resources": [
    {
      "type": "Microsoft.Network/loadBalancers",
      "apiVersion": "2023-04-01",
      "name": "[variables('loadBalancerName')]",
      "location": "[parameters('location')]",
      "properties": {
        "frontendIPConfigurations": [
          {
            "name": "LoadBalancerFrontEnd",
            "properties": {
              "publicIPAddress": {
                "id": "[variables('publicIPAddressID')]"
              }
            }
          }
        ],
        "backendAddressPools": [
          {
            "name": "[variables('bePoolName')]"
          }
        ],
        "inboundNatPools": [
          {
            "name": "[variables('natPoolName')]",
            "properties": {
              "frontendIPConfiguration": {
                "id": "[variables('frontEndIPConfigID')]"
              },
              "protocol": "Tcp",
              "frontendPortRangeStart": "[variables('natStartPort')]",
              "frontendPortRangeEnd": "[variables('natEndPort')]",
              "backendPort": "[variables('natBackendPort')]"
            }
          }
        ],
        "loadBalancingRules": [
          {
            "name": "LBRule",
            "properties": {
              "frontendIPConfiguration": {
                "id": "[variables('frontEndIPConfigID')]"
              },
              "backendAddressPool": {
                "id": "[variables('lbPoolID')]"
              },
              "protocol": "Tcp",
              "frontendPort": 80,
              "backendPort": 80,
              "enableFloatingIP": false,
              "idleTimeoutInMinutes": 5,
              "probe": {
                "id": "[variables('lbProbeID')]"
              }
            }
          }
        ],
        "probes": [
          {
            "name": "tcpProbe",
            "properties": {
              "protocol": "Tcp",
              "port": 80,
              "intervalInSeconds": 5,
              "numberOfProbes": 2
            }
          }
        ]
      },
      "dependsOn": [
        "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]"
      ]
    },
    {
      "type": "Microsoft.Compute/virtualMachineScaleSets",
      "apiVersion": "2023-09-01",
      "name": "[variables('vmScaleSetName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "[parameters('vmSku')]",
        "tier": "Standard",
        "capacity": "[parameters('instanceCount')]"
      },
      "properties": {
        "overprovision": true,
        "upgradePolicy": {
          "mode": "Automatic"
        },
        "singlePlacementGroup": "[parameters('singlePlacementGroup')]",
        "platformFaultDomainCount": "[parameters('platformFaultDomainCount')]",
        "virtualMachineProfile": {
          "storageProfile": {
            "osDisk": {
              "caching": "ReadWrite",
              "createOption": "FromImage"
            },
            "imageReference": "[variables('imageReference')]"
          },
          "osProfile": {
            "computerNamePrefix": "[variables('vmScaleSetName')]",
            "adminUsername": "[parameters('adminUsername')]",
            "adminPassword": "[parameters('adminPassword')]"
          },
          "securityProfile": "[if(equals(parameters('securityType'), 'TrustedLaunch'), variables('securityProfileJson'), null())]",
          "networkProfile": {
            "networkInterfaceConfigurations": [
              {
                "name": "[variables('nicName')]",
                "properties": {
                  "primary": true,
                  "ipConfigurations": [
                    {
                      "name": "[variables('ipConfigName')]",
                      "properties": {
                        "subnet": {
                          "id": "[reference(resourceId('Microsoft.Network/virtualNetworks', variables('vNetName')), '2023-04-01').subnets[0].id]"
                        },
                        "loadBalancerBackendAddressPools": [
                          {
                            "id": "[variables('lbPoolID')]"
                          }
                        ]
                      }
                    }
                  ]
                }
              }
            ]
          },
          "extensionProfile": {
            "extensions": [
              {
                "name": "Microsoft.Powershell.DSC",
                "properties": {
                  "publisher": "Microsoft.Powershell",
                  "type": "DSC",
                  "typeHandlerVersion": "2.9",
                  "autoUpgradeMinorVersion": true,
                  "forceUpdateTag": "[parameters('powershelldscUpdateTagVersion')]",
                  "settings": {
                    "configuration": {
                      "url": "[variables('powershelldscZipFullPath')]",
                      "script": "InstallIIS.ps1",
                      "function": "InstallIIS"
                    },
                    "configurationArguments": {
                      "nodeName": "localhost",
                      "WebDeployPackagePath": "[variables('webDeployPackageFullPath')]"
                    }
                  }
                }
              }
            ]
          }
        }
      },
      "dependsOn": [
        "[resourceId('Microsoft.Network/virtualNetworks', variables('vNetName'))]"
      ]
    },
    {
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2023-04-01",
      "name": "[variables('publicIPAddressName')]",
      "location": "[parameters('location')]",
      "properties": {
        "publicIPAllocationMethod": "Static",
        "dnsSettings": {
          "domainNameLabel": "[variables('longvmScaleSet')]"
        }
      }
    },
    {
      "type": "Microsoft.Network/virtualNetworks",
      "apiVersion": "2023-04-01",
      "name": "[variables('vNetName')]",
      "location": "[parameters('location')]",
      "properties": {
        "addressSpace": {
          "addressPrefixes": [
            "[variables('addressPrefix')]"
          ]
        },
        "subnets": [
          {
            "name": "[variables('subnetName')]",
            "properties": {
              "addressPrefix": "[variables('subnetPrefix')]"
            }
          }
        ]
      }
    },
    {
      "type": "Microsoft.Insights/autoscalesettings",
      "apiVersion": "2022-10-01",
      "name": "autoscalehost",
      "location": "[parameters('location')]",
      "properties": {
        "name": "autoscalehost",
        "targetResourceUri": "[resourceId('Microsoft.Compute/virtualMachineScaleSets', variables('vmScaleSetName'))]",
        "enabled": true,
        "profiles": [
          {
            "name": "Profile1",
            "capacity": {
              "minimum": "1",
              "maximum": "10",
              "default": "1"
            },
            "rules": [
              {
                "metricTrigger": {
                  "metricName": "Percentage CPU",
                  "metricResourceUri": "[resourceId('Microsoft.Compute/virtualMachineScaleSets', variables('vmScaleSetName'))]",
                  "timeGrain": "PT1M",
                  "statistic": "Average",
                  "timeWindow": "PT5M",
                  "timeAggregation": "Average",
                  "operator": "GreaterThan",
                  "threshold": 50
                },
                "scaleAction": {
                  "direction": "Increase",
                  "type": "ChangeCount",
                  "value": "1",
                  "cooldown": "PT5M"
                }
              },
              {
                "metricTrigger": {
                  "metricName": "Percentage CPU",
                  "metricResourceUri": "[resourceId('Microsoft.Compute/virtualMachineScaleSets', variables('vmScaleSetName'))]",
                  "timeGrain": "PT1M",
                  "statistic": "Average",
                  "timeWindow": "PT5M",
                  "timeAggregation": "Average",
                  "operator": "LessThan",
                  "threshold": 30
                },
                "scaleAction": {
                  "direction": "Decrease",
                  "type": "ChangeCount",
                  "value": "1",
                  "cooldown": "PT5M"
                }
              }
            ]
          }
        ]
      },
      "dependsOn": [
        "[resourceId('Microsoft.Compute/virtualMachineScaleSets', variables('vmScaleSetName'))]"
      ]
    }
  ],
  "outputs": {
    "applicationUrl": {
      "type": "string",
      "value": "[uri(format('http://{0}', reference(resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName')), '2023-04-01').dnsSettings.fqdn), '/MyApp')]"
    }
  }
}

Queste risorse sono definite nei modelli seguenti:

Definire un set di scalabilità

Per creare un set di scalabilità con un modello, definire le risorse appropriate. Le parti principali del tipo di risorsa del set di scalabilità di macchine virtuali sono le seguenti:

Proprietà Descrizione della proprietà Valore di esempio del modello
type Tipo di risorsa di Azure da creare Microsoft.Compute/virtualMachineScaleSets
name Nome del set di scalabilità myScaleSet
posizione Posizione in cui creare il set di scalabilità Stati Uniti orientali
sku.name Dimensioni delle VM per ogni istanza del set di scalabilità Standard_A1
sku.capacity Numero di istanze di macchina virtuale da creare inizialmente 2
upgradePolicy.mode Modalità di aggiornamento dell'istanza di macchina virtuale in caso di modifiche Automatico
imageReference Piattaforma o immagine personalizzata da usare per le istanze delle macchine virtuali Microsoft Windows Server 2016 Datacenter
osProfile.computerNamePrefix Prefisso del nome per ogni istanza di macchina virtuale myvmss
osProfile.adminUsername Nome utente di ogni istanza di macchina virtuale azureuser
osProfile.adminPassword Password di ogni istanza di macchina virtuale P@ssw0rd!

Per personalizzare un modello di set di scalabilità, è possibile modificare le dimensioni o la capacità iniziale delle macchine virtuali. In alternativa, è possibile usare una piattaforma diversa o un'immagine personalizzata.

Aggiungere un'applicazione di esempio

Per testare il set di scalabilità, installare un'applicazione Web di base. Quando si distribuisce un set di scalabilità, le estensioni di VM possono fornire attività di configurazione e automazione post-distribuzione, ad esempio l'installazione di un'app. Gli script possono essere scaricati dall'archiviazione di Azure o da GitHub oppure possono essere forniti al portale di Azure durante il runtime dell'estensione. Per applicare un'estensione al set di scalabilità, si aggiunge la sezione extensionProfile all'esempio di risorsa precedente. Il profilo di estensione definisce in genere le proprietà seguenti:

  • Tipo di estensione
  • Server di pubblicazione dell'estensione
  • Versione dell'estensione
  • Percorso degli script di configurazione o installazione
  • Comandi da eseguire nelle istanze di macchina virtuale

Il modello usa l'estensione DSC di PowerShell per installare un'app ASP.NET MVC che viene eseguita in IIS.

Viene scaricato uno script di installazione da GitHub, come definito in url. L'estensione esegue quindi InstallIIS dallo script IISInstall.ps1, come definito in function e Script. L'app ASP.NET viene fornita come pacchetto di distribuzione Web scaricato da GitHub, come definito in WebDeployPackagePath:

Distribuire il modello

Per distribuire il modello, selezionare il pulsante Distribuisci in Azure. Questo pulsante apre il portale di Azure, carica il modello completo e richiede alcuni parametri quali il nome del set di scalabilità, il numero di istanze e le credenziali di amministratore.

Pulsante per distribuire il modello di Resource Manager in Azure.

È possibile distribuire un modello di Resource Manager anche con Azure PowerShell:

# Create a resource group
New-AzResourceGroup -Name myResourceGroup -Location EastUS

# Deploy template into resource group
New-AzResourceGroupDeployment `
    -ResourceGroupName myResourceGroup `
    -TemplateURI https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/demos/vmss-windows-webapp-dsc-autoscale/azuredeploy.json

# Update the scale set and apply the extension
Update-AzVmss `
    -ResourceGroupName myResourceGroup `
    -VmScaleSetName myVMSS `
    -VirtualMachineScaleSet $vmssConfig

Rispondere ai prompt per l'inserimento del nome del set di scalabilità e delle credenziali di amministratore per le istanze di macchina virtuale. Possono essere necessari 10-15 minuti per la creazione del set di scalabilità e l'applicazione dell'estensione per la configurazione dell'app.

Convalidare la distribuzione

Per vedere il set di scalabilità in azione, accedere all'applicazione Web di esempio in un Web browser. Ottenere l'indirizzo IP pubblico del servizio di bilanciamento del carico con Get-AzPublicIpAddress come segue:

Get-AzPublicIpAddress -ResourceGroupName myResourceGroup | Select IpAddress

Immettere l'indirizzo IP pubblico del servizio di bilanciamento del carico in un Web browser nel formato http://publicIpAddress/MyApp. Il servizio di bilanciamento del carico distribuisce il traffico a una delle istanze di macchina virtuale, come illustrato nell'esempio seguente:

Esecuzione del sito IIS

Pulire le risorse

Quando non sono più necessari, è possibile rimuovere il gruppo di risorse e il set di scalabilità con Remove-AzResourceGroup. Il parametro -Force conferma che si desidera eliminare le risorse senza un prompt aggiuntivo a tale scopo. Il parametro -AsJob restituisce il controllo al prompt senza attendere il completamento dell'operazione.

Remove-AzResourceGroup -Name "myResourceGroup" -Force -AsJob

Passaggi successivi

In questa guida di avvio rapido è stato creato un set di scalabilità Windows con un modello di Azure Resource Manager ed è stata usata l'estensione DSC di PowerShell per installare un'app ASP.NET di base nelle istanze di VM. Per altre informazioni, passare all'esercitazione su come creare e gestire i set di scalabilità di macchine virtuali di Azure.