Задача службы ECS Fargate запущена, но целевая группа показывает сбой, и curl для localhost:8000/сбой работоспособности
Краткое описание проблемы:
Я развернул серверную часть Django в ECS, используя тип запуска EC2 (не Fargate), за балансировщиком нагрузки приложений (ALB). Служба запускает контейнерный сервер Gunicorn на порту 8000, а конечной точкой проверки работоспособности является /health/. В то время как ECS показывает, что одна задача запущена и исправна, целевая группа отображает задачу как неработоспособную, и curl для localhost:8000 завершается сбоем в экземпляре EC2.
Подробности настройки ✅ Приложение Django URL-адрес для проверки работоспособности:
def health_check(request):
return JsonResponse({"status": "ok"}, status=200)
path("health/", views.health_check, name="health_check"),
Файл настройки:
FROM python:3.12
ENV PYTHONUNBUFFERED=1
WORKDIR /app
# Install pipenv
RUN pip install --upgrade pip
RUN pip install pipenv
# Install application dependencies
COPY Pipfile Pipfile.lock /app/
# We use the --system flag so packages are installed into the system python
# and not into a virtualenv. Docker containers don't need virtual environments.
RUN pipenv install --system --dev
# Copy the application files into the image
COPY . /app/
# Expose port 8000 on the container
EXPOSE 8000
CMD ["gunicorn", "Shop_Sphere.wsgi:application", "--bind", "0.0.0.0:8000"]
Определение задачи ECS:
Load Balancer SG
Inbound: TCP 80 from 0.0.0.0/0
EC2 Instances SG
Inbound:
TCP 8000 from ALB Security Group
SSH 22 from 0.0.0.0/0
и балансировщик нагрузки, и EC2, вероятно, подключены к одному и тому же SG.
Переменные окружения:
SECURE_SSL_REDIRECT = True
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
ALLOWED_HOSTS = ["*"]
Что я пробовал
✅ Verified Gunicorn runs: gunicorn Shop_Sphere.wsgi:application --bind 0.0.0.0:8000
✅ ps aux | grep gunicorn confirms Gunicorn is listening on PID 1 and 7.
✅ python3 -c "import socket; s = socket.socket(); print(s.connect_ex(('localhost', 8000)))" returns 0 (port is open)
curl http://localhost:8000/health
возвращает:
curl: (7) Failed to connect to localhost port 8000: Connection refused
✅ Изнутри контейнера: curl -v http://localhost:8000/health показывает:
[ec2-user@ip-10-0-1-14 ~]$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
408286a7c603 forkmemaybe/aws-shop-sphere:latest "gunicorn Shop_Spher…" 2 hours ago Up 2 hours (healthy) ecs-Shop-Sphere-Task-Definition-7-Shop-Sphere-Container-90b2d0fed8c7c7e91a00
f4bc560732d3 amazon/amazon-ecs-pause:0.1.0 "/pause" 2 hours ago Up 2 hours ecs-Shop-Sphere-Task-Definition-7-internalecspause-aaabecd7888ad49b2f00
50480628fcce amazon/amazon-ecs-agent:latest "/agent" 11 hours ago Up 11 hours (healthy) ecs-agent
[ec2-user@ip-20-4-9-18 ~]$ sudo docker exec -it 4082 /bin/bash
root@ip-10-0-2-77:/app# curl -v http://localhost:8000/health
* Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /health HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Server: gunicorn
< Date: Sun, 06 Jul 2025 10:47:46 GMT
< Connection: close
< Transfer-Encoding: chunked
< Content-Type: text/html; charset=utf-8
< Location: https://localhost:8000/health
< X-Content-Type-Options: nosniff
< Referrer-Policy: same-origin
< Cross-Origin-Opener-Policy: same-origin
< Vary: origin
<
* Closing connection 0
Итак, я установил путь проверки работоспособности в /health/ Указал порт 8000 в Dockerfile и определении ECS
События облачной обработки
При развертывании службы ECS:
Deployment failed: tasks failed to start.
ECS Deployment Circuit Breaker was triggered.
Вы используете сетевой режим awsvpc, что означает, что контейнер ECS получает свой собственный гибкий сетевой интерфейс в VPC. Таким образом, это было бы вполне ожидаемым поведением, которое вы не смогли бы выполнить curl http://localhost:8000/health из экземпляра EC2, а только изнутри контейнера.
Проблема, скорее всего, заключается в HTTP-ответе, возвращаемом конечной точкой /health:
HTTP/1.1 301 Перенесен навсегда
По умолчанию целевая группа AWS load balancer считает успешным только ответ 200 OK. Если он получит какой-либо другой код ответа для конечной точки проверки работоспособности, он будет считать целевой объект неработоспособным.
Вероятно, вам следует разобраться, почему ваша конечная точка /health возвращает ответ 301. Однако самый простой способ устранить текущую проблему - это обновить целевую группу, чтобы она приняла код ответа 301 в настройках проверки работоспособности.




