Amazon ECS - Come si riavvia tutte le attività di un servizio?


17

Abbiamo un'attività che carica alcuni file di configurazione da un'origine dati esterna. Dopo aver caricato le impostazioni, vorremmo essere in grado di riavviare tutte le attività in un servizio in modo che le impostazioni si propaghino a tutte le istanze.

Qual è il modo migliore per riavviare tutti i servizi?

Abbiamo una "soluzione alternativa" che comporta l'impostazione del "numero di attività" su 0 e quindi il backup, ma questo non è sicuramente come dovrebbe essere fatto e ha tempi di inattività.


PS: Se qualcuno potesse creare il tag amazon-ecs sarebbe fantastico :)
Dennkster

Buona chiamata sul tag, l'ho aggiunto per te.
Ceejayoz,

Questo documento di Amazon spiega la soluzione alternativa che stai attualmente utilizzando?
Matt,

Risposte:


15

Utilizzando lo strumento CLI AWS:

aws ecs update-service --force-new-deployment --service my-service

8

Quello che vuoi fare è essenzialmente lo stesso della ridistribuzione del servizio.

Per ridistribuire il servizio senza tempi di inattività:

  1. Registrare una nuova definizione di attività in base alla definizione di attività corrente (con gli stessi dettagli)
  2. Chiama UpdateService, associando il Servizio esistente alla nuova Definizione attività.

Ciò dovrebbe avviare nuove attività per la nuova definizione di attività e quindi terminare le attività precedenti per la definizione di attività precedente, riavviando efficacemente le attività senza tempi di inattività.

Vedi: UpdateService


1
Avevo bisogno di farlo tramite la Console AWS, e questo è il modo più semplice: puoi gestire l'intero processo manualmente, se necessario. Utile quando devi riavviare rapidamente tutte le attività e non hai qualcosa di più robusto impostato per il processo: nell'interfaccia utente, vai alla definizione dell'attività, crea una nuova revisione, aggiorna il servizio, quindi dopo un po 'di tempo tutti i Le attività vengono riavviate!
geerlingguy,

2
Hanno aggiunto una casella di spunta all'aggiornamento del servizio "Forza nuova distribuzione" che consente di saltare il passaggio 1 del processo.
Josh Vickery,

Il commento sull'opzione "Forza nuova distribuzione" è stata la risposta accettata per me stesso.
ecbrodie,

3

questo ha funzionato per me:

aws ecs list-tasks --cluster <cluster_name> | jq -r ".taskArns[]" | awk '{print "aws ecs stop-task --cluster <cluster_name> --task \""$0"\""}' | sh

le attività vengono quindi ricreate nelle stesse istanze.

se hai bisogno di nuove istanze, usa questo:

aws ecs list-services --cluster <cluster_name> | jq -r ".serviceArns[]" | awk '{print "aws ecs update-service --cluster <cluster_name> --force-new-deployment  --service \""$0"\""}' | sh

La seconda sembra fare qualcosa di diverso dall'avvio di nuove istanze.
user130681

2

L'attività come blocco predefinito di ECS può essere interrotta dalla chiamata StopTask . Il servizio è composto da attività sottostanti che possono essere arrestate con la stessa chiamata API. Solo la parte mancante qui è foreach intorno ai risultati della chiamata ListTasks con il parametro della famiglia definito . Ho scritto una semplice funzione Lambda che può aiutarti in questo.


1

Sto espandendo la risposta di @ user326608 sopra (grazie per la comprensione!).

Ciò riavvierà TUTTI I COMPITI PER TUTTI I SERVIZI PER UN CLUSTER interrompendo tutte le sue attività. Ogni servizio avvierà quindi automaticamente il Xnumero di nuove attività, dov'è Xil servizio desired task count.

#!/bin/bash

index=0
taskArn=$(aws ecs list-tasks --cluster ${CLUSTER_NAME} --query "taskArns[${index}]" --output text)

until [ "$taskArn" = "None" ]
do 
  aws ecs stop-task --cluster ${CLUSTER_NAME} --task $taskArn
  ((index++))
  taskArn=$(aws ecs list-tasks --cluster ${CLUSTER_NAME} --query "taskArns[${index}]" --output text)
done

Nota: se si desidera riavviare le attività per un singolo servizio, forzare semplicemente una nuova distribuzione come descritto da @Ben Whaley.
Sudo Soul,

0

Sulla base della documentazione di Amazon sembra che dovresti essere in grado di eseguire lo script delle operazioni in questione utilizzando le chiamate API UpdateService . Ci sono alcuni esempi di codice disponibili al link precedente, sembra che tu possa adattarti. Sembra che scrivere uno script per occuparsi di ricaricare i servizi usando la definizione di attività appropriata dopo che gli aggiornamenti delle configurazioni delle attività siano la soluzione più elegante al problema.

Esiste più documentazione sull'uso della CLI AWS con ECS che sembra essere il modo più semplice per gestire gli script batch e il riavvio dei servizi.


Posso lavorare sulla scrittura e la pubblicazione della sequenza di script / comandi ma al momento non ho accesso a un account AWS che sarei in grado di utilizzare per testare questo genere di cose, quindi sarebbe una bozza / punto di partenza poiché non lo farei essere in grado di testarlo efficacemente ...
Matt


0

Ci ho lavorato. Sarebbe piuttosto utile poter riavviare un'attività alla volta in modo affidabile. Lo script qui sotto è quello che sto usando ora. È abbastanza cauto. Richiede il ritorno a colpire per ogni attività. Esiste un comando per attendere che il servizio sia stabile, ma ciò non significa che l'attività sia integra. E potrei ritardare. Ma alla fine se le cose vanno male, lo script ucciderebbe lentamente l'app. Così...

#!/bin/bash

if [ $# -eq 2 ]
then
    cluster=$1
    service=$2
else
    echo "Usage: $0 <cluster> <service>"
    exit 1
fi

echo
echo "Restarting $cluster $service tasks:"
echo

for task in $(aws ecs list-tasks --cluster $cluster --service-name $service | awk '{print $2}')
do
    echo
    echo -n "Press enter to stop $task"
    read -r
    echo
    echo "stopping $task..."
    aws ecs stop-task --cluster "$cluster" --task "$task"
    echo
    # aws ecs wait services-stable --cluster "$cluster" --services "$service"    done

0

Ho uno script Python Boto3 che fa il ff:

  1. creare un elenco di attività con stato 'RUNNING' per un servizio tramite

ecs_client.list_tasks(cluster=mycluster,serviceName=myservice,desiredStatus='RUNNING')

  1. fare un ciclo for per l'elenco delle attività sopra e interrompere ciascuna via

ecs_client.stop_task(cluster=mycluster,task=mytask)

  1. descrivere il servizio per ottenere runningCount e desideratoCount

ecs_client.describe_services(cluster=mycluster,services=[myservice])

  1. while loop if runningCount <wishCount - significa che un'attività è attualmente in fase di arresto e non è stata ancora sostituita, quindi non interrompere ancora l'attività successiva!

while myservice['services'][0]['runningCount'] < myservice['services'][0]['desiredCount']:

Se il ciclo while non è più vero, il che significa che sia i conteggi in esecuzione che quelli desiderati sono uguali, interrompere l'attività successiva nell'elenco.

Questo è il flusso effettivo e non riesco a mostrare il codice attuale poiché sono ancora impiegato dal mio lavoro attuale e tutto il mio codice appartiene a loro :)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.