Nginx:上游“主机未find”错误的特殊行为?

nginxproxy_pass返回502时,可能有很多原因。 我想要的是能够检测何时返回502,因为没有find上游主机(即,无法parsing)。

我知道proxy_intercept_errors ,但它似乎没有帮助我的情况。

我拥有的

我有一个运行在Kubernetes窗格上的nginx网关服务器。 它被configuration为根据主机名的第一部分将请求路由到适当的Kubernetes服务(在第一个点之前的词,例如service-name.example.com应该路由到称为service-name )。

这是一个简化的configuration部分负责这个逻辑:

 server { listen 80; resolver 172.16.2.3; // Pod IP address server_name "~^(?<svc>[\w-]+)\."; location / { # Each Kubernetes service has an internal domain name matching the following pattern proxy_pass "http://$svc.default.svc.cluster.local"; proxy_set_header Host $host; # Proxy `X-Forwarded` headers sent by ELB: http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/x-forwarded-headers.html proxy_set_header X-Forwarded-For $http_x_forwarded_for; proxy_set_header X-Forwarded-Port $http_x_forwarded_port; proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; } } 

问题

不pipe为什么上游不可访问(如果它拒绝连接,内部失败或者不存在),nginx返回502.这只是nginx错误日志,你可以看到实际的原因。

由于网关是通过AWS ELB公开提供的,因此经常通过IP或随机名称进行访问,从而在监视器中产生噪声,以便对5XX错误峰值做出反应。

我想做的事

如果服务的主机名不能被Kubernetesparsing器parsing,则设置nginx返回一些较不积极的错误(比如404)。

例如,我发送以下请求:

 curl -H "Host: non-existent-service.example.com" http://gateway.example.com 

我希望nginx能够检测到与服务对应的主机名无法在内部parsing的事实,然后返回404而不是502。

目前日志如下所示:

  • 错误日志:

     2017/11/10 16:03:58 [error] 22#22: *482894 non-existent-service.default.svc.cluster.local could not be resolved (3: Host not found), client: 172.16.1.2, server: ~^(?<svc>[\w-]+)\., request: "GET / HTTP/1.1", host: "non-existent-service.example.com" 
  • 访问日志:

     172.16.1.2 - - [10/Nov/2017:16:03:58 +0000] "non-existent-service.example.com" "GET / HTTP/1.1" 502 173 "-" "curl/7.43.0" "194.126.122.250" "EE" 

UPDATE

应该首先提到这一点。 首先要尝试一个“无所不能”的默认服务器块。 原来,这个块永远不会到达,因为几乎任何主机名匹配的正则expression式。

只需重新启用默认的虚拟主机,并忽略任何命中(因为这样的请求是直接查询IP,或者是恶意的)。

例如,在nginx 1.12.x nginx.conf可以看到:

  server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }