Ciao a tutti! Mi chiamo Kirill, sono il CTO di Adapty. Gran parte della nostra architettura si trova su AWS e oggi vi parlerò di come abbiamo ridotto i costi dei server di tre volte utilizzando istanze spot in ambiente di produzione, oltre a come configurare il loro autoscaling. Inizialmente ci sarà una panoramica di come funziona, seguita da istruzioni dettagliate per l'avvio.
Cosa sono le istanze spot?
Gli istanze sono server di altri utenti AWS che in questo momento sono inattivi e li vendono a un grande sconto (Amazon afferma fino al 90%, ma dalla nostra esperienza è circa 3 volte, variabile a seconda della regione, AZ e del tipo di istanza). La loro principale differenza rispetto agli ordinari è che possono spegnersi in qualsiasi momento. Pertanto, per molto tempo abbiamo ritenuto che fosse opportuno utilizzarli per ambienti di sviluppo o per compiti di calcolo, salvando i risultati intermedi su S3 o in un database, ma non per la produzione. Esistono soluzioni di terze parti che consentono di utilizzare gli spot in produzione, ma nel nostro caso ci sono molte complicazioni, quindi non le abbiamo implementate. L'approccio descritto nell'articolo funziona completamente all'interno delle funzionalità standard di AWS, senza script aggiuntivi, cron o simili.
Di seguito troverai alcuni screenshot che mostrano la cronologia dei prezzi per le istanze spot.
m5.large nella regione eu-west-1 (Irlanda). Il prezzo è prevalentemente stabile per 3 mesi, attualmente il risparmio è di 2.9x.

m5.large nella regione us-east-1 (Virginia del Nord). Il prezzo cambia continuamente da 3 mesi, al momento il risparmio va da 2,3x a 2,8x a seconda della zona di disponibilità.

t3.small nella regione us-east-1 (Virginia del Nord). Il prezzo è stabile da 3 mesi, al momento il risparmio è di 3,4x.

Architettura del servizio
L'architettura di base del servizio di cui parleremo in questo articolo è illustrata nel diagramma qui sotto.

Application Load Balancer → EC2 Target Group → Elastic Container Service
Come bilanciatore, viene utilizzato l'Application Load Balancer (ALB), che invia le richieste al EC2 Target Group (TG). TG è responsabile dell'apertura delle porte sugli istanze per l'ALB e della loro connessione con le porte dei container Elastic Container Service (ECS). ECS è l'equivalente di Kubernetes in AWS, che gestisce i container Docker.
Su un'istanza possono esserci più contenitori in esecuzione con le stesse porte, quindi non possiamo specificarle in modo fisso. ECS informa TG che sta avviando un nuovo task (nella terminologia di Kubernetes questo è chiamato pod), essa verifica le porte disponibili sull'istanza e ne assegna una per il task in avvio. Inoltre, TG controlla regolarmente se l'istanza e l'API su di essa funzionano tramite health check, e se rileva problemi, smette di inviare richieste a quell'istanza.
Gruppi di Auto Scaling EC2 + Fornitori di Capacità ECS
Nella diagramma sopra riportata non è mostrato il servizio Gruppi di Auto Scaling EC2 (ASG). Dal nome si può dedurre che è responsabile della scalabilità delle istanze. Fino a tempi recenti, AWS non disponeva di un'opzione integrata per gestire il numero di macchine avviate da ECS. ECS permette di scalare il numero di task, ad esempio, in base all'utilizzo della CPU, della RAM o al numero di richieste. Tuttavia, se i task occupavano tutte le istanze disponibili, nuove macchine non venivano automaticamente attivate.
Questo è cambiato con l'introduzione degli ECS Capacity Providers (ECS CP). Ora ogni servizio in ECS può essere collegato a un ASG, e se i task non si adattano alle istanze in esecuzione, ne verranno avviate di nuove (ma entro i limiti stabiliti dall'ASG). Funziona anche in direzione opposta: se ECS CP rileva istanze inattive senza task, ordinerà all'ASG di spegnerle. ECS CP ha la possibilità di specificare una percentuale obiettivo di utilizzo delle istanze, in modo da mantenere un certo numero di macchine sempre disponibili per una rapida scalabilità dei task, ne parlerò più avanti.
EC2 Launch Templates
L'ultimo servizio di cui parlerò, prima di passare a una descrizione dettagliata della creazione di questa infrastruttura, è EC2 Launch Templates. Consente di creare un modello in base al quale verranno avviate tutte le macchine, per evitare di dover ripetere questa operazione ogni volta da zero. Qui puoi scegliere il tipo di macchina da avviare, il gruppo di sicurezza, l'immagine del disco e molti altri parametri. È anche possibile specificare dati utente, che saranno caricati su tutte le istanze avviate. Nei dati utente, puoi eseguire script; ad esempio, è possibile modificare il contenuto di un file. .
Uno dei parametri di configurazione più importanti in questo articolo è =true. Se questo parametro è attivato, non appena ECS riceve il segnale che un'istanza spot sta per essere prelevata, tutte le attività in esecuzione su di essa vengono messe nello stato Draining. Nessuna nuova attività sarà assegnata a quest'istanza; se ci sono attività che vogliono essere distribuite su di essa, verranno annullate. Anche le richieste dal bilanciatore smettono di arrivare. La notifica di rimozione dell'istanza arriva 2 minuti prima dell'evento reale. Pertanto, se il tuo servizio non esegue attività per più di 2 minuti e non salva nulla su disco, puoi utilizzare le istanze spot senza perdita di dati.
Per quanto riguarda il disco, AWS recentemente è possibile utilizzare Elastic File System (EFS) insieme a ECS; con questo schema, persino il disco non rappresenta un ostacolo, ma non lo abbiamo provato, poiché in linea di principio non abbiamo bisogno del disco per memorizzare lo stato. Di default, dopo aver ricevuto SIGINT (inviato nel momento in cui il task passa allo stato Draining), tutte le attività in esecuzione verranno interrotte dopo 30 secondi, anche se non sono state completate; questo tempo può essere modificato tramite il parametro . È importante non impostarlo su più di 2 minuti per le istanze spot.
Creazione del servizio
Ora passiamo direttamente alla creazione del servizio descritto. Durante il processo descriverò anche alcuni punti utili che non sono stati menzionati sopra. In generale, si tratta di un'istruzione passo passo, ma non esaminerò casi davvero molto basilari o molto specifici. Tutte le azioni vengono eseguite nella console visiva di AWS, ma possono essere replicate programmaticamente con CloudFormation o Terraform. In Adapty utilizziamo Terraform.
EC2 Launch Template
In questo servizio viene creata una configurazione delle macchine che verranno utilizzate. La gestione dei template avviene nella sezione EC2 -> Instances -> Launch templates.
Amazon machine image (AMI) — specifichiamo l'immagine del disco da cui partiranno tutte le istanze. Per ECS, nella maggior parte dei casi è consigliabile utilizzare un'immagine ottimizzata di Amazon. Viene aggiornata regolarmente e contiene tutto il necessario per far funzionare ECS. Per conoscere l'ID attuale dell'immagine, accediamo alla pagina , selezioniamo la regione utilizzata e copiamo l'AMI ID corrispondente. Ad esempio, per la regione us-east-1, l'ID attuale al momento della scrittura è ami-00c7c1cf5bdc913ed. Questo ID deve essere inserito nel campo Specifica un valore personalizzato.
Tipo di istanza — specifichiamo il tipo di istanza. Scegli quello che si adatta meglio alle tue esigenze.
Coppia di chiavi (accesso) — specifichiamo il certificato con cui sarà possibile connettersi all'istanza tramite SSH, se necessario.
Impostazioni di rete — specifichiamo i parametri di rete. Piattaforma di rete nella maggior parte dei casi deve essere Virtual Private Cloud (VPC). Gruppi di sicurezza — gruppi di sicurezza per le tue istanze. Poiché utilizzeremo un bilanciatore di carico davanti alle istanze, ti consiglio di specificare qui un gruppo che consenta connessioni in ingresso solo dal bilanciatore. Ciò significa che avrai 2 gruppi di sicurezza: uno per il bilanciatore, che consente connessioni in ingresso (inbound) da ovunque sulle porte 80 (http) e 443 (https), e l'altro per le macchine, che consente connessioni in ingresso su qualsiasi porta dal gruppo del bilanciatore. Le connessioni in uscita (outbound) in entrambi i gruppi devono essere consentite tramite il protocollo TCP su tutte le porte verso tutti gli indirizzi. È possibile limitare le porte e gli indirizzi per le connessioni in uscita, ma in tal caso è necessario monitorare costantemente che non si stia cercando di accedere a una porta chiusa.
Storage (volumes) — specifichiamo le impostazioni del disco per le macchine. La dimensione del disco non può essere inferiore a quella definita nell'AMI, per ECS Optimized — 30 GiB.
Dettagli avanzati — specifichiamo parametri aggiuntivi.
Opzione di acquisto — vogliamo acquistare istanze spot. Vogliamo, ma qui non selezioneremo questa opzione, la configureremo nel Gruppo di Scaling Automatico, dove ci sono più opzioni.
Profilo istanza IAM — indichiamo il ruolo con cui verranno avviate le istanze. Affinché le istanze funzionino in ECS, hanno bisogno dei permessi che di solito sono associati al ruolo ecsInstanceRole. In alcuni casi, questo può essere creato; in caso contrario, qui è spiegato come farlo. Dopo la creazione, lo indichiamo nel modello.
Dopo ci sono molti parametri; in generale, si possono lasciare i valori predefiniti, ma ognuno di essi ha una descrizione chiara. Io attivo sempre i parametri EBS-optimized instance e T2/T3 Unlimited, se si utilizzano istanze.
User data — indichiamo i dati utente. Modificheremo il file /etc/ecs/ecs.config, in cui è presente la configurazione dell'agente ECS.
Ecco un esempio di come potrebbero apparire i dati utente:
#!/bin/bash
echo ECS_CLUSTER=DemoApiClusterProd >> /etc/ecs/ecs.config
echo ECS_ENABLE_SPOT_INSTANCE_DRAINING=true >> /etc/ecs/ecs.config
echo ECS_CONTAINER_STOP_TIMEOUT=1m >> /etc/ecs/ecs.config
echo ECS_ENGINE_AUTH_TYPE=docker >> /etc/ecs/ecs.config
echo "ECS_ENGINE_AUTH_DATA={"registry.gitlab.com":{"username":"username","password":"password"}}" >> /etc/ecs/ecs.configECS_CLUSTER=DemoApiClusterProd — questo parametro indica che l'istanza appartiene a un cluster con il nome specificato, il quale potrà quindi eseguire i propri task su questo server. Non abbiamo ancora creato un cluster, ma quando lo faremo utilizzeremo questo nome.
ECS_ENABLE_SPOT_INSTANCE_DRAINING=true — questo parametro indica che, quando si riceve un segnale di spegnimento per un'istanza spot, tutti i task su di essa devono essere spostati nello stato Draining.
ECS_CONTAINER_STOP_TIMEOUT=1m — il parametro indica che, dopo aver ricevuto il segnale SIGINT, tutte le attività hanno 1 minuto prima di essere terminate.
ECS_ENGINE_AUTH_TYPE=docker — il parametro indica che viene utilizzato lo schema docker come meccanismo di autorizzazione.
ECS_ENGINE_AUTH_DATA=... — i parametri di connessione per il registro privato dei container, dove sono memorizzate le tue immagini Docker. Se è pubblico, non è necessario specificare nulla.
In questo articolo utilizzerò un'immagine pubblica da Docker Hub, quindi non è necessario specificare i parametri. ECS_ENGINE_AUTH_TYPE e ECS_ENGINE_AUTH_DATA non è necessario.
È utile sapere: si raccomanda di aggiornare regolarmente l'AMI, poiché nelle nuove versioni vengono aggiornati Docker, Linux, ECS agent e altro. Per non dimenticarlo, puoi sull'uscita di nuove versioni. Puoi ricevere notifiche via email e aggiornare manualmente, oppure puoi scrivere una funzione Lambda che creerà automaticamente una nuova versione del Launch Template con AMI aggiornato.
Gruppo di Auto Scaling EC2
Il Gruppo di Auto Scaling gestisce l'avvio e la scalabilità delle istanze. La gestione dei gruppi avviene nella sezione EC2 -> Auto Scaling -> Gruppi di Auto Scaling.
Template di avvio — selezioniamo il template creato nel passaggio precedente. Lasciamo la versione predefinita.
Opzioni di acquisto e tipi di istanza — specifichiamo i tipi di istanze per il cluster. Adhere to launch template utilizza il tipo di istanza del Launch Template. Combine purchase options and instance types consente di configurare flessibilmente i tipi di istanze. Lo utilizzeremo.
Base on-demand opzionale — il numero di istanze normali, non spot, che saranno sempre attive.
Percentuale on-demand oltre la base — la proporzione tra istanze normali e istanze spot, 50-50 distribuirà uniformemente, 20-80 comporterà l'innalzamento di 4 istanze spot per ogni istanza normale. In questo esempio indicherò 50-50, ma nella realtà facciamo spesso 20-80, in alcuni casi 0-100.
Tipi di istanze — qui si possono indicare ulteriori tipi di istanze che saranno utilizzati nel cluster. Non li abbiamo mai usati, perché non capisco bene il senso di questa storia. Forse è legato ai limiti su specifici tipi di istanze, ma si possono aumentare facilmente tramite il supporto. Se conoscete un'applicazione, sarei felice di leggerla nei commenti)

Network log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy stats timeout 30s user haproxy group haproxy daemondefaults log global mode http option httplog option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000frontend http_front bind *:80 stats uri /haproxy?stats default_backend http_backbackend http_back balance roundrobin server server_name1 private_ip1:80 check server server_name2 private_ip2:80 check — impostazioni di rete, si scelgono VPC e subnet per le macchine; nella maggior parte dei casi è opportuno selezionare tutte le subnet disponibili.
Bilanciamento del carico — impostazioni del bilanciatore, ma faremo questo separatamente; qui non tocchiamo nulla. Controlli di salute saranno configurati successivamente.
Dimensione del gruppo — indichiamo i limiti sul numero di macchine nel cluster e il numero desiderato di macchine all'avvio. Il numero di macchine nel cluster non sarà mai inferiore a quello minimo indicato e non supererà quello massimo, anche se gli metriche suggeriscono un'espansione.
Politiche di scaling — parametri di scaling, ma scaleremo basandoci sui task ECS in esecuzione, quindi configureremo lo scaling successivamente.
Protezione della scala degli istanze — protezione delle istanze dalla rimozione durante il ridimensionamento. Attiviamo in modo che l'ASG non rimuova la macchina con task in esecuzione. Disattivare la protezione per le istanze senza task sarà compito del Provider di Capacità ECS.
Aggiungi tag — è possibile specificare tag per le istanze (per questo deve essere selezionata l'opzione Tag new instances). Si consiglia di specificare il tag Nome, in modo che tutte le istanze avviate all'interno del gruppo abbiano lo stesso nome, facilitando la visualizzazione nella console.

Dopo aver creato il gruppo, aprilo e vai alla sezione Configurazioni avanzate, perché in fase di creazione non tutte le opzioni sono visibili nella console.
Politiche di terminazione — le regole che vengono seguite durante la rimozione delle istanze. Vengono applicate in ordine. Di solito utilizziamo quelle nella figura sottostante. Prima si rimuovono le istanze con il Launch Template più vecchio (ad esempio, se abbiamo aggiornato l'AMI, si è creata una nuova versione, ma tutte le istanze sono riuscite a passare a questa). Poi si scelgono le istanze più vicine al prossimo orario di fatturazione calcolato. E poi si selezionano le più vecchie in base alla data di avvio.

È utile sapere: per aggiornare tutte le macchine nel cluster, è comodo utilizzare . Se combinato con una funzione Lambda dal passo precedente, avrete un sistema di aggiornamento delle istanze completamente automatizzato. Prima di aggiornare tutte le macchine, è necessario disattivare la protezione dal ridimensionamento delle istanze per tutte le istanze nel gruppo. Non la configurazione nel gruppo, ma proprio la protezione delle macchine, che può essere disattivata nella scheda gestione delle istanze.
Application Load Balancer e EC2 Target Group
Il bilanciatore viene creato nella sezione EC2 → Load Balancing → Load Balancers. Utilizzeremo l'Application Load Balancer, per un confronto tra i vari tipi di bilanciatori si può leggere la .
Listeners È consigliabile configurare le porte 80 e 443 e effettuare un reindirizzamento dalla 80 alla 443 tramite regole del bilanciatore.
Zone di disponibilità In molti casi, selezioniamo tutte le zone di disponibilità.
Configura le impostazioni di sicurezza Qui si specifica il certificato SSL per il bilanciatore; l'opzione più comoda è in ACM. Puoi leggere delle differenze Politica di Sicurezza nel , puoi lasciare quella selezionata di default ELBSecurityPolicy-2016-08. Dopo la creazione del bilanciatore, vedrai il suo nome DNS, per il quale dovrai configurare un CNAME per il tuo dominio. Ecco un esempio di come appare in Cloudflare.

Gruppo di Sicurezza Creiamo o selezioniamo un gruppo di sicurezza per il bilanciatore; ne ho parlato più sopra nella sezione Template di Avvio EC2 → Impostazioni di rete.
Gruppo di destinazione creiamo un gruppo responsabile del routing delle richieste dal bilanciatore alle macchine e ne verifica la disponibilità per sostituirle in caso di problemi. Tipo di destinazione deve essere Instance, Protocollo e Port qualsiasi, se utilizzi HTTPS per la comunicazione tra il bilanciatore e le istanze, allora devi caricare il certificato su di esse. Nel contesto di questo esempio, non lo faremo, semplicemente lasceremo la porta 80.
Controlli di salute — parametri di verifica della funzionalità del servizio. In questo servizio, deve trattarsi di una richiesta separata che implementa parti cruciali della logica aziendale; per questo esempio, lascerò le impostazioni predefinite. Successivamente, è possibile scegliere l'intervallo delle richieste, il timeout, i codici di risposta di successo, e altro. Nel nostro esempio, indicheremo i codici di successo 200-399, perché l'immagine Docker utilizzata restituisce il codice 304.

Registrare obiettivi — qui si scelgono le macchine per il gruppo, ma nel nostro caso ci penserà ECS, quindi saltiamo semplicemente questo passaggio.
È utile sapere: a livello del bilanciatore di carico, è possibile attivare i log che verranno salvati in S3 in un certo . Da lì, possono essere esportati in servizi esterni per analisi, oppure è possibile eseguire query SQL direttamente sui dati in S3 con . Questo è comodo e funziona senza alcun codice aggiuntivo. Raccomando inoltre di impostare la cancellazione dei log dal bucket S3 dopo un periodo di tempo specifico.
Definizione del compito ECS
Nei passaggi precedenti abbiamo creato tutto ciò che riguarda l'infrastruttura del servizio, ora passiamo alla descrizione dei container che lanciamo. Questo viene fatto nella sezione ECS → Definizioni di Task.
Tipologia di compatibilità del lancio — scegliamo EC2.
Ruolo IAM di esecuzione del task — selezioniamo ecsTaskExecutionRole. Con questo ruolo vengono registrati i log, viene fornito accesso a variabili segrete e altro.
Nella sezione Definizioni di Container clicchiamo su Aggiungi Container.
Image — link all'immagine con il codice del progetto, in questo esempio utilizzerò un'immagine pubblica da Docker Hub .
Limiti di Memoria — limiti di memoria per il container. Limite Fisso — limite fisso, se il container supera il valore specificato, verrà eseguita il comando docker kill, il container morirà immediatamente. Limite Morbido — limite morbido, il contenitore può superare il valore specificato, ma durante l'assegnazione dei task alle macchine verrà considerato questo parametro. Ad esempio, se c'è 4 GiB di memoria RAM sulla macchina e il limite morbido del contenitore è di 2048 MiB, allora su questa macchina possono essere eseguiti al massimo 2 task con questo contenitore. In realtà, 4 GiB di RAM sono leggermente inferiori a 4096 MiB, come si può vedere nella scheda ECS Instances nel cluster. Il limite morbido non può essere maggiore del limite rigido. È importante comprendere che se in un task ci sono più contenitori, i loro limiti si sommano.
Mappature delle porte — in Porta host se specifichiamo 0, questo significa che la porta verrà assegnata in modo dinamico, verrà monitorata dal Target Group. Porta del contenitore — porta sulla quale funziona la tua applicazione, spesso impostata nel comando di esecuzione, o assegnata nel codice della tua applicazione, Dockerfile, ecc. Per il nostro esempio useremo 3000, poiché è specificato in l'immagine utilizzata.
Controllo dello stato — parametri di controllo della funzionalità del contenitore, non confondere con quello impostato nel Target Group.
Ambiente — impostazioni ambientali. Unità CPU — simile ai limiti di memoria, ma riguarda il processore. Ogni core del processore corrisponde a 1024 unità, quindi se il server ha un processore dual-core e il valore impostato per il container è 512, sarà possibile eseguire 4 task con quel container su uno stesso server. Le unità CPU corrispondono sempre al numero di core, non possono essere leggermente inferiori come nel caso della memoria.
Comando — comando per avviare il servizio all'interno del container, tutti i parametri devono essere separati da una virgola. Può essere gunicorn, npm, ecc. Se non specificato, verrà utilizzato il valore della direttiva CMD dal Dockerfile. Indichiamo npm,start.
Variabili ambientali — variabili d'ambiente del container. Queste possono essere dati testuali semplici, così come variabili segrete da o .
Storage e Logging — qui configureremo il logging in CloudWatch Logs (servizio di log di AWS). È sufficiente attivare l'opzione Auto-configure CloudWatch Logs. Dopo la creazione della Task Definition, verrà automaticamente creata un gruppo log in CloudWatch. Per impostazione predefinita, i log in esso vengono conservati indefinitamente; consiglio di modificare il periodo di retention da Never Expire al periodo richiesto. Questo può essere fatto in CloudWatch Log groups, cliccando sul periodo attuale e selezionando uno nuovo.

ECS Cluster e ECS Capacity Provider
Andiamo alla sezione ECS → Clusters per creare un cluster. Come modello scegliamo EC2 Linux + Networking.
Nome del cluster — è molto importante, utilizziamo qui lo stesso nome indicato nel Launch Template nel parametro ECS_CLUSTER, nel nostro caso — DemoApiClusterProd. Spuntiamo la casella Crea un cluster vuoto. Opzionalmente, puoi abilitare Container Insights per visualizzare le metriche dei servizi in CloudWatch. Se hai fatto tutto correttamente, nella sezione ECS Instances vedrai le macchine create nel gruppo di Auto Scaling.

Andiamo alla scheda Capacity Providers e creiamo uno nuovo. Ricordo che è necessario per gestire la creazione e lo spegnimento delle macchine in base al numero di task ECS attivi. È importante notare che il provider può essere associato a un solo gruppo.
Auto Scaling group — selezioniamo il gruppo creato in precedenza.
Scaling gestito — abilitiamo per consentire al provider di scalare il servizio.
Capacità target % — quale percentuale di carico delle macchine è necessaria per i task. Se si specifica il 100%, tutte le macchine saranno sempre occupate con task in esecuzione. Se si specifica il 50%, metà delle macchine saranno sempre libere. In questo caso, se si verifica un'improvvisa impennata del carico, i nuovi task andranno immediatamente sulle macchine disponibili, senza dover attendere il deploy di nuove istanze.
Protezione dalle terminazioni gestita — se attivato, questo parametro consente al provider di rimuovere la protezione delle istanze dalla cancellazione. Questo accade quando non ci sono task attivi sulla macchina e consente la Target capacity %.
Servizio ECS e configurazione della scalabilità
Ultimo passo :) Per creare un servizio, è necessario accedere al cluster creato in precedenza nella scheda Servizi.
Tipo di avvio — bisogna cliccare su Switch to capacity provider strategy e selezionare il provider creato in precedenza.

Definizione del task — selezioniamo la Definizione del Task creata in precedenza e la sua revisione.
Nome del servizio — per non confondersi, indichiamo sempre lo stesso nome della Definizione del Task.
Tipo di servizio — sempre Replica.
Numero di task — numero desiderato di task attivi nel servizio. Questo parametro è gestito dalla scalabilità, ma deve comunque essere specificato.
Percentuale minima di salute e Percentuale massima — definiscono il comportamento delle attività durante il deployment. I valori predefiniti 100 e 200 indicano che al momento del deployment il numero delle attività aumenterà di fattore, per poi tornare al valore desiderato. Se hai 1 attività in esecuzione, min=0 e max=100, allora durante il deployment sarà terminata e dopo verrà avviata una nuova attività, il che comporterà un'interruzione. Se hai 1 attività in funzionamento, min=50 e max=150, il deployment non avverrà affatto, perché non si può dividere 1 attività a metà o aumentarla di un fattore e mezzo.
Tipo di deployment — lasciamo Rolling update.
Template di posizionamento — regole per il posizionamento delle attività sulle macchine. Per impostazione predefinita, è impostato su AZ Balanced Spread, il che significa che ogni nuova attività verrà collocata su una nuova istanza fino a quando non sono in funzione macchine in tutte le zone di disponibilità. Di solito facciamo BinPack — CPU e Spread — AZ, con questa politica, le attività vengono collocate il più strettamente possibile su una macchina in base alla CPU. Se è necessario creare una nuova macchina, viene creata in una nuova zona di disponibilità.

Tipo di bilanciatore di carico — scegliamo Application Load Balancer.
Ruolo IAM del servizio — selezioniamo ecsServiceRole.
Nome del bilanciatore di carico — selezioniamo il bilanciatore creato in precedenza.
Periodo di tolleranza per il controllo dello stato — pausa prima di eseguire i controlli di disponibilità dopo il rilascio di un nuovo task, di solito impostiamo 60 secondi.
Contenitore per il bilanciamento del carico — nel campo Nome del gruppo di destinazione scegliamo il gruppo precedentemente creato, e tutto si riempirà automaticamente.

Auto Scaling del Servizio — parametri di scaling del servizio. Scegliamo Configura l'Auto Scaling del servizio per regolare il numero desiderato del tuo servizio. Impostiamo il numero minimo e massimo di task durante il scaling.
Ruolo IAM per l'Auto Scaling del Servizio — selezioniamo AWSServiceRoleForApplicationAutoScaling_ECSService.
Politiche di scaling automatico dei task — regole per il scaling. Ci sono 2 tipi:
- Tracciamento degli obiettivi — monitoraggio della metrica target (utilizzo di CPU/RAM o numero di richieste per ogni task). Ad esempio, vogliamo che il carico medio della CPU sia dell'85%, quando supererà tale valore, nuovi task verranno aggiunti fino a che non si tornerà al valore target. Se il carico è inferiore, i task verranno rimossi, a meno che non sia attivata la protezione dallo scaling verso il basso (Disabilita scaling in).
- Scaling a passi — reazione a qualsiasi evento. Qui puoi configurare la reazione a un evento qualsiasi (CloudWatch Alarm); quando si verifica, puoi aggiungere o rimuovere il numero specificato di task, oppure indicare esattamente il numero di task.
Il servizio può avere diverse regole di scalabilità, il che può essere utile; è importante assicurarsi che non conflittino tra loro.
Conclusione
Se hai seguito le istruzioni e hai usato la stessa immagine Docker, il tuo servizio dovrebbe restituire questa pagina.

- Abbiamo creato un modello secondo il quale vengono avviate tutte le macchine nel servizio. Abbiamo anche imparato a aggiornare le macchine quando il modello cambia.
- Abbiamo configurato la gestione del segnale di arresto dell'istanza spot; quindi, entro un minuto dalla ricezione, tutti i task in esecuzione vengono rimossi dalla macchina, in modo che nulla venga perso o interrotto.
- Abbiamo attivato un bilanciatore di carico per distribuire uniformemente il carico tra le macchine.
- Abbiamo creato un servizio che funziona su istanze spot, il che riduce i costi delle macchine di circa tre volte.
- Abbiamo impostato l'autoscaling in entrambe le direzioni per gestire l'aumento del carico, senza pagare per il tempo di inattività.
- Utilizziamo il Capacity Provider affinché sia l'applicazione a gestire l'infrastruttura (le macchine), e non il contrario.
- Siamo bravi.
Se hai picchi di carico prevedibili, ad esempio a causa di una grande campagna email, puoi impostare lo scaling in base a .
Inoltre, puoi effettuare lo scaling basandoti su dati provenienti da diverse parti del tuo sistema. Ad esempio, abbiamo la funzionalità di agli utenti dell'app mobile. A volte la campagna viene inviata a oltre 1 milione di persone. Dopo un invio del genere, si osserva sempre un grande aumento delle richieste all'API, poiché molti utenti accedono all'app simultaneamente. Quindi, se vediamo che nella coda per l'invio delle notifiche promozionali ci sono significativamente più richieste rispetto ai parametri standard, possiamo immediatamente attivare alcune macchine e task aggiuntivi per essere pronti al carico.
Sarei felice se nei commenti condivideste casi interessanti d'uso delle istanze spot e ECS, oppure qualcosa riguardo allo scaling.
Presto pubblicheremo articoli su come gestiamo migliaia di eventi analitici al secondo su un stack principalmente serverless (con budget) e su come realizziamo il deployment dei servizi utilizzando GitLab CI e Terraform Cloud.
Iscrivetevi a noi, sarà interessante!
Solo gli utenti registrati possono partecipare al sondaggio. , per favore.
Usate le istanze spot in produzione?
22,2%Sì
66,7%No18
11,1%Ho scoperto queste istanze da un articolo, pianifico di utilizzarle.
Hanno votato 27 utenti. 5 utenti si sono astenuti.
Fonte: habr.com
