Ciao a tutti! Mi chiamo Kirill, sono CTO in Adapty. Gran parte della nostra architettura si trova su AWS e oggi vi parlerò di come abbiamo ridotto i costi sui server di 3 volte grazie all'utilizzo di istanze spot in un ambiente di produzione e di come configurare il loro autoscaling. Inizierò con una panoramica su come funziona, seguita da istruzioni dettagliate per l'implementazione.
Cosa sono le istanze spot?
istanze spot sono server di altri utenti AWS che al momento sono inattivi e vengono venduti a un grande sconto (Amazon scrive fino al 90%, ma dalla nostra esperienza circa ~3x, varia a seconda della regione, AZ e tipo di istanza). La principale differenza rispetto alle normali è che possono spegnersi in qualsiasi momento. Pertanto, a lungo abbiamo ritenuto che fosse normale utilizzarle per ambienti di sviluppo, o per calcoli di qualcosa, mantenendo i risultati intermedi su S3 o in un database, ma non per la produzione. Esistono soluzioni di terze parti che consentono di utilizzare le istanze spot in produzione, ma per il nostro caso presentano molti problemi, quindi non le abbiamo implementate. L'approccio descritto in questo articolo funziona interamente all'interno delle funzionalità standard di AWS, senza script aggiuntivi, cron e simili.
Di seguito mostrerò alcuni screenshot che mostrano la storia dei prezzi delle 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 costantemente per 3 mesi; attualmente 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; attualmente il risparmio è di 3.4x.

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

Application Load Balancer → EC2 Target Group → Elastic Container Service
Come bilanciatore, utilizziamo 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 associazione con le porte dei contenitori del Elastic Container Service (ECS). ECS è l'equivalente di Kubernetes in AWS, che gestisce i contenitori Docker.
Su un'istanza possono esserci più contenitori attivi con le stesse porte, quindi non possiamo definirle in modo fisso. ECS informa TG che sta avviando un nuovo task (chiamato pod in terminologia Kubernetes), effettua un controllo sulle porte libere sull'istanza e ne assegna una per il task in avvio. TG controlla anche regolarmente se l'istanza e le API su di essa funzionano tramite un health check e, se riscontra dei problemi, smette di inviare richieste a quella istanza.
EC2 Auto Scaling Groups + ECS Capacity Providers
Nella diagramma riportata sopra non è mostrato il servizio EC2 Auto Scaling Groups (ASG). Dal nome si può capire che è responsabile della scalabilità delle istanze. Fino a poco tempo fa, AWS non aveva una funzionalità integrata per gestire il numero di macchine avviate da ECS. ECS consentiva di scalare il numero di task, ad esempio, in base all'uso della CPU, RAM o al numero di richieste. Ma se i task occupavano tutte le istanze disponibili, nuove macchine non venivano avviate automaticamente.
Questo è cambiato con l'introduzione di ECS Capacity Providers (ECS CP). Ora ogni servizio in ECS può essere associato a un ASG e, se i task non possono essere contenuti nelle istanze attive, verrà avviata una nuova (ma nel rispetto dei limiti impostati per l'ASG). Funziona anche in senso opposto: se ECS CP rileva istanze inattive senza task, ordina all'ASG di spegnerle. ECS CP ha la possibilità di specificare una percentuale di carico target delle istanze, in modo che un certo numero di macchine rimanga sempre libero per una rapida scalabilità dei task, vi parlerò di questo tra poco.
EC2 Launch Templates
L'ultimo servizio di cui parlerò, prima di passare a una descrizione dettagliata della creazione di questa infrastruttura, è EC2 Launch Templates. Permette di creare un modello secondo il quale verranno avviate tutte le macchine, in modo da non dover ripetere il processo ogni volta da zero. Qui si possono scegliere il tipo di macchina da avviare, il gruppo di sicurezza, l'immagine del disco e molti altri parametri. È possibile specificare anche dati utente che saranno caricati su tutte le istanze avviate. Nei dati utente è possibile eseguire script, ad esempio, è possibile modificare il contenuto di un file .
Uno dei parametri di configurazione più importanti ai fini di questo articolo è =true. Se questo parametro è attivato, non appena ECS riceve un segnale che l'istanza spot viene ritirata, tutti i task in esecuzione su di essa vengono messi nello stato Draining. Nessun nuovo task verrà assegnato a questa istanza e se ci sono task che vogliono passare su di essa, verranno annullati. Anche le richieste dal bilanciatore di carico smettono di arrivare. La notifica di rimozione dell'istanza arriva 2 minuti prima dell'evento effettivo. Quindi, se il tuo servizio non esegue attività per più di 2 minuti e non salva nulla su disco, puoi usare le istanze spot senza perdita di dati.
Riguardo al disco - AWS recentemente possibile l'uso di Elastic File System (EFS) insieme a ECS, con questo schema anche il disco non rappresenta un ostacolo, ma non l'abbiamo provato poiché, in linea di principio, non abbiamo bisogno di un disco per memorizzare lo stato. Per impostazione predefinita, dopo aver ricevuto SIGINT (inviato nel momento in cui il task passa allo stato Draining), tutti i task in esecuzione verranno arrestati entro 30 secondi, anche se non hanno potuto completarsi, questo tempo può essere modificato tramite il parametro . L'importante è non impostarlo a più di 2 minuti per le macchine spot.
Creazione del servizio
Passiamo direttamente alla creazione del servizio descritto. Durante il processo descriverò anche alcuni punti utili che non sono stati menzionati in precedenza. In generale, questa è una guida passo passo, ma non tratterò casi molto fondamentali o viceversa molto specifici. Tutte le azioni vengono eseguite nella console visuale di AWS, ma possono essere replicate programmaticamente utilizzando CloudFormation o Terraform. In Adapty utilizziamo Terraform.
EC2 Launch Template
In questo servizio viene creata la 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 verranno avviate tutte le istanze. Per ECS, nella maggior parte dei casi, è consigliabile utilizzare l'immagine ottimizzata di Amazon. Viene aggiornata regolarmente e contiene tutto il necessario per il funzionamento di ECS. Per scoprire l'ID dell'immagine attuale, accediamo alla pagina , selezioniamo la regione utilizzata e copiamo l'AMI ID per essa. Ad esempio, per la regione us-east-1, l'ID attuale al momento della scrittura di questo articolo è ami-00c7c1cf5bdc913ed. Questo ID deve essere inserito nella voce Specifica un valore personalizzato.
Tipo di istanza — specifichiamo il tipo di istanza. Scegli quello che meglio si adatta alle tue esigenze.
Chiave di accesso (login) — specifichiamo il certificato che consente di connettersi all'istanza tramite SSH, se necessario.
Impostazioni di rete — specifichiamo i parametri di rete. Piattaforma di networking nella maggior parte dei casi dovrebbe 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 solo le connessioni in entrata dal bilanciatore. Ciò significa che avrai 2 gruppi di sicurezza, uno per il bilanciatore che consente le connessioni in entrata (inbound) da qualsiasi parte sulle porte 80 (http) e 443 (https), e un secondo per le macchine, che consente le connessioni in entrata su tutte le porte dal gruppo del bilanciatore. Le connessioni in uscita (outbound) in entrambi i gruppi devono essere aperte per 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 di non tentare di accedere a porte chiuse.
Archiviazione (volumi) — specifichiamo i parametri dei dischi per le macchine. La dimensione del disco non può essere inferiore a quella specificata nell'AMI, per ECS Optimized — 30 GiB.
Dettagli avanzati — specifichiamo parametri aggiuntivi.
Opzione di acquisto — vogliamo acquistare istanze spot. Vogliamo farlo, ma qui non segneremo questa casella, lo configureremo nel gruppo di scaling automatico, dove ci sono più opzioni.
Profilo istanza IAM — specifichiamo il ruolo con cui verranno avviate le istanze. Affinché le istanze funzionino in ECS, hanno bisogno dei permessi, che di solito si trovano nel ruolo ecsInstanceRole. In alcuni casi può essere creato, se non c'è, qui informazioni su come farlo. Dopo la creazione, lo specifichiamo nel modello.
Dopo ci sono molti parametri, in genere si possono lasciare i valori predefiniti, ma ciascuno di essi ha una chiara descrizione. Attivo sempre i parametri istanza EBS-ottimizzata e T2/T3 Unlimited, se sono utilizzati istanze.
Dati utente — specifichiamo i dati utente. Modificheremo il file /etc/ecs/ecs.config, in cui si trova la configurazione dell'agente ECS.
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 — il parametro indica che l'istanza appartiene a un cluster con un nome specificato, cioè questo cluster sarà in grado di 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 — il parametro indica che, quando si riceve un segnale di spegnimento dell'istanza spot, tutti i task su di essa devono essere messi in 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 il meccanismo di autorizzazione docker.
ECS_ENGINE_AUTH_DATA=... — parametri di connessione al registry privato dei container, dove sono memorizzate le tue immagini Docker. Se è pubblico, non è necessario indicare nulla.
In questo articolo utilizzerò un'immagine pubblica da Docker Hub, quindi non indicherò 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 si aggiornano le versioni di Docker, Linux, dell'agente ECS e altro. Per non dimenticarlo, puoi per il rilascio 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 l'AMI aggiornato.
EC2 Auto Scaling Group
L'Auto Scaling Group è responsabile dell'avvio e dello scaling delle istanze. La gestione dei gruppi avviene nella sezione EC2 -> Auto Scaling -> Auto Scaling Groups.
Template di avvio — selezioniamo il template creato nel passaggio precedente. Manteniamo la versione predefinita.
Opzioni di acquisto e tipi di istanza — indichiamo i tipi di istanza per il cluster. Adhere to launch template utilizza il tipo di istanza dal Launch Template. Combine purchase options and instance types consente di configurare flessibilmente i tipi di istanza. Lo utilizzeremo.
Base On-Demand opzionale — il numero di istanze normali, non spot, che saranno sempre attive.
Percentuale On-Demand sopra la base — la proporzione percentuale tra istanze normali e spot, 50-50 distribuisce equamente, 20-80 per ogni istanza normale verranno sollevate 4 istanze spot. In questo esempio indicherò 50-50, ma nella realtà facciamo spesso 20-80 e, in alcuni casi, 0-100.
Tipi di istanza — qui puoi specificare tipi aggiuntivi di istanze che saranno utilizzati nel cluster. Non li abbiamo mai usati, perché non ne comprendo molto il significato. Potrebbe essere una questione di limiti per tipi specifici di istanze, ma possono essere aumentati facilmente attraverso il supporto. Se conosci un'applicazione, sarei felice di leggerne nei commenti)

Network global 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, scegli VPC e sottoreti per le macchine, nella maggior parte dei casi è consigliabile selezionare tutte le sottoreti disponibili.
Bilanciamento del carico — impostazioni del bilanciatore, ma lo faremo separatamente, qui non tocchiamo nulla. Controlli di salute saranno anche configurati più tardi.
Dimensione del gruppo — specifichiamo i limiti sul numero di macchine nel cluster e il numero desiderato di macchine all'avvio. Il numero di macchine nel cluster non diminuirà mai sotto il numero minimo specificato e non supererà il massimo, anche se le metriche richiederebbero un scaling.
Politiche di scaling — parametri di scaling, ma scaleremo in base ai task ECS in esecuzione, quindi configureremo lo scaling più tardi.
Protezione dallo scaling delle istanze — protezione delle istanze dalla cancellazione durante lo scaling verso il basso. Attiviamo questa opzione per evitare che l'ASG elimini una macchina su cui sono presenti task attivi. Disattivare la protezione per le istanze senza task sarà l'ECS Capacity Provider.
Aggiungi tag — puoi specificare tag per le istanze (per questo deve essere selezionata l'opzione Tag new instances). Ti consiglio di indicare il tag Nome, così tutte le istanze avviate all'interno del gruppo avranno lo stesso nome, facilitandone la visualizzazione nella console.

Dopo aver creato il gruppo, aprilo e vai alla sezione Configurazioni avanzate, perché in fase di creazione non sono visibili tutte le opzioni nella console.
Politiche di terminazione — regole considerate durante la cancellazione delle istanze. Vengono applicate in sequenza. Di solito utilizziamo quelle come nell'immagine qui sotto. Prima vengono eliminate 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 passarvi). Poi vengono selezionate le istanze più vicine all'ora di fatturazione successiva. E infine vengono scelte le più vecchie in base alla data di avvio.

È utile sapere: per aggiornare tutte le macchine nel cluster, è comodo utilizzare . Se combini questo con la funzione Lambda del passaggio precedente, avrai un sistema di aggiornamento completamente automatizzato per le istanze. Prima di aggiornare tutte le macchine, è necessario disattivare la protezione dallo scale-in per tutte le istanze nel gruppo. Non la configurazione nel gruppo, ma proprio la protezione delle macchine stesse, che si effettua 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, è possibile leggere il confronto tra i diversi tipi di bilanciatori su .
Listeners — ha senso impostare le porte 80 e 443 e fare un reindirizzamento da 80 a 443 tramite le regole del bilanciatore.
Availability Zones — nella maggior parte dei casi scegliamo tutte le zone di disponibilità.
Configura le impostazioni di sicurezza — qui si indica il certificato SSL per il bilanciatore, l'opzione più conveniente è in ACM. Si possono leggere le differenze Security Policy nel , si può lasciare quello predefinito ELBSecurityPolicy-2016-08. Dopo la creazione del bilanciatore, vedrai il suo nome DNS, per il quale è necessario impostare un CNAME per il tuo dominio. Ad esempio, ecco come appare in Cloudflare.

Gruppo di Sicurezza — creiamo o selezioniamo un gruppo di sicurezza per il bilanciatore, ho scritto più in alto su questo nel paragrafo EC2 Launch Template → Impostazioni di rete.
Gruppo target — creiamo un gruppo che gestisce il routing delle richieste dal bilanciatore alle macchine e ne verifica la disponibilità, in modo da sostituirle in caso di problemi. Tipo target deve essere Instance, Protocollo e Porta qualsiasi, se utilizzi HTTPS per la comunicazione tra il bilanciatore e le istanze, è necessario caricare il certificato su di esse. In questo esempio non lo faremo, lasceremo semplicemente la porta 80.
Controlli di salute — parametri di verifica della funzionalità del servizio. Nel servizio attuale dovrebbe essere una richiesta separata, che implementa parti importanti della logica di business. In questo esempio, lascerò le impostazioni predefinite. Successivamente, puoi scegliere l'intervallo delle richieste, il timeout, i codici delle risposte di successo, ecc. Nel nostro esempio indicheremo i codici di successo 200-399, poiché l'immagine Docker che verrà utilizzata restituisce il codice 304.

Registrare i Target — qui si scelgono le macchine per il gruppo, ma nel nostro caso ciò sarà gestito da ECS, quindi saltiamo semplicemente questo passaggio.
È utile sapere: a livello del bilanciatore puoi attivare i log, che verranno salvati in S3 in un file specifico . Da lì possono essere esportati in servizi esterni per l'analisi, oppure è possibile eseguire query SQL direttamente sui dati in S3 con . È comodo e funziona senza alcun codice aggiuntivo. Consiglio anche di impostare l'eliminazione dei log dal bucket S3 dopo un periodo di tempo definito.
Definizione del Compito ECS
Nei passaggi precedenti abbiamo creato tutto quello che riguarda l'infrastruttura del servizio, ora passiamo alla descrizione dei container che andremo a lanciare. Questo si fa nella sezione ECS → Definizioni dei Compiti.
Compatibilità del tipo di avvio — scegliamo EC2.
Ruolo IAM per l'esecuzione del compito — selezioniamo ecsTaskExecutionRole. Con questo vengono scritti i log, viene fornito accesso a variabili segrete, ecc.
Nella sezione Definizioni del Container facciamo clic su Aggiungi Container.
Immagine — link all'immagine con il codice del progetto, per questo esempio userò un'immagine pubblica da Docker Hub .
Limiti di Memoria — limiti della memoria per il container. Limite Rigido — limite rigido, se il container supera il valore specificato, verrà eseguita il comando docker kill, il container morirà immediatamente. Limite Morbido — limite morbido, il container può superare il valore specificato, ma questo parametro sarà preso in considerazione quando si pianificano i compiti sulle macchine. Ad esempio, se una macchina ha 4 GiB di RAM e il limite morbido del container è 2048 MiB, allora su quella macchina possono esserci al massimo 2 task attivi con questo container. In realtà, 4 GiB di RAM è un po' meno di 4096 MiB, questo può essere verificato nella scheda ECS Instances nel cluster. Il limite morbido non può essere maggiore del limite rigido. È importante capire che se in un task ci sono più container, i loro limiti si sommano.
Mappature delle porte — in Porta Host impostiamo 0, questo significa che la porta sarà assegnata dinamicamente, sarà monitorata dal Target Group. Porta del Container — la porta su cui gira la vostra applicazione, spesso è specificata nel comando di esecuzione, oppure viene assegnata nel codice della vostra applicazione, Dockerfile, ecc. Per il nostro esempio utilizziamo 3000, poiché è specificato nell' immagine utilizzata.
Controllo della salute — parametri per il controllo del funzionamento del container, da non confondere con quello impostato nel Target Group.
Ambiente — impostazioni dell'ambiente. unità CPU — sembra che sia simile ai limiti di memoria, ma riguarda la CPU. Ogni core della CPU equivale a 1024 unità, quindi se il server ha una CPU dual-core e il container ha un valore impostato a 512, possono essere eseguite 4 attività con quel container su uno stesso server. Le unità CPU corrispondono sempre al numero di core, non possono essere inferiori come nel caso della memoria.
Comando — comando per avviare il servizio all'interno del container, tutti i parametri sono separati da virgole. Può essere gunicorn, npm, ecc. Se non specificato, verrà utilizzato il valore della direttiva CMD dal Dockerfile. Indichiamo npm,start.
Variabili d'ambiente — variabili d'ambiente del container. Possono essere semplici dati testuali o variabili riservate da o .
Archiviazione e Registrazione — qui configureremo la registrazione su CloudWatch Logs (servizio di logging di AWS). Per farlo, basta abilitare l'opzione Auto-configure CloudWatch Logs. Dopo la creazione della Task Definition, verrà automaticamente creata un gruppo di log in CloudWatch. Per impostazione predefinita, i log vengono conservati indefinitamente, consiglio di cambiare il periodo di conservazione da Never Expire al termine desiderato. Questo si fa nel gruppo di log di CloudWatch, è necessario cliccare sul periodo attuale e scegliere il nuovo.

Cluster ECS e Provider di Capacità ECS
Andiamo alla sezione ECS → Clusters per creare un cluster. Come modello, scegliamo EC2 Linux + Networking.
Nome del cluster — molto importante, qui diamo lo stesso nome indicato nel Launch Template nel parametro ECS_CLUSTER, nel nostro caso — DemoApiClusterProd. Spuntiamo l'opzione Crea un cluster vuoto. Facoltativamente, è possibile abilitare Container Insights per monitorare 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 un nuovo. Ricordo che è necessario per gestire la creazione e lo spegnimento delle macchine in base al numero di attività ECS in esecuzione. È importante notare che il provider può essere collegato solo a un gruppo.
Auto Scaling group — scegliamo il gruppo creato in precedenza.
Scaling gestito — attiviamo per consentire al provider di scalare il servizio.
Capacità target % — quale percentuale di utilizzo delle macchine desideriamo per i task. Se impostiamo il 100%, tutte le macchine saranno sempre occupate da task attivi. Se impostiamo il 50%, la metà delle macchine sarà sempre libera. In questo caso, se si verifica un improvviso aumento del carico, i nuovi task verranno immediatamente assegnati alle macchine disponibili, senza dover aspettare il deployment delle istanze.
Protezione da terminazione gestita — attiviamo, questo parametro consente al fornitore di rimuovere la protezione delle istanze dalla cancellazione. Ciò avviene quando non ci sono task attivi sulla macchina e consente di rispettare la percentuale di capacità target.
Servizio ECS e impostazione della scalabilità
Ultimo passo :) Per creare un servizio, è necessario accedere al cluster precedentemente creato nella scheda Servizi.
Tipo di avvio — dobbiamo cliccare su Passa alla strategia del fornitore di capacità e selezionare i fornitori creati in precedenza.

Definizione del task — selezioniamo la Definizione del task creata in precedenza e la sua revisione.
Nome del servizio — per evitare confusioni, 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 di salute minima e Percentuale massima — definiscono il comportamento dei task durante il deployment. I valori predefiniti di 100 e 200 indicano che durante il deployment il numero di task aumenterà di un fattore, per poi tornare al desiderato. Se si utilizza 1 task, min=0 e max=100, esso verrà terminato durante il deployment e un nuovo task verrà avviato, quindi ci sarà un'interruzione. Se è attivo 1 task, min=50 e max=150, il deployment non avverrà affatto, poiché non è possibile dividere un task in due o aumentarlo di un fattore e mezzo.
Tipo di deployment — lasciamo Aggiornamento continuo.
Modelli di posizionamento — regole di posizionamento dei task sulle macchine. Per impostazione predefinita è impostato su AZ Balanced Spread - ciò significa che ogni nuovo task sarà collocato su una nuova istanza fino a quando non verranno attivate macchine in tutte le zone di disponibilità. Di solito utilizziamo BinPack - CPU e Spread - AZ, in questa politica i task vengono allocati il più densamente possibile su una macchina in base alla CPU. Quando è necessario creare una nuova macchina, essa viene creata in una nuova zona di disponibilità.

Tipo di bilanciatore di carico — selezioniamo il Bilanciatore di carico applicativo.
Ruolo IAM del servizio — selezioniamo ecsServiceRole.
Nome del bilanciatore di carico — selezioniamo il bilanciatore di carico creato in precedenza.
Periodo di grazia per il controllo di integrità — pausa prima di eseguire i controlli di integrità dopo il rilascio di un nuovo task, di solito impostiamo 60 secondi.
Contenitore da bilanciare — nel campo Nome gruppo target selezioniamo il gruppo creato in precedenza e tutto si compilerà automaticamente.

Auto Scaling del servizio — parametri di scaling del servizio. Selezioniamo Configura Auto Scaling del servizio per regolare il conteggio desiderato del tuo servizio. Impostiamo il numero minimo e massimo di task durante il scaling.
Ruolo IAM per Auto Scaling del servizio — selezioniamo AWSServiceRoleForApplicationAutoScaling_ECSService.
Politiche di scaling automatico dei task — regole per il scaling. Ci sono 2 tipi:
- Monitoraggio del target — monitoraggio di una 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 supera questa soglia, verranno aggiunti nuovi task fino a raggiungere il valore target. Se il carico è inferiore, i task verranno invece rimossi, a meno che non sia attivata la protezione dallo scaling verso il basso (Disabilita scaling verso il basso).
- Scaling a step — reazione a un evento casuale. Qui puoi impostare la risposta a qualsiasi evento (Allerta CloudWatch), quando si verifica, puoi aggiungere o rimuovere un numero specificato di task, oppure indicare un numero esatto di task.
Il servizio può avere più regole di scaling, il che può essere utile; è importante assicurarsi che non conflittino tra loro.
Conclusione
Se hai seguito le istruzioni e utilizzato la stessa immagine Docker, il tuo servizio dovrebbe restituire questa pagina.

- Abbiamo creato un modello secondo cui tutte le macchine nel servizio vengono avviate. Abbiamo anche imparato ad aggiornare le macchine quando il modello viene modificato.
- Abbiamo impostato la gestione del segnale di arresto per le istanze spot, quindi entro un minuto dalla ricezione, tutti i task in esecuzione vengono rimossi dalla macchina, in questo modo nulla viene perso o interrotto.
- Abbiamo avviato un bilanciatore di carico per distribuire uniformemente il carico tra le macchine.
- Abbiamo creato un servizio che funziona su istanze spot, riducendo così i costi delle macchine di circa 3 volte.
- Abbiamo configurato l'auto scaling in entrambe le direzioni per gestire l'aumento del carico, ma allo stesso tempo non pagare per inattività.
- Utilizziamo il Capacity Provider affinché l'applicazione gestisca l'infrastruttura (macchine) e non viceversa.
- Siamo dei bravi.
Se hai picchi di carico prevedibili, ad esempio, se fai pubblicità in una grande newsletter via email, puoi impostare lo scaling in base a .
È possibile anche eseguire la scalabilità basata sui dati provenienti da diverse parti del sistema. Ad esempio, abbiamo una funzionalità agli utenti dell'app mobile. A volte la campagna viene inviata a oltre 1 milione di persone. Dopo tale invio, si osserva sempre un grande aumento delle richieste all'API, poiché molti utenti accedono all'app contemporaneamente. Quindi, se vediamo che ci sono molte più richieste nella coda per l'invio di notifiche promozionali rispetto ai valori standard, possiamo immediatamente avviare diverse macchine e task aggiuntivi per essere pronti al carico.
Sarei felice se nei commenti condivideste interessanti casi d'uso delle istanze spot e ECS o qualcosa sulla scalabilità.
Presto ci saranno articoli su come gestiamo migliaia di eventi analitici al secondo su uno stack principalmente serverless (con risorse finanziarie) e su come è strutturato il deployment dei servizi tramite GitLab CI e Terraform Cloud.
Iscriviti a noi, sarà interessante!
Solo gli utenti registrati possono partecipare al sondaggio. , per favore.
Utilizzate le istanze spot in produzione?
22,2%Sì6
66,7%No18
11,1%Ne ho sentito parlare in un articolo, ho intenzione di utilizzarle
Hanno votato 27 utenti. Si sono astenuti 5 utenti.
Fonte: habr.com
