从 aws ELB hostcheck 获取 400 以在 awsvpc 网络模式下与 aws ECS 中的 django ALLOWED_HOSTS 一起工作?
Getting 400's from aws ELB hostcheck to work with django ALLOWED_HOSTS in aws ECS under awsvpc networking mode?
当使用 awsvpc 网络模式转移到 ECS 时,我的 ALB 说我的所有主机都不健康,因为检查 /status/
会产生 400s。我已将问题缩小到 ALLOWED_HOSTS.
有问题
如何让我的网络应用程序为 ELB Healthchecker 提供 200 分?
我想到的解决办法是把LB的地址加到ALLOWED_HOSTS
:
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
这将从附加到您的容器的每个网络中获取每个 IP,并将其添加到您的 ALLOWED_HOSTS。
在使用 awsvpc 网络模式转移到 ECS 之前,我们中的很多人都熟悉这一行,它检索 EC2 实例的 IP,ELB 运行状况检查程序将其用作主机名:
ELB_HEALTHCHECK_HOSTNAME = requests.get('http://169.254.169.254/latest/meta-data/local-ipv4', timeout=2).text
带有 awsvpc 网络的 ECS 下的这一行检索 EC2 实例的 IP,而不是附加到容器的 ENI。要检索 ENI 的 IP,请向环境变量 ${ECS_CONTAINER_METADATA_URI}
中的端点发送请求
这个 returns 有关容器的有用元数据,包括 IPV4
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-metadata-endpoint-v3.html
另一个简单的解决方案是编写自定义 MIDDLEWARE
,它将在检查 ALLOWED_HOSTS
之前向 ELB 提供响应。
中间件可以这么简单:
project/app/middleware.py
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',
...
]
Django 中间件参考资料https://docs.djangoproject.com/en/dev/topics/http/middleware/
你可以试试这个简单的方法
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()))
当使用 awsvpc 网络模式转移到 ECS 时,我的 ALB 说我的所有主机都不健康,因为检查 /status/
会产生 400s。我已将问题缩小到 ALLOWED_HOSTS.
如何让我的网络应用程序为 ELB Healthchecker 提供 200 分?
我想到的解决办法是把LB的地址加到ALLOWED_HOSTS
:
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
这将从附加到您的容器的每个网络中获取每个 IP,并将其添加到您的 ALLOWED_HOSTS。
在使用 awsvpc 网络模式转移到 ECS 之前,我们中的很多人都熟悉这一行,它检索 EC2 实例的 IP,ELB 运行状况检查程序将其用作主机名:
ELB_HEALTHCHECK_HOSTNAME = requests.get('http://169.254.169.254/latest/meta-data/local-ipv4', timeout=2).text
带有 awsvpc 网络的 ECS 下的这一行检索 EC2 实例的 IP,而不是附加到容器的 ENI。要检索 ENI 的 IP,请向环境变量 ${ECS_CONTAINER_METADATA_URI}
中的端点发送请求这个 returns 有关容器的有用元数据,包括 IPV4
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-metadata-endpoint-v3.html
另一个简单的解决方案是编写自定义 MIDDLEWARE
,它将在检查 ALLOWED_HOSTS
之前向 ELB 提供响应。
中间件可以这么简单:
project/app/middleware.py
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',
...
]
Django 中间件参考资料https://docs.djangoproject.com/en/dev/topics/http/middleware/
你可以试试这个简单的方法
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()))