Nginx内部DNS解决问题 [英] Nginx internal dns resolve issue

查看:413
本文介绍了Nginx内部DNS解决问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在AWS中有nginx容器,该容器确实为我的网站提供反向代理,例如 https://example.com .我拥有自动在本地DNS中注册的后端服务-aws.local(由AWS ECS自动发现完成). 我的问题是nginx仅在启动期间将名称解析为IP,因此当服务容器重新启动并获取新IP时,nginx仍尝试使用旧IP,并且出现"502 Bad Gateway"错误.

I have nginx container in AWS that does reverse proxy for my website e.g. https://example.com. I have backend services that automatically register in local DNS - aws.local (this is done by AWS ECS Auto-Discovery). The problem I have is that nginx is only resolving name to IP during start, so when service container is rebooted and gets new IP, nginx still tries old IP and I have "502 Bad Gateway" error.

这是我正在运行的代码:

Here is a code that I am running:

worker_processes 1;
events { worker_connections 1024; }
http {
    sendfile on;
    include    /etc/nginx/mime.types;
    log_format  graylog2_json  '{ "timestamp": "$time_iso8601", '
                       '"remote_addr": "$remote_addr", '
                       '"body_bytes_sent": $body_bytes_sent, '
                       '"request_time": $request_time, '
                       '"response_status": $status, '
                       '"request": "$request", '
                       '"request_method": "$request_method", '
                       '"host": "$host",'
                       '"upstream_cache_status": "$upstream_cache_status",'
                       '"upstream_addr": "$upstream_addr",'
                       '"http_x_forwarded_for": "$http_x_forwarded_for",'
                       '"http_referrer": "$http_referer", '
                       '"http_user_agent": "$http_user_agent" }';


    upstream service1 {
        server service1.aws.local:8070;
    }

    upstream service2 {
        server service2.aws.local:8080;
    }

    resolver 10.0.0.2 valid=10s;

    server {
        listen 443 http2 ssl;
        server_name example.com;
        location /main {
            proxy_pass         http://service1;
        }

        location /auth {
            proxy_pass         http://service2;
        }

我找到一些建议来更改nginx配置以解析每个请求的名称,但是随后我发现我的浏览器尝试打开"service2.aws.local:8070",但由于其AWS本地DNS名称而失败.我应该在浏览器上看到 https://example.com/auth .

I find advices to change nginx config to resolve names per request, but then I see my browser tries to open "service2.aws.local:8070" and fails since its AWS local DNS name. I should see https://example.com/auth" on my browser.

server {

        set $main service1.aws.local:2000;
        set $auth service2.aws.local:8070;

        location /main {
            proxy_http_version 1.1;
            proxy_pass http://$main;
        }
        location /auth {
            proxy_http_version 1.1;
            proxy_pass http://$auth;
        }

您能帮我修复它吗? 谢谢!!!

Can you help me fixing it? Thanks !!!

推荐答案

我找到了解决此问题的完美方法. Nginx的"proxy_pass"不能使用"etc/hosts"信息.

I found perfectly solution of this issue. Nginx "proxy_pass" can't use "etc/hosts" information.

我建议您在ECS中使用HA-Proxy反向代理. 我尝试了nginx反向代理,但失败了. HA-Proxy并获得成功. 它比nginx配置更简单.

I wanna sugguest you use HA-Proxy reverse proxy in ECS. I tried nginx reverse proxy, but failed. And success with HA-Proxy. It is more simple than nginx configuration.

首先,使用Docker的链接"选项并设置环境变量"(例如LINK_APP,LINK_PORT).

First, use "links" option of Docker and setting "environment variables" (eg. LINK_APP, LINK_PORT).

第二,将此环境变量"填充到haproxy.cfg中.

Second, fill this "environment variables" into haproxy.cfg.

此外,我建议您使用动态端口映射"到ALB.它使作品更加灵活.

Also, I recommend you use "dynamic port mapping" to ALB. it makes more flexible works.

taskdef.json:

taskdef.json :

# taskdef.json

{
    "executionRoleArn": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/<APP_NAME>_ecsTaskExecutionRole",
    "containerDefinitions": [
      {
        "name": "<APP_NAME>-rp",
        "image": "gnokoheat/ecs-reverse-proxy:latest",
        "essential": true,
        "memoryReservation": <MEMORY_RESV>,
        "portMappings": [
          {
            "hostPort": 0,
            "containerPort": 80,
            "protocol": "tcp"
          }
        ],
        "links": [
          "<APP_NAME>"
        ],
        "environment": [
          {
            "name": "LINK_PORT",
            "value": "<SERVICE_PORT>"
          },
          {
            "name": "LINK_APP",
            "value": "<APP_NAME>"
          }
        ]
      },
      {
        "name": "<APP_NAME>",
        "image": "<IMAGE_NAME>",
        "essential": true,
        "memoryReservation": <MEMORY_RESV>,
        "portMappings": [
          {
            "protocol": "tcp",
            "containerPort": <SERVICE_PORT>
          }
        ],
        "environment": [
          {
            "name": "PORT",
            "value": "<SERVICE_PORT>"
          },
          {
            "name": "APP_NAME",
            "value": "<APP_NAME>"
          }
        ]
      }
    ],
    "requiresCompatibilities": [
      "EC2"
    ],
    "networkMode": "bridge",
    "family": "<APP_NAME>"
  }

haproxy.cfg:

haproxy.cfg :

# haproxy.cfg

global
    daemon
    pidfile /var/run/haproxy.pid

defaults
    log global
    mode http
    retries 3
    timeout connect 5000
    timeout client 50000
    timeout server 50000

frontend http
    bind *:80

    http-request set-header X-Forwarded-Host %[req.hdr(Host)]

    compression algo gzip
    compression type text/css text/javascript text/plain application/json application/xml

    default_backend app

backend app
    server static "${LINK_APP}":"${LINK_PORT}"

Dockerfile(haproxy):

Dockerfile(haproxy) :

FROM haproxy:1.7
USER root
COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg

请参阅:

Github: https://github.com/gnokoheat/ecs-reverse-proxy

Docker镜像:gnokoheat/ecs-reverse-proxy:latest

Docker image : gnokoheat/ecs-reverse-proxy:latest

这篇关于Nginx内部DNS解决问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆