2016-03-01 1 views
3

У меня есть Django webapp. Он работает внутри Docker на эластичном бобовом стебле.Проверка работоспособности URL-адресов Django и Elastic Beanstalk

Я хотел бы указать health check URL для более продвинутой проверки работоспособности, чем «может ELB установить TCP-соединение».

Полностью разумно, ELB делает это, подключаясь к экземпляру через HTTP, используя имя хоста экземпляра (например, ec2-127-0-0-1.compute-1.amazonaws.com) в качестве заголовка Host.

Django имеет ALLOWED_HOSTS, который проверяет заголовок входящих сообщений Host. Я установил это для внешнего домена моего приложения через переменную среды.

Неудивительно и полностью разумно, поэтому Django отвергает проверки работоспособности URL-адресов ELB из-за отсутствия соответствия Host.

Мы не хотим отключать ALLOWED_HOSTS, потому что мы хотим быть в состоянии доверять get_host().

Решения до сих пор кажутся:

  • Каким-то образом убедить Django не заботиться о ALLOWED_HOSTS для определенных конкретных путей (т.е. проверка состояния URL)
  • ли что-то в стиле фанк, как вызов EC2 API информации о чтобы получить полное доменное имя хоста и добавить его в ALLOWED_HOSTS

Ни один из них не кажется особенно приятным. Может ли кто-нибудь рекомендовать лучшее/существующее решение?

(Во избежание сомнений, я считаю, эта проблема должна быть идентична сценарию «Disabled ALLOWED_HOSTS, противостоя HTTPD, который фильтрует на хосте» - Я хочу, чтобы проверить здоровье ударить Джанго, не противостоя HTTPD)

+1

https://dryan.com/articles/elb-django-allowed-hosts/ – TheGeorgeous

+0

@TheGeorgeous Извините за то, что я не был явным раньше - это именно то, что я был после; хотите опубликовать его в качестве ответа, чтобы я мог его принять? (Надеюсь, вы не возражаете, если я не услышу от вас через месяц, я сделаю это, так что это станет более заметным для всех, кто приземляется здесь!) –

ответ

3

Это то, что я использую, и она работает хорошо:

import socket 
local_ip = str(socket.gethostbyname(socket.gethostname())) 
ALLOWED_HOSTS=[local_ip, '.mydomain.com', 'mydomain.elasticbeanstalk.com' ] 

где вы замените mydomain и mydomain.elasticbeanstalk.com с вашим собственным.

+0

Работает и для меня. Интересно, дает ли этот результат тот же результат, что и локальный ip из метаданных экземпляра, используя 'http: // 169.254.169.254/latest/meta-data/local-ipv4'? – Dennis

5

Если проверка работоспособности ELB отправляет свой запрос с заголовком узла, содержащим домен с эластичным доменом beanstalk (* .elasticbeanstalk.com или домен EC2 * .amazonaws.com), тогда стандарт ALLOWED_HOSTS все еще может использоваться с подстановочным знаком запись '.amazonaws.com' или '.elasticbeanstalk.com'.

В моем случае я получил стандартные ipv4-адреса в качестве хостов проверки работоспособности, поэтому было необходимо другое решение. Если вы не можете предсказать хост вообще, и может быть безопаснее предположить, что вы не можете, вам нужно будет пройти маршрут, например, один из следующих.

Вы можете использовать Apache для обработки утвержденных хостов вместо распространения неоднозначных запросов на Django. Поскольку заголовок хоста предназначен для имени хоста сервера, получающего запрос, это решение изменяет заголовок допустимых запросов на использование ожидаемого имени узла сайта. С эластичным beanstalk вам нужно будет настроить Apache, используя .ebextensions, как описано here. В каталоге .ebextensions в корне вашего проекта добавьте следующее в файл .config.

files: 
    "/etc/httpd/conf.d/eb_healthcheck.conf": 
    mode: "000644" 
    owner: root 
    group: root 
    content: | 
     <If "req('User-Agent') == 'ELB-HealthChecker/1.0' && %{REQUEST_URI} == '/status/'"> 
      RequestHeader set Host "example.com" 
     </If> 

Замена /status/ с вашей проверки URL здоровья и example.com с соответствующим доменом сайта. Это говорит Apache, чтобы проверить все входящие запросы и изменить заголовки хостов на запросы с соответствующим агентом проверки работоспособности, который запрашивает соответствующий URL проверки работоспособности.

Если вы действительно не хотите настраивать Apache, вы можете написать собственное промежуточное программное обеспечение для проверки проверки работоспособности. Среднему программному обеспечению пришлось бы переопределитьDjango, который вызывает метод HttpRequestget_host(), который проверяет хост запроса. Вы могли бы сделать что-то вроде этого

from django.middleware.common import CommonMiddleware 


class CommonOverrideMiddleware(CommonMiddleware): 
    def process_request(self, request): 
     if not('HTTP_USER_AGENT' in request.META and request.META['HTTP_USER_AGENT'] == 'ELB-HealthChecker/1.0' and request.get_full_path() == '/status/'): 
      return super().process_request(request) 

Это просто разрешает любые запросы проверки работоспособности пропускать проверку хоста. Затем вы замените django.middleware.common.CommonMiddleware на path.CommonOverrideMiddleware в своем settings.py.

Я бы рекомендовал использовать подход конфигурации Apache, чтобы избежать каких-либо деталей в промежуточном программном обеспечении и полностью изолировать Django от проблем с хостом.

+0

Метод Apache был единственным, что работало для меня после нескольких стратегий. –

Смежные вопросы