Amazon ECS - Como você reinicia todas as tarefas de um serviço?

16

Temos uma tarefa que carrega alguns arquivos de configuração de uma fonte de dados externa. Após o upload das configurações, gostaríamos de poder reiniciar todas as tarefas em um serviço para que as configurações sejam propagadas para todas as instâncias.

Qual é a melhor maneira de reiniciar todos os serviços?

Temos uma 'solução alternativa' que envolve definir o 'número de tarefas' como 0 e fazer backup, mas definitivamente não é assim que deve ser feito e tem tempo de inatividade.

Dennkster
fonte
PS: Se alguém pudesse criar a tag amazon-ecs, isso seria ótimo :) #
214 Dennkster
Boa chamada na etiqueta, eu adicionei para você.
ceejayoz
Este documento da Amazon explica a solução alternativa que você está usando atualmente?
Matt

Respostas:

15

Usando a ferramenta CLI da AWS:

aws ecs update-service --force-new-deployment --service my-service
Ben Whaley
fonte
7

O que você quer fazer é essencialmente o mesmo que reimplementar o Serviço.

Para reimplementar o serviço sem tempo de inatividade:

  1. Registre uma nova definição de tarefa com base na definição de tarefa atual (com os mesmos detalhes)
  2. Chame UpdateService, associando o serviço existente à nova definição de tarefa.

Isso deve iniciar novas tarefas para a nova definição de tarefa e, em seguida, eliminar as antigas tarefas para a antiga definição de tarefa, reiniciando efetivamente as tarefas sem tempo de inatividade.

Consulte: UpdateService

Matt Callanan
fonte
1
Eu precisava fazer isso por meio do console da AWS, e essa é a maneira mais fácil - você pode gerenciar todo o processo manualmente, se precisar. Útil quando você precisar reiniciar rapidamente todas as tarefas e não tiver algo mais robusto configurado para o processo - na interface do usuário, vá para a definição de Tarefas, crie uma nova revisão, atualize o serviço e depois de um tempo Tarefas são relançadas!
geerlingguy
2
Eles adicionaram uma caixa de seleção à atualização de serviço "Forçar nova implantação", que permite pular a etapa 1 do seu processo.
Josh Vickery
O comentário sobre a opção "Forças nova implantação" foi a Resposta Aceita para mim.
ecbrodie
3

isso funcionou para mim:

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

as tarefas são recriadas nas mesmas instâncias.

se você precisar de novas instâncias, use o seguinte:

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
fonte
Esse segundo parece fazer algo diferente de iniciar novas instâncias.
user130681
2

A tarefa como componente básico do ECS pode ser interrompida pela chamada StopTask . O serviço é composto de tarefas subjacentes que podem ser interrompidas com a mesma chamada de API. Somente a parte que falta aqui é foreach em torno dos resultados da chamada ListTasks com parâmetro de família definido Eu escrevi a função Lambda simples que pode ajudá-lo com isso.

s7anley
fonte
1

Estou expandindo a resposta de @ user326608 acima (obrigado pela compreensão!).

Isso reiniciará TODAS AS TAREFAS DE TODOS OS SERVIÇOS DE UM CLUSTER , interrompendo todas as suas tarefas. Cada serviço iniciará automaticamente o Xnúmero de novas tarefas, onde Xestá o serviço 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
fonte
Nota: Se você deseja reiniciar tarefas para um único serviço, basta forçar uma nova implantação, como o @Ben Whaley descreveu.
sudo soul
0

Com base na documentação da Amazon, parece que você deve conseguir criar um script das operações em questão usando as chamadas da API UpdateService . Existem alguns exemplos de código disponíveis no link anterior, parece possível que você possa se adaptar. Parece que escrever um script para recarregar os serviços usando a definição de tarefa apropriada após as atualizações nas configurações da tarefa seria a solução mais elegante para o problema.

Há mais documentação sobre o uso da CLI da AWS com ECS, que parece ser a maneira mais fácil de lidar com scripts em lote e a reinicialização de serviços.

Matt
fonte
Posso trabalhar para escrever e postar a sequência de scripts / comandos, mas atualmente não tenho acesso a uma conta da AWS que eu poderia usar para testar esse tipo de coisa; portanto, seria um rascunho / ponto de partida, pois eu não faria isso. ser capaz de testá-lo de forma eficaz ...
Matt
0

Eu tenho trabalhado nisso. Seria útil poder reiniciar uma tarefa por vez de maneira confiável. O script abaixo é o que estou usando agora. É muito cauteloso. Requer que você aperte return para cada tarefa. Há um comando para aguardar o serviço ser estável, mas isso não significa que a tarefa esteja íntegra. E eu poderia colocar um atraso de tempo. Mas, no final, se tudo der errado, o script acabaria matando o aplicativo lentamente. Então...

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

Eu tenho um script python boto3 que faz o ff:

  1. crie uma lista de tarefas com o status 'RUNNING' para um serviço via

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

  1. faça um loop for para a lista de tarefas acima e pare cada uma

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

  1. descreva o serviço para obter o runningCount e o desejadoCount

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

  1. while loop if runningCount <desejadoCount - o que significa que uma tarefa está sendo parada no momento e ainda não foi substituída, portanto, não pare a próxima tarefa ainda!

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

Se o loop while não for mais verdadeiro - o que significa que as contagens de execução e desejada são iguais, pare a próxima tarefa na lista.

Esse é o fluxo real e não consigo mostrar o código real, pois ainda estou empregado no meu trabalho atual e todo o meu código pertence a eles :)

pnocti
fonte