Amazon ECS - Comment redémarrez-vous toutes les tâches d'un service?


17

Nous avons une tâche qui charge certains fichiers de configuration à partir d'une source de données externe. Une fois les paramètres téléchargés, nous aimerions pouvoir redémarrer toutes les tâches d'un service afin que les paramètres se propagent à toutes les instances.

Quelle est la meilleure façon de redémarrer tous les services?

Nous avons une «solution de contournement» qui implique de définir le «nombre de tâches» à 0, puis de sauvegarder, mais ce n'est certainement pas la façon dont cela est censé être fait et il y a des temps d'arrêt.


PS: Si quelqu'un pouvait créer le tag amazon-ecs ce serait génial :)
Dennkster

Bon appel sur le tag, je l'ai ajouté pour toi.
ceejayoz

Ce document d'Amazon explique-t-il la solution de contournement que vous utilisez actuellement?
Matt

Réponses:


15

Utilisation de l'outil AWS CLI:

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

8

Ce que vous voulez faire est essentiellement le même que le redéploiement du service.

Pour redéployer le service sans interruption:

  1. Enregistrer une nouvelle définition de tâche basée sur la définition de tâche actuelle (avec les mêmes détails)
  2. Appelez UpdateService, en associant le service existant à la nouvelle définition de tâche.

Cela devrait lancer de nouvelles tâches pour la nouvelle définition de tâche, puis tuer les anciennes tâches pour l'ancienne définition de tâche, en redémarrant efficacement les tâches sans interruption.

Voir: UpdateService


1
J'avais besoin de le faire via la console AWS, et c'est le moyen le plus simple: vous pouvez gérer l'ensemble du processus manuellement si vous en avez besoin. Utile lorsque vous devez relancer rapidement toutes les tâches et ne pas avoir quelque chose de plus robuste configuré pour le processus - dans l'interface utilisateur, accédez à la définition de la tâche, créez une nouvelle révision, mettez à jour le service, puis après un peu de temps tous les Les tâches sont relancées!
geerlingguy

2
Ils ont ajouté une case à cocher à la mise à jour de service "Forcer le nouveau déploiement" qui vous permet d'ignorer l'étape 1 de votre processus.
Josh Vickery

Le commentaire sur l'option "Forcer le nouveau déploiement" était la réponse acceptée pour moi-même.
ecbrodie

3

cela a fonctionné pour moi:

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

les tâches sont ensuite recréées sur les mêmes instances.

si vous avez besoin de nouvelles instances, utilisez ceci:

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

Cette seconde semble faire autre chose que démarrer de nouvelles instances.
user130681

2

La tâche en tant que bloc de construction d'ECS peut être arrêtée par un appel StopTask . Le service est composé de tâches sous-jacentes qui peuvent être arrêtées avec le même appel d'API. Seule la partie manquante ici est foreach autour des résultats de l' appel ListTasks avec un paramètre de famille défini . J'ai écrit une fonction Lambda simple qui peut vous aider.


1

Je développe la réponse de @ user326608 ci-dessus (merci pour la perspicacité!).

Cela redémarrera TOUTES LES TÂCHES POUR TOUS LES SERVICES POUR UN GROUPE en arrêtant toutes ses tâches. Chaque service lancera alors automatiquement le Xnombre de nouvelles tâches, où Xest le service 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

Remarque: Si vous souhaitez redémarrer des tâches pour un seul service, forcez simplement un nouveau déploiement comme @Ben Whaley l'a décrit.
sudo soul

0

Sur la base de la documentation Amazon, il semble que vous devriez être en mesure de scripter les opérations en question à l'aide des appels de l'API UpdateService . Il y a quelques exemples de code disponibles sur le lien précédent, il semble possible que vous puissiez vous adapter. Il semble que l'écriture d'un script pour prendre en charge le rechargement des services à l'aide de la définition de tâche appropriée après les mises à jour des configurations de tâches serait la solution la plus élégante au problème.

Il y a plus de documentation sur l'utilisation d' AWS CLI avec ECS, ce qui semble être le moyen le plus simple de gérer les scripts par lots lors du redémarrage des services.


Je peux travailler sur l'écriture et la publication de la séquence de script / commande mais je n'ai pas actuellement accès à un compte AWS que je serais en mesure d'utiliser pour tester ce genre de chose, donc ce serait un brouillon / point de départ car je ne le ferais pas être en mesure de le tester efficacement ...
Matt


0

J'y travaille. Il serait très utile de pouvoir redémarrer une tâche à la fois de manière fiable. Le script ci-dessous est ce que j'utilise maintenant. C'est assez prudent. Vous devez appuyer sur Retour pour chaque tâche. Il existe une commande pour attendre que le service soit stable, mais cela ne signifie pas que la tâche est saine. Et je pourrais mettre un délai. Mais à la fin, si les choses tournent mal, le script tuerait lentement l'application. Donc...

#!/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

J'ai un script python boto3 qui fait le ff:

  1. créer une liste de tâches avec le statut 'RUNNING' pour un service via

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

  1. faire une boucle for pour la liste des tâches ci-dessus et arrêter chaque via

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

  1. décrire le service pour obtenir le RunningCount et le desireCount

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

  1. Boucle while si runningCount <desireCount - ce qui signifie qu'une tâche est actuellement en cours d'arrêt et n'a pas encore été remplacée, alors n'arrêtez pas encore la tâche suivante!

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

Si la boucle while n'est plus vraie - ce qui signifie que les nombres en cours d'exécution et souhaités sont égaux, arrêtez la tâche suivante dans la liste.

C'est le flux réel et je ne peux pas montrer le code réel car je suis toujours employé par mon travail actuel et tout mon code leur appartient :)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.