Aumentare o ridurre le istanze di un cluster di Service Fabric a livello di codiceScale a Service Fabric cluster programmatically

Le nozioni di base sulla scalabilità di un cluster Service Fabric in Azure sono trattate nella documentazione sulla scalabilità del cluster.Fundamentals of scaling a Service Fabric cluster in Azure are covered in documentation on cluster scaling. Questo articolo descrive come i cluster Service Fabric sono costruiti su set di scalabilità di macchine virtuali ed è possibile ottenere la scalabilità manualmente o usando regole di scalabilità automatica.That article covers how Service Fabric clusters are built on top of virtual machine scale sets and can be scaled either manually or with auto-scale rules. Vengono esaminati i metodi a livello di codice per il coordinamento delle operazioni di scalabilità in Azure per scenari più avanzati.This document looks at programmatic methods of coordinating Azure scaling operations for more advanced scenarios.

Motivi per eseguire la scalabilità a livello di codiceReasons for programmatic scaling

In molti scenari, la scalabilità manuale o mediante regole di scalabilità automatica sono soluzioni valide.In many scenarios, scaling manually or via auto-scale rules are good solutions. In altri scenari, tuttavia, potrebbero non essere la scelta adatta.In other scenarios, though, they may not be the right fit. Alcuni potenziali svantaggi di questi approcci sono:Potential drawbacks to these approaches include:

  • La scalabilità manuale richiede l'accesso e la richiesta esplicita delle operazioni di scalabilità.Manually scaling requires you to log in and explicitly request scaling operations. Questo approccio potrebbe non essere una soluzione valida se le operazioni di scalabilità vengono richieste di frequente oppure in momenti imprevisti.If scaling operations are required frequently or at unpredictable times, this approach may not be a good solution.
  • Quando le regole di scalabilità automatica rimuovono un'istanza da un set di scalabilità di macchine virtuali, non rimuovono automaticamente le informazioni di questo nodo dal cluster Service Fabric associato, a meno che il tipo di nodo non disponga di un livello di durabilità Silver o Gold.When auto-scale rules remove an instance from a virtual machine scale set, they do not automatically remove knowledge of that node from the associated Service Fabric cluster unless the node type has a durability level of Silver or Gold. Poiché funzionano a livello di set di scalabilità anziché a livello di Service Fabric, le regole di scalabilità automatica possono rimuovere i nodi Service Fabric senza arrestarli in modo normale.Because auto-scale rules work at the scale set level (rather than at the Service Fabric level), auto-scale rules can remove Service Fabric nodes without shutting them down gracefully. Questo tipo di rimozione dei nodi lascerà il nodo Service Fabric nello stato "ghost" dopo le operazioni di riduzione delle istanze.This rude node removal will leave 'ghost' Service Fabric node state behind after scale-in operations. Un utente o un servizio dovrà pulire periodicamente lo stato del nodo rimosso nel cluster Service Fabric.An individual (or a service) would need to periodically clean up removed node state in the Service Fabric cluster.
    • Un tipo di nodo con un livello di durabilità Gold o Silver esegue automaticamente la pulizia dei nodi rimossi. Non è necessaria una pulizia aggiuntiva.A node type with a durability level of Gold or Silver automatically cleans up removed nodes, so no additional clean-up is needed.
  • Anche se le regole di scalabilità automatica supportano molte metriche, si tratta comunque di un set limitato.Although there are many metrics supported by auto-scale rules, it is still a limited set. Se lo scenario richiede la scalabilità basata su alcune metriche non incluse in questo set, le regole di scalabilità automatica potrebbero non essere una soluzione valida.If your scenario calls for scaling based on some metric not covered in that set, then auto-scale rules may not be a good option.

Considerando queste limitazioni, è consigliabile implementare più modelli di scalabilità automatica personalizzati.Based on these limitations, you may wish to implement more customized automatic scaling models.

Scalabilità delle APIScaling APIs

Esistono API Azure che consentono alle applicazioni di usare a livello di codice i set di scalabilità di macchine virtuali e i cluster Service Fabric.Azure APIs exist which allow applications to programmatically work with virtual machine scale sets and Service Fabric clusters. Se le opzioni di scalabilità automatica esistenti non funzionano per lo scenario specifico, queste API consentono di implementare una logica di scalabilità personalizzata.If existing auto-scale options don't work for your scenario, these APIs make it possible to implement custom scaling logic.

Un approccio all'implementazione di questa funzionalità di scalabilità automatica "interna" consiste nell'aggiungere un nuovo servizio senza stato all'applicazione Service Fabric per gestire le operazioni di scalabilità.One approach to implementing this 'home-made' auto-scaling functionality is to add a new stateless service to the Service Fabric application to manage scaling operations. All'interno del metodo RunAsync del servizio, un set di trigger può determinare se la scalabilità è necessaria, inclusi i parametri di controllo, come la dimensione massima di un cluster e i tempi di raffreddamento della scalabilità.Within the service's RunAsync method, a set of triggers can determine if scaling is required (including checking parameters such as maximum cluster size and scaling cooldowns).

L'API usata per le interazioni dei set di scalabilità di macchine virtuali, sia per verificare il numero corrente di istanze di macchine virtuali che per modificarlo, è la libreria Azure Management Compute Fluent.The API used for virtual machine scale set interactions (both to check the current number of virtual machine instances and to modify it) is the fluent Azure Management Compute library. La libreria Fluent fornisce un'API facile da usare per l'interazione con i set di scalabilità di macchine virtuali.The fluent compute library provides an easy-to-use API for interacting with virtual machine scale sets.

Per interagire con il cluster Service Fabric, usare System.Fabric.FabricClient.To interact with the Service Fabric cluster itself, use System.Fabric.FabricClient.

Naturalmente non è necessario che il codice di scalabilità sia in esecuzione come servizio nel cluster di cui modificare la scalabilità.Of course, the scaling code doesn't need to run as a service in the cluster to be scaled. Sia IAzure sia FabricClient possono connettersi in remoto alle risorse di Azure associate; il servizio di scalabilità può quindi essere facilmente un'applicazione console o il servizio Windows in esecuzione dall'esterno dell'applicazione Service Fabric.Both IAzure and FabricClient can connect to their associated Azure resources remotely, so the scaling service could easily be a console application or Windows service running from outside the Service Fabric application.

Gestione delle credenzialiCredential management

Un problema in fase di scrittura di un servizio per gestire la scalabilità è che il servizio deve essere in grado di accedere alle risorse dei set di scalabilità di macchine virtuali senza un accesso interattivo.One challenge of writing a service to handle scaling is that the service must be able to access virtual machine scale set resources without an interactive login. L'accesso al cluster Service Fabric è semplice se il servizio di scalabilità sta modificando la propria applicazione Service Fabric, ma sono necessarie le credenziali per accedere al set di scalabilità.Accessing the Service Fabric cluster is easy if the scaling service is modifying its own Service Fabric application, but credentials are needed to access the scale set. Per accedere, è possibile usare un'entità servizio creata con l'interfaccia della riga di comando di Azure 2.0.To log in, you can use a service principal created with the Azure CLI 2.0.

È possibile creare un'entità servizio con i passaggi seguenti:A service principal can be created with the following steps:

  1. Accedere all'interfaccia della riga di comando di Azure (az login) come utente con accesso al set di scalabilità di macchine virtualiLog in to the Azure CLI (az login) as a user with access to the virtual machine scale set
  2. Creare l'entità servizio con az ad sp create-for-rbacCreate the service principal with az ad sp create-for-rbac
    1. Prendere nota di appId (denominato altrove "ID client"), nome, password e tenant per un uso successivo.Make note of the appId (called 'client ID' elsewhere), name, password, and tenant for later use.
    2. Sarà inoltre necessario l'ID sottoscrizione, che può essere visualizzato con az account listYou will also need your subscription ID, which can be viewed with az account list

La libreria di calcolo Fluent può eseguire l'accesso usando queste credenziali come indicato di seguito. Si noti che i tipi di Azure fluent principali, ad esempio IAzure, sono nel pacchetto Microsoft.Azure.Management.Fluent:The fluent compute library can log in using these credentials as follows (note that core fluent Azure types like IAzure are in the Microsoft.Azure.Management.Fluent package):

var credentials = new AzureCredentials(new ServicePrincipalLoginInformation {
                ClientId = AzureClientId,
                ClientSecret = 
                AzureClientKey }, AzureTenantId, AzureEnvironment.AzureGlobalCloud);
IAzure AzureClient = Azure.Authenticate(credentials).WithSubscription(AzureSubscriptionId);

if (AzureClient?.SubscriptionId == AzureSubscriptionId)
{
    ServiceEventSource.Current.ServiceMessage(Context, "Successfully logged into Azure");
}
else
{
    ServiceEventSource.Current.ServiceMessage(Context, "ERROR: Failed to login to Azure");
}

Una volta eseguito l'accesso, è possibile eseguire una query del numero di istanze di set di scalabilità tramite AzureClient.VirtualMachineScaleSets.GetById(ScaleSetId).Capacity.Once logged in, scale set instance count can be queried via AzureClient.VirtualMachineScaleSets.GetById(ScaleSetId).Capacity.

Aumento del numero di istanzeScaling out

Usando l'SDK di calcolo di Azure Fluent è possibile aggiungere istanze al set di scalabilità di macchine virtuali con poche chiamate.Using the fluent Azure compute SDK, instances can be added to the virtual machine scale set with just a few calls -

var scaleSet = AzureClient.VirtualMachineScaleSets.GetById(ScaleSetId);
var newCapacity = (int)Math.Min(MaximumNodeCount, scaleSet.Capacity + 1);
scaleSet.Update().WithCapacity(newCapacity).Apply(); 

In alternativa, le dimensioni del set di scalabilità di macchine virtuali possono essere gestite anche con i cmdlet di PowerShell.Alternatively, virtual machine scale set size can also be managed with PowerShell cmdlets. Get-AzureRmVmss consente di recuperare l'oggetto set di scalabilità di macchine virtuali.Get-AzureRmVmss can retrieve the virtual machine scale set object. La capacità corrente è disponibile tramite la proprietà .sku.capacity.The current capacity is available through the .sku.capacity property. Dopo avere impostato la capacità sul valore desiderato, il set di scalabilità di macchine virtuali in Azure può essere aggiornato con il comando Update-AzureRmVmss.After changing the capacity to the desired value, the virtual machine scale set in Azure can be updated with the Update-AzureRmVmss command.

Quando si aggiunge manualmente un nodo, l'aggiunta di un'istanza del set di scalabilità dovrebbe essere sufficiente per avviare un nuovo nodo Service Fabric in quanto il modello del set di scalabilità include le estensioni per aggiungere automaticamente nuove istanze al cluster Service Fabric.As when adding a node manually, adding a scale set instance should be all that's needed to start a new Service Fabric node since the scale set template includes extensions to automatically join new instances to the Service Fabric cluster.

RiduzioneScaling in

La riduzione è simile all'aumento del numero di istanze. Le modifiche effettive al set di scalabilità di macchine virtuali sono praticamente le stesse.Scaling in is similar to scaling out. The actual virtual machine scale set changes are practically the same. Tuttavia, come illustrato in precedenza, Service Fabric pulisce automaticamente solo i nodi rimossi con la durabilità Gold o Silver.But, as was discussed previously, Service Fabric only automatically cleans up removed nodes with a durability of Gold or Silver. Pertanto, nel caso di riduzione con la durabilità Bronze, è necessario interagire con il cluster Service Fabric per arrestare il nodo da rimuovere, quindi rimuovere il relativo stato.So, in the Bronze-durability scale-in case, it's necessary to interact with the Service Fabric cluster to shut down the node to be removed and then to remove its state.

La preparazione del nodo per l'arresto implica la ricerca del nodo da rimuovere, ovvero il nodo aggiunto più di recente, e la relativa disattivazione.Preparing the node for shutdown involves finding the node to be removed (the most recently added node) and deactivating it. Per i nodi non di inizializzazione, è possibile trovare i nodi più recenti confrontando il valore NodeInstanceId.For non-seed nodes, newer nodes can be found by comparing NodeInstanceId.

using (var client = new FabricClient())
{
    var mostRecentLiveNode = (await client.QueryManager.GetNodeListAsync())
        .Where(n => n.NodeType.Equals(NodeTypeToScale, StringComparison.OrdinalIgnoreCase))
        .Where(n => n.NodeStatus == System.Fabric.Query.NodeStatus.Up)
        .OrderByDescending(n => n.NodeInstanceId)
        .FirstOrDefault();

I nodi di inizializzazione sono diversi e non seguono necessariamente la convenzione per cui gli ID di istanza maggiori vengono rimossi per primi.Seed nodes are different and don't necessarily follow the convention that greater instance IDs are removed first.

Dopo avere individuato il nodo da rimuovere, questo può essere disattivato e rimosso usando la stessa istanza FabricClient e l'istanza IAzure precedente.Once the node to be removed is found, it can be deactivated and removed using the same FabricClient instance and the IAzure instance from earlier.

var scaleSet = AzureClient.VirtualMachineScaleSets.GetById(ScaleSetId);

// Remove the node from the Service Fabric cluster
ServiceEventSource.Current.ServiceMessage(Context, $"Disabling node {mostRecentLiveNode.NodeName}");
await client.ClusterManager.DeactivateNodeAsync(mostRecentLiveNode.NodeName, NodeDeactivationIntent.RemoveNode);

// Wait (up to a timeout) for the node to gracefully shutdown
var timeout = TimeSpan.FromMinutes(5);
var waitStart = DateTime.Now;
while ((mostRecentLiveNode.NodeStatus == System.Fabric.Query.NodeStatus.Up || mostRecentLiveNode.NodeStatus == System.Fabric.Query.NodeStatus.Disabling) &&
        DateTime.Now - waitStart < timeout)
{
    mostRecentLiveNode = (await client.QueryManager.GetNodeListAsync()).FirstOrDefault(n => n.NodeName == mostRecentLiveNode.NodeName);
    await Task.Delay(10 * 1000);
}

// Decrement VMSS capacity
var newCapacity = (int)Math.Max(MinimumNodeCount, scaleSet.Capacity - 1); // Check min count 

scaleSet.Update().WithCapacity(newCapacity).Apply(); 

Anche in questo caso, come per l'aumento del numero di istanze, è possibile usare i cmdlet di PowerShell per modificare la capacità del set di scalabilità di macchine virtuali, se si preferisce un approccio basato sugli script.As with scaling out, PowerShell cmdlets for modifying virtual machine scale set capacity can also be used here if a scripting approach is preferable. Dopo avere rimosso l'istanza di macchina virtuale, è possibile rimuovere lo stato del nodo Service Fabric.Once the virtual machine instance is removed, Service Fabric node state can be removed.

await client.ClusterManager.RemoveNodeStateAsync(mostRecentLiveNode.NodeName);

Potenziali svantaggiPotential drawbacks

Come illustrato nei frammenti di codice precedenti, la creazione di un servizio di scalabilità proprio offre il massimo livello di controllo e personalizzazione sul comportamento di scalabilità dell'applicazione.As demonstrated in the preceding code snippets, creating your own scaling service provides the highest degree of control and customizability over your application's scaling behavior. Questa condizione può essere utile negli scenari che richiedono un controllo preciso su quando e come aumentare o ridurre il numero di istanze dell'applicazione. Tuttavia, questo controllo implica un compromesso a livello di complessità del codice.This can be useful for scenarios requiring precise control over when or how an application scales in or out. However, this control comes with a tradeoff of code complexity. Questo approccio richiede un codice di scalabilità proprio, il che non è semplice.Using this approach means that you need to own scaling code, which is non-trivial.

L'approccio da scegliere per la scalabilità di Service Fabric dipende dallo scenario specifico.How you should approach Service Fabric scaling depends on your scenario. Se la scalabilità non è comune, la possibilità di aggiungere o rimuovere nodi manualmente è probabilmente sufficiente.If scaling is uncommon, the ability to add or remove nodes manually is probably sufficient. Per gli scenari più complessi, gli SDK e le regole di scalabilità automatica che espongono la capacità di eseguire la scalabilità a livello di codice offrono alternative molto efficaci.For more complex scenarios, auto-scale rules and SDKs exposing the ability to scale programmatically offer powerful alternatives.

Passaggi successiviNext steps

Per iniziare a implementare la logica di scalabilità automatica, acquisire familiarità con i seguenti concetti e le utili API:To get started implementing your own auto-scaling logic, familiarize yourself with the following concepts and useful APIs: