Amazon ECS - Jak zrestartować wszystkie zadania usługi?

18

Mamy zadanie, które ładuje niektóre pliki konfiguracyjne z zewnętrznego źródła danych. Po przesłaniu ustawień chcielibyśmy móc zrestartować wszystkie zadania w usłudze, aby ustawienia zostały rozpowszechnione we wszystkich instancjach.

Jaki jest najlepszy sposób na ponowne uruchomienie wszystkich usług?

Mamy „obejście” polegające na ustawieniu „liczby zadań” na 0, a następnie na wykonanie kopii zapasowej, ale zdecydowanie nie tak powinno się to robić i ma przestoje.

Dennkster
źródło
PS: Gdyby ktoś mógł utworzyć tag amazon-ecs, byłoby świetnie :)
Dennkster
Dobre wywołanie tagu, dodałem go dla ciebie.
ceejayoz
Czy ten dokument od Amazon wyjaśnia obejście, którego obecnie używasz?
Matt

Odpowiedzi:

16

Za pomocą narzędzia AWS CLI:

aws ecs update-service --force-new-deployment --service my-service
Ben Whaley
źródło
9

To, co chcesz zrobić, to w zasadzie to samo, co ponowne wdrożenie Usługi.

Aby ponownie wdrożyć usługę bez przestojów:

  1. Zarejestruj nową definicję zadania na podstawie bieżącej definicji zadania (z tymi samymi szczegółami)
  2. Zadzwoń do UpdateService, kojarząc istniejącą usługę z nową definicją zadania.

Powinno to uruchomić nowe zadania dla nowej definicji zadania, a następnie zabić stare zadania dla starej definicji zadania, skutecznie ponownie uruchamiając zadania bez przestoju.

Zobacz: UpdateService

Matt Callanan
źródło
1
Musiałem to zrobić za pomocą konsoli AWS i jest to najłatwiejszy sposób - w razie potrzeby możesz ręcznie zarządzać całym procesem. Przydaje się, gdy trzeba szybko ponownie uruchomić wszystkie zadania i nie skonfigurować bardziej niezawodnego procesu - w interfejsie użytkownika przejdź do definicji zadania, utwórz nową wersję, zaktualizuj usługę, a po pewnym czasie wszystkie Zadania zostały uruchomione ponownie!
geerlingguy,
2
Dodali pole wyboru do aktualizacji usługi „Wymuś nowe wdrożenie”, która pozwala pominąć krok 1 w procesie.
Josh Vickery
Komentowanie opcji „Wymuś nowe wdrożenie” było dla mnie odpowiedzią zaakceptowaną.
ecbrodie
3

to działało dla mnie:

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

zadania są następnie odtwarzane w tych samych instancjach.

jeśli potrzebujesz nowych instancji, użyj tego:

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
użytkownik326608
źródło
Ten drugi wydaje się robić coś innego niż uruchamianie nowych instancji.
user130681,
2

Zadanie jako element konstrukcyjny ECS można zatrzymać za pomocą wywołania StopTask . Usługa składa się z podstawowych zadań, które można zatrzymać za pomocą tego samego wywołania interfejsu API. Jedynie brakująca część jest tutaj wyświetlana wokół wyników wywołania ListTasks ze zdefiniowanym parametrem rodziny . Napisałem prostą funkcję Lambda, która może ci w tym pomóc.

s7anley
źródło
1

Rozwijam powyższą odpowiedź @ user326608 (dzięki za wgląd!).

Spowoduje to zrestartowanie WSZYSTKICH ZADAŃ DLA WSZYSTKICH USŁUG DLA Klastra poprzez zatrzymanie wszystkich jego zadań. Następnie każda usługa automatycznie uruchomi Xliczbę nowych zadań, gdzie Xjest usługa 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
dusza sudo
źródło
Uwaga: Jeśli chcesz zrestartować zadania dla pojedynczej usługi, po prostu wymuś nowe wdrożenie, jak opisano w @Ben Whaley.
sudo soul
0

W oparciu o dokumentację Amazon wydaje się, że powinieneś być w stanie napisać odpowiednie operacje za pomocą wywołań API UpdateService . Istnieje kilka przykładów kodu dostępnych pod poprzednim linkiem, wydaje się możliwe, że powinieneś być w stanie się dostosować. Wygląda na to, że napisanie skryptu, który zajmie się przeładowaniem usług przy użyciu odpowiedniej definicji zadania, po tym jak aktualizacje konfiguracji zadań będą najbardziej eleganckim rozwiązaniem problemu.

Jest więcej dokumentacji na temat używania AWS CLI z ECS, która wydaje się być najłatwiejszym sposobem radzenia sobie ze wsadowym skryptowaniem ponownego uruchamiania usług.

Matt
źródło
Mogę pracować nad pisaniem i publikowaniem sekwencji skryptów / poleceń, ale obecnie nie mam dostępu do konta AWS, którego mógłbym użyć do testowania tego rodzaju rzeczy, więc byłby to wstępny szkic / punkt wyjścia, ponieważ nie chciałbym być w stanie skutecznie to przetestować ...
Matt
0

Pracowałem nad tym. Byłoby bardzo przydatne, aby móc ponownie uruchomić jedno zadanie na raz. Poniższy skrypt jest tym, którego teraz używam. To jest dość ostrożne. Wymaga ci powrotu za każde zadanie. Istnieje polecenie czekające na stabilizację usługi, ale nie oznacza to, że zadanie jest prawidłowe. I mógłbym wprowadzić opóźnienie czasowe. Ale w końcu, jeśli coś pójdzie nie tak, skrypt po prostu powoli zabije aplikację. Więc...

#!/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
użytkownik130681
źródło
0

Mam skrypt boto3 python, który wykonuje FF:

  1. utwórz listę zadań ze statusem „URUCHOMIENIE” dla usługi za pośrednictwem

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

  1. wykonaj pętlę for dla powyższej listy zadań i zatrzymaj każde za pomocą

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

  1. opisz usługę, aby uzyskać bieżącą liczbę i żądaną liczbę

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

  1. pętla while, jeśli runningCount <pożądana liczba - co oznacza, że ​​zadanie jest aktualnie zatrzymywane i nie zostało jeszcze zastąpione, więc nie zatrzymuj jeszcze następnego zadania!

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

Jeśli pętla while nie jest już prawdziwa - co oznacza, że ​​liczba uruchomień i żądanych jest równa, zatrzymaj następne zadanie na liście.

To jest rzeczywisty przepływ i nie jestem w stanie wyświetlić rzeczywistego kodu, ponieważ wciąż jestem zatrudniony w mojej obecnej pracy i cały mój kod należy do nich :)

pnocti
źródło