Amazon ECS: ¿cómo reinicia todas las tareas de un servicio?

17

Tenemos una tarea que carga algunos archivos de configuración de una fuente de datos externa. Después de cargar la configuración, nos gustaría poder reiniciar todas las tareas en un servicio para que la configuración se propague a todas las instancias.

¿Cuál es la mejor manera de reiniciar todos los servicios?

Tenemos una 'solución' que implica establecer el 'número de tareas' en 0 y luego hacer una copia de seguridad, pero definitivamente no es así como se supone que debe hacerse y tiene tiempo de inactividad.

Dennkster
fuente
PD: Si alguien pudiera crear la etiqueta amazon-ecs sería genial :)
Dennkster
Buena llamada en la etiqueta, la agregué por ti.
ceejayoz
¿Este documento de Amazon explica la solución que está utilizando actualmente?
Matt

Respuestas:

15

Usando la herramienta AWS CLI:

aws ecs update-service --force-new-deployment --service my-service
Ben Whaley
fuente
8

Lo que desea hacer es esencialmente lo mismo que volver a implementar el Servicio.

Para volver a implementar el servicio sin tiempo de inactividad:

  1. Registre una nueva definición de tarea basada en la definición de tarea actual (con los mismos detalles)
  2. Llame a UpdateService, asociando el Servicio existente con la nueva Definición de tarea.

Esto debería lanzar nuevas tareas para la nueva definición de tarea y luego eliminar las viejas tareas para la antigua definición de tarea, reiniciando efectivamente las tareas sin tiempo de inactividad.

Ver: UpdateService

Matt Callanan
fuente
1
Necesitaba hacer esto a través de la consola de AWS, y esta es la forma más fácil: puede administrar todo el proceso manualmente si lo necesita. Útil cuando necesita relanzar rápidamente todas las tareas y no tiene algo más sólido configurado para el proceso: en la interfaz de usuario, vaya a la definición de Tarea, cree una nueva revisión, actualice el servicio y luego, después de un poco de tiempo, todo el ¡Se relanzan las tareas!
geerlingguy
2
Han agregado una casilla de verificación a la actualización del servicio "Forzar nueva implementación" que le permite omitir el paso 1 en su proceso.
Josh Vickery
El comentario sobre la opción "Forzar nuevo despliegue" fue la Respuesta aceptada para mí.
ecbrodie
3

esto funcionó para mí:

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

las tareas luego se recrean en las mismas instancias.

si necesita nuevas instancias, use esto:

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
usuario326608
fuente
Ese segundo parece hacer algo más que comenzar nuevas instancias.
user130681
2

La tarea como bloque de construcción de ECS se puede detener mediante la llamada StopTask . El servicio se compone de tareas subyacentes que se pueden detener con la misma llamada API. Aquí solo falta parte de los resultados de la llamada ListTasks con el parámetro de familia definido . Escribí una función simple de Lambda que puede ayudarte con esto.

s7anley
fuente
1

Estoy ampliando la respuesta de @ user326608 anterior (¡gracias por la información!).

Esto reiniciará TODAS LAS TAREAS DE TODOS LOS SERVICIOS PARA UN CLÚSTER al detener todas sus tareas. Cada servicio lanzará automáticamente una Xcantidad de tareas nuevas, donde se Xencuentra el servicio 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
alma sudo
fuente
Nota: Si desea reiniciar tareas para un solo servicio, simplemente fuerce una nueva implementación como lo ha descrito @Ben Whaley.
sudo soul
0

Según la documentación de Amazon, parece que debería poder realizar un script de las operaciones en cuestión utilizando las llamadas a la API UpdateService . Hay algunos ejemplos de código disponibles en el enlace anterior, parece posible que pueda adaptarse. Parece que escribir un script para encargarse de volver a cargar los servicios utilizando la definición de tarea adecuada después de que las actualizaciones de las configuraciones de la tarea serían la solución más elegante para el problema.

Hay más documentación sobre el uso de AWS CLI con ECS, que parece ser la forma más fácil de lidiar con la secuencia de comandos por lotes para reiniciar los servicios.

Mate
fuente
Puedo trabajar en escribir y publicar la secuencia de comandos / comandos, pero actualmente no tengo acceso a una cuenta de AWS que podría usar para probar este tipo de cosas, por lo que sería un borrador / punto de partida ya que no ser capaz de probarlo efectivamente ...
Matt
0

He estado trabajando en esto. Sería bastante útil poder reiniciar una tarea a la vez de manera confiable. El siguiente script es lo que estoy usando ahora. Es muy cauteloso. Requiere que pulses volver para cada tarea. Hay un comando para esperar a que el servicio sea estable, pero eso no significa que la tarea sea correcta. Y pude poner un retraso de tiempo. Pero al final, si las cosas van mal, el script simplemente mataría lentamente la aplicación. Entonces...

#!/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
usuario130681
fuente
0

Tengo un script python boto3 que hace el ff:

  1. crear una lista de tareas con el estado 'EN EJECUCIÓN' para un servicio a través de

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

  1. haga un bucle for para la lista de tareas anteriores y detenga cada vía

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

  1. describa el servicio para obtener el runningCount y el deseadoCount

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

  1. while loop si runningCount <deseadoCount - lo que significa que una tarea se está deteniendo actualmente y aún no se ha reemplazado, ¡así que no dejes la siguiente tarea todavía!

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

Si el ciclo while ya no es verdadero, lo que significa que tanto el conteo en ejecución como el deseado son iguales, detenga la siguiente tarea en la lista.

Este es el flujo real y no puedo mostrar el código real, ya que todavía estoy empleado en mi trabajo actual y todo mi código les pertenece :)

pnocti
fuente