В настоящее время я использую Fargate на Amazon ECS. В моей настройке есть определение задачи, которое включает в себя два контейнера:
Selenium-hub
).Я хочу следующее поведение:
Однако у меня возникла проблема с тем, как ECS обрабатывает свойство essential
в определении задачи. Когда я устанавливаю essential
на true
для контейнера Python, ECS отправляет сигнал SIGTERM
в эфемерный сервисный контейнер после завершения работы контейнера Python. В результате контейнер эфемерной службы возвращает ненулевой код завершения, что нежелательно.
Мне нужно, чтобы ECS логически AND
возвращал коды возврата только основных контейнеров, а это означает, что коды завершения второстепенных контейнеров не должны влиять на общий статус задачи. В частности, я хочу, чтобы задача учитывала только код завершения контейнера Python, игнорируя код завершения эфемерного сервисного контейнера при определении того, выполнена ли задача успешно или нет.
Есть ли какой-нибудь способ или сложное решение для решения этой проблемы?
Это ожидаемое поведение, поскольку вы отметили свой контейнер Python как важный, отсюда :
ECS завершает второстепенные задачи, отправляя SIGTERM в необязательные контейнеры. По истечении тайм-аута в 30 секунд (тайм-аут по умолчанию) он отправляет SIGKILL для принудительной остановки контейнера.
Итак, вам нужно обработать сигнал SIGTERM в ваших «необязательных» контейнерах и сделать все необходимое для правильной очистки и выхода. Короче говоря, вам нужно что-то вроде этого примера с Python из здесь:
def shutdown_handler(signal: int, frame: FrameType) -> None:
"""Gracefully shutdown app."""
logger.info("Signal received, safely shutting down.")
database.shutdown()
middleware.logging_flush()
print("Exiting process.", flush=True)
sys.exit(0)
if __name__ == "__main__":
# handles Ctrl-C locally
signal.signal(signal.SIGINT, shutdown_handler)
app.run(host = "127.0.0.1", port=8080, debug=True)
else:
# handles Cloud Run container termination
signal.signal(signal.SIGTERM, shutdown_handler)
А также поручите ECS передавать сигналы для обработки внутри конатинеров, включив initProcessEnabled
проверить документацию здесь
Интересный пост об AWS по обработке сигналов с помощью ECS.
Включите initProcessEnabled во втором контейнере, чтобы позволить процессу перехватывать сигнал SIGTERM, и надейтесь, что ваш процесс в контейнере сможет обработать это по умолчанию, в противном случае я не вижу никаких альтернатив, поскольку именно так работают процессы и сигналы.
Позвольте мне попробовать. Второй контейнер — Docker-Selenium
.
К сожалению, это не работает! :(
Можете ли вы установить значение false для этого контейнера? Docker-Selenium и оставить значение true для контейнера Python?
Я сделал то же самое. Код Python важен и зависит от того, находится ли код Selenium в начальном состоянии.
Я просто публикую ответ на него и ссылаюсь на ваш пост. Спасибо за помощь.
Как уже упоминалось @MedAgou, не существует простого способа справиться с этим конкретным сценарием (т. е. управлять сигналами или изменять код выхода в несущественном дополнительном контейнере).
Вот два подхода к решению этой проблемы при использовании контейнеров selenium-hub
и Python code
:
Создание собственного образа. Вы можете создать собственный образ Docker, сочетающий в себе функциональность обоих контейнеров. Однако такой подход увеличивает сложность системы и создает тесно связанную кодовую базу, что обычно не рекомендуется.
Изменение точки входа контейнера Selenium Hub. Более гибкое решение предполагает изменение точки входа контейнера selenium-hub
. Я исследовал этот репозиторий и адаптировал скрипт enter_point.sh следующим образом:
#!/usr/bin/env bash
NODE_CONFIG_DIRECTORY=${NODE_CONFIG_DIRECTORY:-"/opt/bin"}
#==============================================
# OpenShift or non-sudo environments support
# https://docs.openshift.com/container-platform/3.11/creating_images/guidelines.html#openshift-specific-guidelines
#==============================================
if ! whoami &> /dev/null; then
if [ -w /etc/passwd ]; then
echo "${USER_NAME:-default}:x:$(id -u):0:${USER_NAME:-default} user:${HOME}:/sbin/nologin" >> /etc/passwd
fi
fi
/usr/bin/supervisord --configuration /etc/supervisord.conf &
SUPERVISOR_PID=$!
function shutdown {
echo "The following line does the trick!"
exit 0
}
trap shutdown SIGTERM SIGINT
wait ${SUPERVISOR_PID}
Докерфайл:
ARG IMAGE_TAG=4.23.1-20240820
FROM selenium/standalone-chrome:${IMAGE_TAG}
LABEL maintainer = "Mostafa"
COPY modified-entry-point.sh /opt/bin/modified-entry-point.sh
RUN chmod +x /opt/bin/modified-entry-point.sh
ENTRYPOINT ["/opt/bin/modified-entry-point.sh"]
Этот сценарий гарантирует, что при выходе из контейнера Python контейнер selenium-hub
корректно обработает завершение, не вызывая ненулевой код выхода. Такой подход сохраняет слабую связь между вашими сервисами и обеспечивает желаемое поведение ECS.
Спасибо за ваш ответ. Я не хочу изменять образ второго контейнера по умолчанию. Есть ли какое-либо решение для этой цели?