В настоящее время я пытаюсь настроить простой CI, который перестроит мой проект, создаст новый образ докера, переместит новый образ в хранилище amazon ecr, создаст новую ревизию существующего определения задачи с последним образом докера, обновит запустить службу с новой ревизией определения задачи и, наконец, остановить существующую задачу, на которой выполняется старая ревизия, и запустить одну, на которой выполняется новая ревизия.
Все работает нормально, кроме запуска новой ревизии задачи.
Из скрипта bash последняя команда, которую я вызываю:
aws ecs update-service --cluster "$CLUSTER" --service "$SERVICE" --task-definition "$TASK_DEFINITION":"$REVISION"
Это приводит к ошибке события:
(service rj-api-service) was unable to place a task because no container instance met all of its requirements. The closest matching (container-instance bbbc23d5-1a09-45e7-b344-e68cc408e683) is already using a port required by your task.
И это имеет смысл, потому что контейнер, который я заменяю, точно такой же, как и новый, и будет работать на том же порту, он просто содержит последнюю версию моего приложения.
У меня сложилось впечатление, что команда update-service
остановит существующую задачу и запустит новую, но похоже, что сначала она запускает новую, а в случае успеха останавливает старую.
Какова лучшая практика для обработки этого? Должен ли я сначала остановить старую задачу? Должен ли я сначала удалить службу в моем сценарии и заново создавать всю службу при каждом обновлении?
В настоящее время мне нужен только 1 экземпляр выполняемой задачи, но я не хочу включать себя, если мне нужно это, чтобы иметь возможность автоматического масштабирования до нескольких экземпляров. Любые предложения о том, как решить эту проблему?
3 ответа
Вы можете начать новую редакцию задач с помощью следующих шагов, используя скрипт оболочки в вашей среде сборки.
Сохраните шаблон json определения задач в своем создать среду в файле (например, файл шаблона -
web-server.json
, а семейство определений задач -web-server
).Использовать каталог файлов в качестве текущего каталога и выполнить определение задачи реестра (происходит при первом запуске, если не существует)
aws ecs register-task-definition --cli-input-json file://web-server.json
Получить идентификатор запущенной задачи (TASK_ID) для переменной в сценарии оболочки.
TASK_ID=`aws ecs list-tasks --cluster default --desired-status RUNNING --family web-server | egrep "task" | tr "/" " " | tr "[" " " | awk '{print $2}' | sed 's/"$//'`
Получить ревизию задачи (TASK_REVISION) для переменных в сценарии оболочки.
TASK_REVISION=`aws ecs describe-task-definition --task-definition web-server | egrep "revision" | tr "/" " " | awk '{print $2}' | sed 's/"$//'`
Остановить текущую задачу
aws ecs stop-task --cluster default --task ${TASK_ID}
Немедленно начать новое задание
aws ecs update-service --cluster default --service web-server --task-definition web-server:${TASK_REVISION} --desired-count 1
Рекомендуется сохранять минимум желаемого количества для 2 задач (две задачи, выполняющиеся внутри службы) и выполнять непрерывные обновления (обновлять по одной задаче за раз), используя следующий скрипт (расширение вышеуказанных шагов для нескольких контейнеров) с нулем. время простоя (убедитесь, что у вас достаточно времени после первых обновлений контейнера, например, сна 30, чтобы он был готов принимать новые запросы).
cd /<directory-containing-web-server.json>
aws ecs register-task-definition --cli-input-json file://web-server.json
OLD_TASK_ID=`aws ecs list-tasks --cluster default --desired-status RUNNING --family web-server | egrep "task" | tr "/" " " | tr "[" " " | awk '{print $2}' | sed 's/"$//'`
TASK_REVISION=`aws ecs describe-task-definition --task-definition web-server | egrep "revision" | tr "/" " " | awk '{print $2}' | sed 's/"$//'`
aws ecs stop-task --cluster default --task ${OLD_TASK_ID}
OLD_TASK_ID=`aws ecs list-tasks --cluster default --desired-status RUNNING --family web-server | egrep "task" | tr "/" " " | tr "[" " " | awk '{print $2}' | sed 's/"$//'`
aws ecs update-service --cluster default --service web-server --task-definition web-server:${TASK_REVISION} --desired-count 1
sleep 30
aws ecs stop-task --task ${OLD_TASK_ID}
aws ecs update-service --cluster default --service web-server --task-definition web-server:${TASK_REVISION} --desired-count 2
Примечание. Необходимо соответствующим образом настроить семейство определений задач, число экземпляров и шаблон определения задач.
Так что теперь у меня это работает.
После того как я вызвал aws ecs update service
с новым определением задачи, я вызываю aws ecs list-tasks
и затем запускаю 'aws stop task' для каждой запущенной задачи службы. Поскольку желаемое количество для службы равно 1, оно немедленно пытается запустить резервное копирование задач и использует новое определение службы.
Это не очень красиво, но, похоже, пока работает достаточно хорошо.
Чтобы обновить определение задачи в «задачах», запущенных в сервисе, необходимо удалить задачи и запустить новую задачу.
Таким образом, я решаю проблему обновления определения задач в задачах.
Я написал следующий код:
# Register a new Task definition
aws ecs register-task-definition --family testing-cluster --cli-input-json file://scripts/taskdefinition/testingtaskdef.json --region $AWS_REGION
# Update Service in the Cluster
aws ecs update-service --cluster $CLUSTER_NAME --service $SERVICE --task-definition testing-cluster --desired-count 1 --region $AWS_REGION
DECRIBED_SERVICE=$(aws ecs describe-services --region $AWS_REGION --cluster $CLUSTER_NAME --services $SERVICE);
CURRENT_DESIRED_COUNT=$(echo $DECRIBED_SERVICE | jq --raw-output ".services[0].desiredCount")
# - echo $CURRENT_DESIRED_COUNT
CURRENT_TASK_REVISION=$(echo $DECRIBED_SERVICE | jq -r ".services[0].taskDefinition")
echo "Current Task definition in Service" + $CURRENT_TASK_REVISION
CURRENT_RUNNING_TASK=$(echo $DECRIBED_SERVICE | jq -r ".services[0].runningCount")
echo $CURRENT_RUNNING_TASK
CURRENT_STALE_TASK=$(echo $DECRIBED_SERVICE | jq -r ".services[0].deployments | .[] | select(.taskDefinition != \"$CURRENT_TASK_REVISION\") | .taskDefinition")
echo "Task defn apart from current service Taskdefn" + $CURRENT_STALE_TASK
# - echo $CURRENT_STALE_TASK
tasks=$(aws ecs --region $AWS_REGION list-tasks --cluster $CLUSTER_NAME | jq -r '.taskArns | map(.[40:]) | reduce .[] as $item (""; . + $item + " ")')
echo "Tasks are as follows"
echo $tasks
TASKS=$(aws ecs --region $AWS_REGION describe-tasks --cluster $CLUSTER_NAME --task $tasks);
# - echo $TASKS
OLDER_TASK=$(echo $TASKS | jq -r ".tasks[] | select(.taskDefinitionArn!= \"$CURRENT_TASK_REVISION\") | .taskArn | split(\"/\") | .[1] ")
echo "Older Task running " + $OLDER_TASK
for old_task in $OLDER_TASK; do
aws ecs --region us-east-1 stop-task --cluster $CLUSTER_NAME --task $old_task
done
# Run new tasks with the updated new Task-definition
aws ecs --region $AWS_REGION run-task --cluster $CLUSTER_NAME --task-definition $CURRENT_TASK_REVISION
Похожие вопросы
Новые вопросы
amazon-web-services
Amazon Web Services (AWS) - это общедоступное облако: IaaS (инфраструктура как услуга) и SaaS (программное обеспечение как услуга), предоставляемые Amazon. Вопросы по программированию и архитектуре находятся по теме. Общую справку по серверу можно получить по адресу https://serverfault.com. Тег AWS редко используется отдельно и обычно используется вместе с другими тегами, чтобы более четко определить тему вопроса.