Gestire applicazioni e servizi come risorse di Azure Resource Manager

È possibile distribuire applicazioni e servizi in un cluster di Service Fabric tramite Azure Resource Manager. Ciò significa che invece di distribuire e gestire le applicazioni tramite PowerShell o l'interfaccia della riga di comando dopo aver aspettato che il cluster sia pronto, è ora possibile esprimere applicazioni e servizi in JSON e distribuirli nello stesso modello di Resource Manager del cluster. L'intero processo di registrazione, provisioning e distribuzione delle applicazioni viene eseguito in un unico passaggio.

È consigliabile distribuire in questo modo tutte le applicazioni di configurazione, governance o gestione cluster necessarie nel cluster, come Patch Orchestration Application, i watchdog e tutte le applicazioni che devono essere eseguite nel cluster prima della distribuzione di altre applicazioni o servizi.

Se possibile, gestire le applicazioni come risorse di Resource Manager in modo da usufruire dei vantaggi seguenti.

  • Audit trail: Resource Manager controlla ogni operazione e mantiene un log attività dettagliato che consente di tenere traccia di tutte le modifiche apportate a queste applicazioni e al cluster.
  • Controllo degli accessi in base al ruolo di Azure: la gestione dell'accesso ai cluster e alle applicazioni distribuite nel cluster può essere eseguita tramite lo stesso modello di Resource Manager.
  • Azure Resource Manager, tramite il portale di Azure, diventa un punto di accesso centralizzato per la gestione del cluster e delle distribuzioni di applicazioni critiche.

Il frammento seguente illustra le diverse tipologie di risorse che è possibile gestire tramite un modello:

{
    "apiVersion": "2019-03-01",
    "type": "Microsoft.ServiceFabric/clusters/applicationTypes",
    "name": "[concat(parameters('clusterName'), '/', parameters('applicationTypeName'))]",
    "location": "[variables('clusterLocation')]",
},
{
    "apiVersion": "2019-03-01",
    "type": "Microsoft.ServiceFabric/clusters/applicationTypes/versions",
    "name": "[concat(parameters('clusterName'), '/', parameters('applicationTypeName'), '/', parameters('applicationTypeVersion'))]",
    "location": "[variables('clusterLocation')]",
},
{
    "apiVersion": "2019-03-01",
    "type": "Microsoft.ServiceFabric/clusters/applications",
    "name": "[concat(parameters('clusterName'), '/', parameters('applicationName'))]",
    "location": "[variables('clusterLocation')]",
},
{
    "apiVersion": "2019-03-01",
    "type": "Microsoft.ServiceFabric/clusters/applications/services",
    "name": "[concat(parameters('clusterName'), '/', parameters('applicationName'), '/', parameters('serviceName'))]",
    "location": "[variables('clusterLocation')]"
}

Aggiungere una nuova applicazione al modello di Resource Manager

  1. Preparare il modello di Resource Manager del cluster per la distribuzione. Per altre informazioni, vedere Creare un cluster di Service Fabric usando Azure Resource Manager.

  2. Esaminare alcune delle applicazioni che si intende distribuire nel cluster. Esistono applicazioni che saranno sempre in esecuzione e con cui altre applicazioni potrebbero stabilire dipendenze? È prevista la distribuzione di applicazioni di configurazione o governance del cluster? Questi tipi di applicazioni possono essere gestiti in modo ottimale tramite un modello di Resource Manager, come illustrato in precedenza.

  3. Dopo aver scoperto le applicazioni da distribuire in questo modo, le applicazioni devono essere inserite in un pacchetto, compresso e inserito in una condivisione di archiviazione. La condivisione deve essere accessibile tramite un endpoint REST per poter essere utilizzata da Azure Resource Manager durante la distribuzione. Per informazioni dettagliate, vedere Creare un account di archiviazione.

  4. Nel modello di Resource Manager, sotto la dichiarazione del cluster descrivere le proprietà di ogni applicazione. Tali proprietà includono il numero di repliche o istanze e tutte le catene di dipendenze tra le risorse (altre applicazioni o servizi). Si noti che questo non sostituisce i manifesti dell'applicazione o del servizio, ma ne descrive alcuni come parte del modello di Resource Manager del cluster. Ecco un modello di esempio che include la distribuzione di un servizio senza stato Service1 e un servizio con stato Service2 come parte di Application1:

    {
     "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
     "contentVersion": "1.0.0.0",
     "parameters": {
       "clusterName": {
         "type": "string",
         "defaultValue": "Cluster",
         "metadata": {
           "description": "Name of your cluster - Between 3 and 23 characters. Letters and numbers only."
         }
       },
       "applicationTypeName": {
         "type": "string",
         "defaultValue": "ApplicationType",
         "metadata": {
           "description": "The application type name."
         }
       },
       "applicationTypeVersion": {
         "type": "string",
         "defaultValue": "1",
         "metadata": {
           "description": "The application type version."
         }
       },
       "appPackageUrl": {
         "type": "string",
         "metadata": {
           "description": "The URL to the application package sfpkg file."
         }
       },
       "applicationName": {
         "type": "string",
         "defaultValue": "Application1",
         "metadata": {
           "description": "The name of the application resource."
         }
       },
       "serviceName": {
         "type": "string",
         "defaultValue": "Application1~Service1",
         "metadata": {
           "description": "The name of the service resource in the format of {applicationName}~{serviceName}."
         }
       },
       "serviceTypeName": {
         "type": "string",
         "defaultValue": "Service1Type",
         "metadata": {
           "description": "The name of the service type."
         }
       },
       "serviceName2": {
         "type": "string",
         "defaultValue": "Application1~Service2",
         "metadata": {
           "description": "The name of the service resource in the format of {applicationName}~{serviceName}."
         }
       },
       "serviceTypeName2": {
         "type": "string",
         "defaultValue": "Service2Type",
         "metadata": {
           "description": "The name of the service type."
         }
       }
     },
     "variables": {
       "clusterLocation": "[resourcegroup().location]"
     },
     "resources": [
       {
         "apiVersion": "2019-03-01",
         "type": "Microsoft.ServiceFabric/clusters/applicationTypes",
         "name": "[concat(parameters('clusterName'), '/', parameters('applicationTypeName'))]",
         "location": "[variables('clusterLocation')]",
         "dependsOn": [],
         "properties": {
           "provisioningState": "Default"
         }
       },
       {
         "apiVersion": "2019-03-01",
         "type": "Microsoft.ServiceFabric/clusters/applicationTypes/versions",
         "name": "[concat(parameters('clusterName'), '/', parameters('applicationTypeName'), '/', parameters('applicationTypeVersion'))]",
         "location": "[variables('clusterLocation')]",
         "dependsOn": [
           "[concat('Microsoft.ServiceFabric/clusters/', parameters('clusterName'), '/applicationTypes/', parameters('applicationTypeName'))]"
         ],
         "properties": {
           "provisioningState": "Default",
           "appPackageUrl": "[parameters('appPackageUrl')]"
         }
       },
       {
         "apiVersion": "2019-03-01",
         "type": "Microsoft.ServiceFabric/clusters/applications",
         "name": "[concat(parameters('clusterName'), '/', parameters('applicationName'))]",
         "location": "[variables('clusterLocation')]",
         "dependsOn": [
           "[concat('Microsoft.ServiceFabric/clusters/', parameters('clusterName'), '/applicationTypes/', parameters('applicationTypeName'), '/versions/', parameters('applicationTypeVersion'))]"
         ],
         "properties": {
           "provisioningState": "Default",
           "typeName": "[parameters('applicationTypeName')]",
           "typeVersion": "[parameters('applicationTypeVersion')]",
           "parameters": {},
           "upgradePolicy": {
             "upgradeReplicaSetCheckTimeout": "01:00:00.0",
             "forceRestart": "false",
             "rollingUpgradeMonitoringPolicy": {
               "healthCheckWaitDuration": "00:02:00.0",
               "healthCheckStableDuration": "00:05:00.0",
               "healthCheckRetryTimeout": "00:10:00.0",
               "upgradeTimeout": "01:00:00.0",
               "upgradeDomainTimeout": "00:20:00.0"
             },
             "applicationHealthPolicy": {
               "considerWarningAsError": "false",
               "maxPercentUnhealthyDeployedApplications": "50",
               "defaultServiceTypeHealthPolicy": {
                 "maxPercentUnhealthyServices": "50",
                 "maxPercentUnhealthyPartitionsPerService": "50",
                 "maxPercentUnhealthyReplicasPerPartition": "50"
               }
             }
           }
         }
       },
       {
         "apiVersion": "2019-03-01",
         "type": "Microsoft.ServiceFabric/clusters/applications/services",
         "name": "[concat(parameters('clusterName'), '/', parameters('applicationName'), '/', parameters('serviceName'))]",
         "location": "[variables('clusterLocation')]",
         "dependsOn": [
           "[concat('Microsoft.ServiceFabric/clusters/', parameters('clusterName'), '/applications/', parameters('applicationName'))]"
         ],
         "properties": {
           "provisioningState": "Default",
           "serviceKind": "Stateless",
           "serviceTypeName": "[parameters('serviceTypeName')]",
           "instanceCount": "-1",
           "partitionDescription": {
             "partitionScheme": "Singleton"
           },
           "correlationScheme": [],
           "serviceLoadMetrics": [],
           "servicePlacementPolicies": []
         }
       },
       {
         "apiVersion": "2019-03-01",
         "type": "Microsoft.ServiceFabric/clusters/applications/services",
         "name": "[concat(parameters('clusterName'), '/', parameters('applicationName'), '/', parameters('serviceName2'))]",
         "location": "[variables('clusterLocation')]",
         "dependsOn": [
           "[concat('Microsoft.ServiceFabric/clusters/', parameters('clusterName'), '/applications/', parameters('applicationName'))]"
         ],
         "properties": {
           "provisioningState": "Default",
           "serviceKind": "Stateful",
           "serviceTypeName": "[parameters('serviceTypeName2')]",
           "targetReplicaSetSize": "3",
           "minReplicaSetSize": "2",
           "replicaRestartWaitDuration": "00:01:00.0",
           "quorumLossWaitDuration": "00:02:00.0",
           "standByReplicaKeepDuration": "00:00:30.0",
           "partitionDescription": {
             "partitionScheme": "UniformInt64Range",
             "count": "5",
             "lowKey": "1",
             "highKey": "5"
           },
           "hasPersistedState": "true",
           "correlationScheme": [],
           "serviceLoadMetrics": [],
           "servicePlacementPolicies": [],
           "defaultMoveCost": "Low"
         }
       }
     ]
    }
    

    Nota

    Fare riferimento al riferimento di Azure Resource Manager di Service Fabric per trovare l'utilizzo e i dettagli sulle singole proprietà del modello.

  5. Eseguire la distribuzione.

Rimuovere la risorsa applicazione del provider di risorse di Service Fabric

Di seguito viene attivato il provisioning del pacchetto dell'app dal cluster e lo spazio su disco usato verrà pulito:

$resourceGroup = 'sftestcluster'
$cluster = $resourceGroup
$applicationType = 'VotingType'
$application = 'Voting'
$applicationVersion = '1.0.0'

$sf = Get-AzResource -ResourceGroupName $resourceGroup -ResourceName $cluster
$app = Get-AzResource -ResourceId "$($sf.Id)/applications/$application"
$appType = Get-AzResource -ResourceId "$($sf.Id)/applicationTypes/$applicationType"
$appTypeVersion = Get-AzResource -ResourceId "$($appType.Id)/versions/$applicationVersion"

# remove application
Remove-AzResource -ResourceId $app.Id

# remove application type version
Remove-AzResource -ResourceId $appTypeVersion.Id

# remove application type 
# Remove-AzResource -ResourceId $appType.Id

La semplice rimozione di Microsoft.ServiceFabric/clusters/application dal modello di Resource Manager non comporta l'annullamento del provisioning dell'applicazione. Comando di PowerShell Remove-AzResource come illustrato in precedenza o esecuzione di versioni del tipo di applicazione REST DELETE : l'eliminazione diretta è due opzioni che è possibile usare.

Nota

Una volta completata la rimozione, non dovrebbe più essere visualizzata la versione del pacchetto in SFX o ARM. Non è possibile eliminare la risorsa della versione del tipo di applicazione con cui è in esecuzione l'applicazione; ARM/SFRP impedirà questo problema. Se si tenta di annullare il provisioning del pacchetto in esecuzione, il runtime SF lo impedirà.

Gestire un'applicazione esistente tramite Resource Manager

Se il cluster è già attivo e si vogliono gestire come risorse di Resource Manager alcune applicazioni già distribuite nel cluster, invece di rimuovere le applicazioni e ridistribuirle è possibile eseguire una chiamata PUT usando le stesse API affinché le applicazioni vengano riconosciute come risorse di Resource Manager. Per altre informazioni, vedere Che cos'è il modello di risorse dell'applicazione di Service Fabric?

Nota

Per consentire un aggiornamento del cluster e ignorare le app non integre, il cliente può specificare "maxPercentUnhealthyApplications: 100" nella sezione "upgradeDescription/healthPolicy". Descrizioni dettagliate per tutte le impostazioni sono disponibili nella documentazione dei criteri di aggiornamento del cluster API REST di Service Fabric.

Passaggi successivi