web-dev-qa-db-fra.com

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

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.

18
Dennkster

Utilisation de l'outil AWS CLI:

aws ecs update-service --force-new-deployment --service my-service
16
Ben Whaley

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: pdateService

9
Matt Callanan

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
3
user326608

La tâche en tant que bloc de construction d'ECS peut être arrêtée par StopTask appel. 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 pour chaque résultat autour de ListTasks appel avec le paramètre family défini. J'ai écrit simple fonction Lambda qui peut vous aider.

2
s7anley

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 CLUSTER en arrêtant toutes ses tâches. Chaque service lancera alors automatiquement X nombre de nouvelles tâches, où X est le desired task count Du service.

#!/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
1
sudo soul

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 :)

0
pnocti

Sur la base de la documentation d'Amazon, il semble que vous devriez être en mesure de scripter les opérations en question à l'aide de appels 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 qu'écrire 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 de AWS CLI avec ECS qui semble être la façon la plus simple de gérer les scripts batch pour le redémarrage des services.

0
Matt

Fonctionne très bien https://github.com/fdfk/ecsServiceRestart

python ecsServiceRestart.py restart --services="app app2" --cluster=test
0
user8458170

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 au final, 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
user130681