当 nginxproxy_pass
返回 502 时,原因可能多种多样。我想要的是能够检测何时由于未找到上游主机(即解析失败)而返回 502。
我知道proxy_intercept_errors
,但对我的情况来说它似乎没有帮助。
我拥有的
我有一个在 Kubernetes pod 上运行的 nginx 网关服务器。它配置为根据主机名的第一部分(第一个点之前的单词,例如service-name.example.com
应路由到名为 的服务service-name
)将请求路由到适当的 Kubernetes 服务。
以下是负责此逻辑的简化配置部分:
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;
}
}
问题
无论上游为何无法访问(如果它拒绝连接、内部失败或根本不存在),nginx 都会返回 502。只有在 nginx 错误日志中才能看到实际原因。
由于网关通过 AWS ELB 公开可用,因此它经常通过 IP 或随机名称进行访问,这会在针对 5XX 错误峰值做出反应的监视器中产生噪音。
我想做的事
设置 nginx 以返回一些不太严重的错误(例如,404),以防服务的主机名无法被 Kubernetes 解析器解析。
例如我发送以下请求:
curl -H "Host: non-existent-service.example.com" http://gateway.example.com
我希望 nginx 能够检测到服务对应的主机名无法内部解析,然后返回 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"
更新
应该首先提到这一点。首先要尝试的是“catch-all”默认服务器块。结果发现这个块从未被达到,因为实际上任何主机名都与正则表达式匹配。
答案1
只需重新启用默认虚拟主机并忽略任何命中的内容(因为此类请求直接查询 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 {
}
}