2017-01-15 8 views
1

В настоящее время я развертываю приложение Django + uWSGI с помощью single container docker environment в AWS ElasticBeanstalk. Эта среда уже поставляется с nginx, который я сейчас пытаюсь настроить.Настройка nginx в среде контейнера с одним докере (AWS ElasticBeanstalk)

Я пытаюсь добиться следующего:

  1. Прекратить HTTPS при балансировки нагрузки окружающей среды в
  2. Перенаправление HTTP запросы HTTPS с помощью Nginx (который поставляется с окружающей средой)
  3. Pass запросы от Nginx к uwsgi
  4. информации

Окружающей среды:

  • Конфигурация и решение Stack Название: Single Контейнер Docker 1,11 версия 2.3.0
  • AMI: 64bit Amazon Linux 2016,09 v2.3.0 работает докер 1.11.2 2016.09.0
  • Docker Version: 1.11.2
  • Proxy Server: Nginx 1.10.1

Это моя текущая конфигурация:

.ebxtensions/00-loadbalancer-terminatehttps.config

option_settings: 
    aws:elb:listener:443: 
    ListenerEnabled: true 
    ListenerProtocol: HTTPS 
    SSLCertificateId: <resource-id-here> 
    InstancePort: 443 
    InstanceProtocol: HTTP 
    aws:elb:listener:80: 
    ListenerEnabled: true 
    ListenerProtocol: HTTP 
    InstancePort: 80 
    InstanceProtocol: HTTP 

.ebextensions/01-Nginx-proxy.config

files: 
    "/etc/nginx/sites-available/test.domain.com.conf": 
    mode: "000644" 
    owner: root 
    group: root 
    content: | 
     server { 
     listen 80; 
     server_name test.domain.com; 
     access_log /var/log/nginx/$server_name.access.log; 

     location/{ 
      return 301 https://$server_name$request_uri; 
     } 

     location = /status/ { 
      access_log /var/log/nginx/$server_name.healthd.log healthd; 
      include uwsgi_params; 
      uwsgi_pass docker; 
      proxy_set_header Host $host; 
      proxy_set_header X-Real-IP $remote_addr; 
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
      proxy_set_header X-Forwarded-Host $host; 
      proxy_set_header X-Forwarded-Server $host; 
     } 

     } 

     server { 
     listen 443; 
     server_name test.domain.com; 
     access_log /var/log/nginx/$server_name.access.log; 

     location/{ 
      include uwsgi_params; 
      uwsgi_pass docker; 
      proxy_set_header Host $host; 
      proxy_set_header X-Real-IP $remote_addr; 
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
      proxy_set_header X-Forwarded-Host $host; 
      proxy_set_header X-Forwarded-Server $host; 
      client_max_body_size 100m; 
     } 

     location /static { 
      alias /var/www/static; 
     } 
     } 

commands: 
    00_enable_site: 
    command: 'rm -f /etc/nginx/sites-enabled/* && ln -s /etc/nginx/sites-available/test.domain.com.conf /etc/nginx/sites-enabled/test.domain.com.conf' 

.ebextensions/02-healthcheckurl.config

option_settings: 
    - namespace: aws:elasticbeanstalk:application 
    option_name: Application Healthcheck URL 
    value: /status/ 

application.ini (uwsgi конфигурации)

[uwsgi] 
master = true 
socket = :3031 
processes = 4 
enable-threads = true 
threads = 2 
chdir = /opt/app/ 
wsgi-file = test/wsgi.py 
logto2 = /var/log/uwsgi.log 
callable = application 
py-autoreload = 3 

Теперь, при тестировании конфигурации:

Проверка http://test.domain.com/status/ работает отлично

$ wget http://test.domain.com/status/ 
--2017-01-14 23:00:18-- http://test.domain.com/status/ 
Resolving test.domain.com... 52.xx.xx.xx, 52.xx.xx.xy 
Connecting to test.domain.com|52.xx.xx.xx|:80... connected. 
HTTP request sent, awaiting response... 200 OK 

Проверка http://test.domain.com/hello/ не работает должным образом. Он перенаправляет штраф, но затем зависает, пока запрос не истечет.

$ wget http://test.domain.com/hello/ 
--2017-01-14 22:59:13-- http://test.domain.com/hello/ 
Resolving test.domain.com... 52.xx.xx.xx, 52.xx.xx.xy 
Connecting to test.domain.com|52.xx.xx.xx|:80... connected. 
HTTP request sent, awaiting response... 301 Moved Permanently 
Location: https://test.domain.com/hello/ [following] 
--2017-01-14 22:59:15-- https://test.domain.com/hello/ 
Connecting to test.domain.com|52.xx.xx.xx|:443... connected. 
HTTP request sent, awaiting response... 408 REQUEST_TIMEOUT 
2017-01-14 23:00:17 ERROR 408: REQUEST_TIMEOUT. 
+0

Вы видели ошибки в журналах afte r войти в машину EC2/ECS, созданную службой Beanstalk? – Sairam

+0

/var/log/nginx/error.log ничего не показывает. Uwsgi.log показывает только запросы GET для/status /. По-видимому, uwsgi не получает запросы на другие пути (т. Е./Hello/и /) из nginx. – blaze

+1

Тайм-аут обычно указывает на группы безопасности, не допускающие определенного трафика. Я не слишком хорошо знаком с ELB над Elasticbeanstalk, но для «нормального» ELB вам необходимо специально открыть 443 трафика. – deviavir

ответ

2

Следуя предложению @ deviavir, мне нужно было разрешить трафик с балансира нагрузки в экземпляр EC2.

Это моя окончательная конфигурация:

.ebextensions 
    |-- 00-resources.config 
    |-- 01-nginx-proxy.config 

.ebextensions/00-resources.config:

Resources: 
    AWSEBSecurityGroup: 
    Type: "AWS::EC2::SecurityGroup" 
    Properties: 
     GroupDescription: "Allow traffic to ports 80 and 443 from the load balancer. Restrict SSH access." 
    AWSEBLoadBalancer: 
    Type: "AWS::ElasticLoadBalancing::LoadBalancer" 
    Properties: 
     Listeners: 
     - {LoadBalancerPort: 80, 
      Protocol: 'HTTP', 
      InstancePort: 80, 
      InstanceProtocol: 'HTTP'} 
     - {LoadBalancerPort: 443, 
      Protocol: 'HTTPS', 
      InstancePort: 443, 
      InstanceProtocol: 'HTTP', 
      SSLCertificateId: 'arn:aws:acm:us-east-1:xxxx:certificate/yyyy'} 
     HealthCheck: 
     Target: HTTP:80/status/ 
     HealthyThreshold: '3' 
     UnhealthyThreshold: '5' 
     Interval: '30' 
     Timeout: '5' 
    Port80SecurityGroupIngress: 
    Type: "AWS::EC2::SecurityGroupIngress" 
    Properties: 
     GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]} 
     IpProtocol: tcp 
     ToPort: 80 
     FromPort: 80 
     SourceSecurityGroupName: {"Fn::GetAtt" : ["AWSEBLoadBalancer" , "SourceSecurityGroup.GroupName"]} 
    Port443SecurityGroupIngress: 
    Type: "AWS::EC2::SecurityGroupIngress" 
    Properties: 
     GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]} 
     IpProtocol: tcp 
     ToPort: 443 
     FromPort: 443 
     SourceSecurityGroupName: {"Fn::GetAtt" : ["AWSEBLoadBalancer" , "SourceSecurityGroup.GroupName"]} 
    SSHSecurityGroupIngress: 
    Type: "AWS::EC2::SecurityGroupIngress" 
    Properties: 
     GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]} 
     IpProtocol: tcp 
     ToPort: 22 
     FromPort: 22 
     CidrIp: xx.xx.xx.xx/yy 

.ebextensions/01-Nginx-proxy.config:

files: 
    "/etc/nginx/sites-available/test.domain.com.conf": 
    mode: "000644" 
    owner: root 
    group: root 
    content: | 
     server { 
     listen 80; 
     server_name test.domain.com; 
     access_log /var/log/nginx/$server_name.access.log; 

     location/{ 
      return 301 https://$server_name$request_uri; 
     } 

     location = /status/ { 
      access_log /var/log/nginx/$server_name.status.log; 
      uwsgi_pass docker; 
      include uwsgi_params; 
     } 

     } 

     server { 
     listen 443; 
     server_name test.domain.com; 
     access_log /var/log/nginx/$server_name.access.log; 

     location/{ 
      uwsgi_pass docker; 
      include uwsgi_params; 
      client_max_body_size 100m; 
     } 

     location /static/ { 
      root /var/www; 
     } 
     } 

commands: 
    00_enable_site: 
    command: 'rm -f /etc/nginx/sites-enabled/* && ln -s /etc/nginx/sites-available/test.domain.com.conf /etc/nginx/sites-enabled/test.domain.com.conf' 
0

редактировать: Проблема

OP была решена здесь Configuring nginx in a single docker container environment (AWS ElasticBeanstalk), я оставляю ниже информацию для полноты картины.


Удалить "сервер" блок для порта 443 из вашей Nginx конфигурации, и в .ebxtensions/00-loadbalancer-terminatehttps.config, установите aws:elb:listener:443: «s InstancePort до 80, и проверить HTTPS с помощью Nginx '$ http_x_forwarded_proto'.

if ($http_x_forwarded_proto != "https") { 
    rewrite ^(.*)$ https://$server_name$1 permanent; 
} 

Почему? В настоящее время кажется, что ваш nginx + elb пытается завершить HTTPS вместе, но ваш nginx не отвечает ни с чем. Если вы не планируете иметь внутренние HTTPS, имеет смысл просто придерживаться одного блока сервера nginx и выполнять всю свою логику.

Я предлагаю следующие конфигурационные файлы:

.ebxtensions/00-loadbalancer-terminatehttps.config

option_settings: 
    aws:elb:listener:443: 
    ListenerEnabled: true 
    ListenerProtocol: HTTPS 
    SSLCertificateId: <resource-id-here> 
    InstancePort: 80 
    InstanceProtocol: HTTP 
    aws:elb:listener:80: 
    ListenerEnabled: true 
    ListenerProtocol: HTTP 
    InstancePort: 80 
    InstanceProtocol: HTTP 

.ebextensions/01-Nginx-proxy.config

files: 
    "/etc/nginx/sites-available/test.domain.com.conf": 
    mode: "000644" 
    owner: root 
    group: root 
    content: | 
     server { 
     listen 80; 
     server_name test.domain.com; 
     access_log /var/log/nginx/$server_name.access.log; 

     if ($http_x_forwarded_proto != "https") { 
      set $test http; 
     } 

     if ($request_uri = /status/) { 
      set $test "${test}+status"; 
     } 

     if ($test = "http") { 
      return 301 https://$server_name$request_uri; 
     } 

     location = /status/ { 
      access_log /var/log/nginx/$server_name.healthd.log healthd; 
      include uwsgi_params; 
      uwsgi_pass docker; 
      proxy_set_header Host $host; 
      proxy_set_header X-Real-IP $remote_addr; 
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
      proxy_set_header X-Forwarded-Host $host; 
      proxy_set_header X-Forwarded-Server $host; 
      client_max_body_size 100m; 
     } 

     location /static { 
      alias /var/www/static; 
     } 

     location/{ 
      include uwsgi_params; 
      uwsgi_pass docker; 
      proxy_set_header Host $host; 
      proxy_set_header X-Real-IP $remote_addr; 
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
      proxy_set_header X-Forwarded-Host $host; 
      proxy_set_header X-Forwarded-Server $host; 
      client_max_body_size 100m; 
     } 

     } 

commands: 
    00_enable_site: 
    command: 'rm -f /etc/nginx/sites-enabled/* && ln -s /etc/nginx/sites-available/test.domain.com.conf /etc/nginx/sites-enabled/test.domain.com.conf' 

Обратите внимание, что я ни в коем случае не утверждаю, что это лучшее решение вашей проблемы (или даже решение вообще), 408, по-видимому, указывает на несколько странную проблему, однако, это должно привести вас к несколько более простой конфигурации для отладки и, надеюсь, сразу начнется.

+1

Спасибо. У меня есть отдельные директивы сервера, так как [только безопасные вещи, которые должны выполняться внутри директивы if, являются «return» и «rewrite»] (https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil /). В конце концов, я создал новый файл '00-resources.config', где создаю пользовательскую SecurityGroup, настраиваемый LoadBalancer и три пользовательских ресурса SecurityGroupIngress. – blaze

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