#python #docker #amazon-ecs #aws-fargate
#python #docker #amazon-ecs #aws-fargate
Вопрос:
У меня есть контейнер Fargate ECS, который я использую для запуска контейнера Docker через задачи в ECS. При запуске задачи вызывается скрипт sh, runner.sh
,
#!/bin/sh
echo "this line will get logged to ECS..."
python3 src/my_python_script.py # however print statements from this Python script are not logged to ECS
Это, в свою очередь, запускает давно запущенный скрипт Python, my_python_script.py
. Я знаю, что скрипт Python работает нормально, потому что он делает то, что ему нужно, но я не вижу выходных данных скрипта Python.
Внутри my_python_script.py
есть несколько print()
инструкций. В журналах CloudWatch для моей задачи ECS Fargate я вижу вывод из sh script ( "this line will get logged to ECS..."
), но не вывод из print()
инструкций, выполняемых в скрипте Python.
Это конфигурация журналов из определения моей задачи:
{
"ipcMode": null,
"executionRoleArn": "myecsTaskExecutionRolearn",
"containerDefinitions": [
{
"dnsSearchDomains": null,
"environmentFiles": null,
"logConfiguration": {
"logDriver": "awslogs",
"secretOptions": null,
"options": {
"awslogs-group": "/ecs/mylogsgroup",
"awslogs-region": "eu-west-1",
"awslogs-stream-prefix": "ecs"
}
},
"entryPoint": null,
"portMappings": [],
"command": null,
"linuxParameters": null,
"cpu": 0,
"environment": [],
"resourceRequirements": null,
"ulimits": null,
"dnsServers": null,
"mountPoints": [],
"workingDirectory": null,
"secrets": null,
"dockerSecurityOptions": null,
"memory": null,
"memoryReservation": null,
"volumesFrom": [],
"stopTimeout": null,
"image": "1234567.dck.aws.com/mydockerimage",
"startTimeout": null,
"firelensConfiguration": null,
"dependsOn": null,
"disableNetworking": null,
"interactive": null,
"healthCheck": null,
"essential": true,
"links": null,
"hostname": null,
"extraHosts": null,
"pseudoTerminal": null,
"user": null,
"readonlyRootFilesystem": null,
"dockerLabels": null,
"systemControls": null,
"privileged": null,
"name": "my-task-definition-name"
}
],
"memory": "4096",
"taskRoleArn": "myecsTaskRolearn",
"family": "my-task-definition-name",
"pidMode": null,
"requiresCompatibilities": [
"FARGATE"
],
"networkMode": "awsvpc",
"cpu": "2048",
"inferenceAccelerators": [],
"proxyConfiguration": null,
"volumes": [],
"tags": []
}
Dockerfile:
FROM rocker/verse:3.6.0
ENV DEBIAN_FRONTEND noninteractive
RUN install2.r --error
jsonlite
RUN echo "deb http://ftp.de.debian.org/debian testing main" >> /etc/apt/sources.list
RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local
RUN apt-get update amp;amp; apt-get -t testing install -y --force-yes python3.6
RUN apt-get update amp;amp; apt-get -t testing install -y libmagick -dev python3-pip python-setuptools
RUN mkdir /app
WORKDIR /app
COPY ./src /app/src
RUN pip3 install --trusted-host pypi.python.org -r /app/requirements.txt
CMD /app/runner.sh
Я думаю, что я следую инструкциям awslogs из https://docs.aws.amazon.com/AmazonECS/latest/userguide/using_awslogs.html а может, и нет? Есть ли что-то очевидное, что мне нужно сделать, чтобы убедиться, что print()
инструкции из скрипта Python записываются в журналы CloudWatch моей задачи ECS?
Комментарии:
1. Можете ли вы опубликовать остальную часть определения задачи и Dockerfile, из которого был создан образ?
2. @alexandre-juma Я отредактировал свой вопрос, чтобы добавить определение моей задачи и Dockerfile. Спасибо
3. Можете ли вы попробовать изменить свой
CMD
оператор Dockerfile на формат execCMD ["/app/runner.sh"]
и добавить изменение вашего вспомогательного скрипта, напримерexec python3 src/my_python_script.py
? После этого, пожалуйста, войдите в контейнер в интерактивном режиме и проверьте, удерживается ли PID 1 вашим скриптом python, просто чтобы убедиться.4. Это долгий путь, но, возможно, драйвер ведения журнала выходит из себя, потому что ваш PID 1 является оболочкой-оболочкой (вы не запускаете CMD в режиме exec), а затем вызываете другой сценарий оболочки /app/runner.sh а затем вызываем интерпретатор python и скрипт.
Ответ №1:
Мне кажется, что есть пара вещей, с которыми вы могли бы иметь дело здесь.
Первое — это поведение буферизации Python по умолчанию, которое может помешать отображению выходных данных. Вам нужно будет остановить это.
Вы можете правильно установить переменную PYTHONUNBUFFERED env, вставив следующее перед CMD:
ENV PYTHONUNBUFFERED=1
Во-вторых, цитирую документ с использованием драйвера awslogs, который вы связали:
Тип информации, которая регистрируется контейнерами в вашей задаче, в основном зависит от их команды ENTRYPOINT . По умолчанию в журналах, которые записываются, отображаются выходные данные команды, которые вы обычно видите в интерактивном терминале, если вы запускаете контейнер локально, то есть потоки ввода-вывода STDOUT и STDERR. Драйвер журнала awslogs просто передает эти журналы из Docker в журналы CloudWatch. Дополнительные сведения о том, как обрабатываются журналы Docker, включая альтернативные способы захвата различных файловых данных или потоков, см. В разделе Просмотр журналов для контейнера или службы в документации Docker.
Исходя из этого, я бы заменил строку CMD на следующую в соответствии с формой Exec для ENTRYPOINT:
ENTRYPOINT ["/app/runner.sh"]
Это должно послужить для подключения потоков ввода-вывода STDOUT и STDERR для вашего сценария оболочки и, надеюсь, вашего скрипта Python к ведению журнала контейнера.