When moving over to ECS with awsvpc networking mode, my ALB says all my hosts are unhealthy because checking /status/
yields 400s. I've narrowed it down to the issue being something wrong with ALLOWED_HOSTS.
How do I get my web app to give 200's to the ELB Healthchecker?
答案 0 :(得分:2)
另一个简单的解决方案是编写自定义MIDDLEWARE
,该自定义ALLOWED_HOSTS
将在检查project/app/middleware.py
之前将响应发送给ELB。
中间件可以很简单:
from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin
class HealthCheckMiddleware(MiddlewareMixin):
def process_request(self, request):
if request.META["PATH_INFO"] == "/ping/":
return HttpResponse("pong")
settings.py
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'app.middleware.HealthCheckMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
...
]
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_DATABASE=test_db
- MYSQL_USER=sec_user
- MYSQL_PASSWORD=password
Django中间件参考https://docs.djangoproject.com/en/dev/topics/http/middleware/
答案 1 :(得分:1)
您可以尝试这种简单的方法
from socket import gethostname, gethostbyname
# This environment variable is automatically set when ECS runs a task
if os.environ.get("AWS_EXECUTION_ENV"):
ALLOWED_HOSTS.append(gethostbyname(gethostname()))
答案 2 :(得分:0)
The solution I came up with is in your settings, do
ELB_HEALTHCHECK_HOSTNAMES = [ip for network in
requests.get(os.environ['ECS_CONTAINER_METADATA_URI']).json()['Networks']
for ip in network['IPv4Addresses']]
ALLOWED_HOSTS += ELB_HEALTHCHECK_HOSTNAMES
This will take every IP from every networks attached to your container and add it to your ALLOWED_HOSTS.
Prior to moving over to ECS with awsvpc networking mode, a lot of us are familiar with this line that retrieves the EC2 instance's IP which is used as the hostname by the ELB health checker:
ELB_HEALTHCHECK_HOSTNAME = requests.get('http://169.254.169.254/latest/meta-data/local-ipv4', timeout=2).text
This line under ECS with awsvpc networking retrieves the IP of the EC2 instance, not the ENI attached to your container. To retrieve the IP of the ENI, you send a request to the endpoint in the environment variable ${ECS_CONTAINER_METADATA_URI}
This returns useful metadata about the containers, including the IPV4
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-metadata-endpoint-v3.html