Amazon ECS - Wie können Sie alle Aufgaben eines Dienstes neu starten?

14

Wir haben eine Aufgabe, die einige Konfigurationsdateien von einer externen Datenquelle lädt. Nach dem Hochladen der Einstellungen möchten wir in der Lage sein, alle Aufgaben in einem Dienst neu zu starten, damit die Einstellungen auf alle Instanzen übertragen werden.

Was ist der beste Weg, um alle Dienste neu zu starten?

Wir haben eine "Problemumgehung", bei der die "Anzahl der Aufgaben" auf 0 gesetzt und dann gesichert wird. Dies ist jedoch definitiv nicht die Vorgehensweise und hat Ausfallzeiten.

Dennkster
quelle
PS: Wenn jemand das Tag amazon-ecs erstellen könnte, wäre das großartig :)
Dennkster
Guter Anruf auf dem Tag, ich habe es für dich hinzugefügt.
Ceejayoz
Erklärt dieses Dokument von Amazon die Problemumgehung, die Sie derzeit verwenden?
Matt

Antworten:

14

Verwenden des AWS CLI-Tools:

aws ecs update-service --force-new-deployment --service my-service
Ben Whaley
quelle
6

Was Sie tun möchten, entspricht im Wesentlichen der erneuten Bereitstellung des Dienstes.

So stellen Sie den Dienst ohne Ausfallzeiten erneut bereit:

  1. Registrieren Sie eine neue Aufgabendefinition basierend auf der aktuellen Aufgabendefinition (mit denselben Details).
  2. Rufen Sie UpdateService auf und verknüpfen Sie den vorhandenen Service mit der neuen Aufgabendefinition.

Dies sollte neue Aufgaben für die neue Aufgabendefinition starten und dann die alten Aufgaben für die alte Aufgabendefinition beenden, wodurch die Aufgaben ohne Ausfallzeiten effektiv neu gestartet werden.

Siehe: UpdateService

Matt Callanan
quelle
1
Ich musste dies über die AWS-Konsole tun, und dies ist der einfachste Weg - Sie können den gesamten Prozess bei Bedarf manuell verwalten. Hilfreich, wenn Sie alle Aufgaben schnell neu starten müssen und keine robustere Einrichtung für den Prozess haben müssen. Gehen Sie in der Benutzeroberfläche zur Aufgabendefinition, erstellen Sie eine neue Revision, aktualisieren Sie den Dienst und nach einiger Zeit alle Aufgaben werden neu gestartet!
Geerlingguy
2
Sie haben dem Service-Update "Neue Bereitstellung erzwingen" ein Kontrollkästchen hinzugefügt, mit dem Sie Schritt 1 in Ihrem Prozess überspringen können.
Josh Vickery
Der Kommentar zur Option "Neue Bereitstellung erzwingen" war für mich die akzeptierte Antwort.
Ecbrodie
3

das hat bei mir funktioniert:

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

Die Aufgaben werden dann auf denselben Instanzen neu erstellt.

Wenn Sie neue Instanzen benötigen, verwenden Sie Folgendes:

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
user326608
quelle
Dieser zweite scheint etwas anderes zu tun, als neue Instanzen zu starten.
user130681
2

Die Aufgabe als Baustein von ECS kann durch einen StopTask- Aufruf gestoppt werden . Der Dienst besteht aus zugrunde liegenden Aufgaben, die mit demselben API-Aufruf gestoppt werden können. Hier fehlt nur ein Teil der Ergebnisse des ListTasks- Aufrufs mit definierten Familienparametern . Ich habe eine einfache Lambda-Funktion geschrieben, die Ihnen dabei helfen kann.

s7anley
quelle
1

Ich erweitere die Antwort von @ user326608 oben (danke für den Einblick!).

Dadurch werden ALLE AUFGABEN FÜR ALLE DIENSTLEISTUNGEN FÜR EINEN CLUSTER neu gestartet, indem alle seine Aufgaben gestoppt werden. Jeder Dienst startet dann automatisch die XAnzahl der neuen Aufgaben, wo Xsich die Dienste befinden 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
Sudo Seele
quelle
Hinweis: Wenn Sie Aufgaben für einen einzelnen Dienst neu starten möchten, erzwingen Sie einfach eine neue Bereitstellung, wie von @Ben Whaley beschrieben.
Sudo Soul
0

Basierend auf der Amazon-Dokumentation sollten Sie in der Lage sein, die fraglichen Vorgänge mithilfe der UpdateService-API-Aufrufe zu skripten . Unter dem vorherigen Link sind einige Codebeispiele verfügbar. Möglicherweise sollten Sie sich anpassen können. Es scheint, als wäre das Schreiben eines Skripts zum erneuten Laden der Dienste mithilfe der entsprechenden Aufgabendefinition nach den Aktualisierungen der Aufgabenkonfigurationen die eleganteste Lösung für das Problem.

Es gibt weitere Dokumentationen zur Verwendung von AWS CLI mit ECS, die anscheinend der einfachste Weg sind, mit Batch-Skripten beim Neustart von Diensten umzugehen.

Matt
quelle
Ich kann am Schreiben und Veröffentlichen der Skript- / Befehlssequenz arbeiten, habe jedoch derzeit keinen Zugriff auf ein AWS-Konto, das ich zum Testen dieser Art von Dingen verwenden könnte. Daher wäre dies ein grober Entwurf / Ausgangspunkt, da ich dies nicht tun würde in der Lage sein, es effektiv zu testen ...
Matt
0

Ich habe daran gearbeitet. Es wäre sehr nützlich, wenn Sie jeweils eine Aufgabe zuverlässig neu starten könnten. Das folgende Skript verwende ich jetzt. Es ist ziemlich vorsichtig. Erfordert, dass Sie für jede Aufgabe die Eingabetaste drücken. Es gibt einen Befehl, der darauf wartet, dass der Dienst stabil ist. Dies bedeutet jedoch nicht, dass die Aufgabe fehlerfrei ist. Und ich könnte eine Zeitverzögerung setzen. Aber am Ende, wenn die Dinge schlecht laufen, würde das Skript die App nur langsam beenden. So...

#!/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
user130681
quelle
0

Ich habe ein Python Boto3-Skript, das die folgenden Funktionen ausführt:

  1. Erstellen Sie eine Liste von Aufgaben mit dem Status 'RUNNING' für einen Dienst über

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

  1. Führen Sie eine for-Schleife für die Liste der oben genannten Aufgaben aus und stoppen Sie jede via

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

  1. Beschreiben Sie den Dienst, um den runningCount und den gewünschtenCount abzurufen

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

  1. while-Schleife, wenn runningCount <gewünschterCount - bedeutet, dass eine Aufgabe gerade gestoppt wird und noch nicht ersetzt wurde. Stoppen Sie also die nächste Aufgabe noch nicht!

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

Wenn die while-Schleife nicht mehr wahr ist - was bedeutet, dass sowohl die laufende als auch die gewünschte Anzahl gleich sind, stoppen Sie die nächste Aufgabe in der Liste.

Dies ist der tatsächliche Ablauf und ich kann den tatsächlichen Code nicht anzeigen, da ich noch bei meinem aktuellen Job beschäftigt bin und mein gesamter Code zu ihnen gehört :)

pnocti
quelle