【问题标题】:Nginx internal dns resolve issueNginx 内部 dns 解决问题
【发布时间】:2019-10-02 09:02:22
【问题描述】:

我在 AWS 中有 nginx 容器,它为我的网站做反向代理,例如https://example.com。我有自动在本地 DNS 中注册的后端服务 - aws.local(这是由 AWS ECS Auto-Discovery 完成的)。 我遇到的问题是 nginx 仅在启动期间将名称解析为 IP,因此当服务容器重新启动并获取新 IP 时,nginx 仍然尝试旧 IP,并且出现“502 Bad Gateway”错误。

这是我正在运行的代码:

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"。

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;
        }

你能帮我修一下吗? 谢谢!!!

【问题讨论】:

标签: amazon-web-services docker nginx amazon-ecs nginx-reverse-proxy


【解决方案1】:

TL;DR

resolver 169.254.169.253;
set $upstream "service1.aws.local";
proxy_pass http://$upstream:8070;

就像使用 ECS 一样,我在使用 Docker Compose 时遇到了同样的问题。

根据six8's comment on GitHub

nginx 仅在启动时解析主机名。您可以将变量与 proxy_pass 让它使用解析器进行运行时查找。

见:

https://forum.nginx.org/read.php?2,215830,215832#msg-215832

https://www.ruby-forum.com/topic/4407628

这很烦人。

上面的一个链接提供了一个例子

resolver 127.0.0.1;
set $backend "foo.example.com";
proxy_pass http://$backend;

resolver 部分是必需的。而且我们这里不能引用定义的upstreams。

根据Ivan Frolov's answer on StackExchangeresolver的地址应该设置为169.254.169.253

【讨论】:

    【解决方案2】:

    您的 CloudMap 服务发现记录的 TTL 是多少?如果您从 NGINX 容器中进行 NS 查找(假设 EC2 模式并且您可以执行到容器中)它会返回新记录吗?没有更多信息,很难说,但我敢说这是一个 TTL 问题,而不是 NGINX/Service Discovery 问题。

    将 TTL 降低到 1 秒,看看是否可行。

    AWS CloudMap API Reference DNS Record

    【讨论】:

      【解决方案3】:

      我找到了这个问题的完美解决方案。 Nginx“proxy_pass”不能使用“etc/hosts”信息。

      我想建议您在 ECS 中使用 HA-Proxy 反向代理。 我尝试了 nginx 反向代理,但失败了。以及 HA-Proxy 的成功。 比nginx配置更简单。

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

      其次,将这个“环境变量”填入haproxy.cfg。

      另外,我建议您使用“动态端口映射”到 ALB。它使工作更加灵活。

      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
      
      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):

      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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-26
        • 1970-01-01
        • 1970-01-01
        • 2016-06-11
        • 2020-04-07
        • 2020-05-19
        • 2010-09-18
        • 2012-10-10
        相关资源
        最近更新 更多