Kubernetes nginx ingress控制器返回502,但仅用于AJAX/XmlHttpRequest请求

Kubernetes nginx ingress控制器返回502,但仅用于AJAX/XmlHttpRequest请求,nginx,kubernetes,Nginx,Kubernetes,我有一个web应用程序在nginx入口控制器后面运行Kubernetes,它可以很好地用于请求浏览,但是来自浏览器的任何AJAX/XMLHTTPRequest都会从nginx得到一个502错误 我捕获了常规和AJAX请求的HTTP头,它们看起来很好、正确的主机头、协议等。我不明白为什么只有XMLHttpRequest请求从nginx获得502。没有延迟/挂起,502是即时的。请求似乎从未到达应用程序,但被nginx本身拒绝。将nginx换成直接负载平衡器,问题就消失了 我将进一步挖掘,但我想知道

我有一个web应用程序在nginx入口控制器后面运行Kubernetes,它可以很好地用于请求浏览,但是来自浏览器的任何AJAX/XMLHTTPRequest都会从nginx得到一个502错误

我捕获了常规和AJAX请求的HTTP头,它们看起来很好、正确的主机头、协议等。我不明白为什么只有XMLHttpRequest请求从nginx获得502。没有延迟/挂起,502是即时的。请求似乎从未到达应用程序,但被nginx本身拒绝。将nginx换成直接负载平衡器,问题就消失了

我将进一步挖掘,但我想知道是否有其他使用nginx入口控制器的人以前见过这个问题并解决了它

我从nginx日志中选择了这个错误,它表明容器返回的响应对于nginx缓冲区来说头太大。但是,我检查了nginx.conf并禁用了缓冲:“proxy_buffering off;”

2016/10/27 19:55:51 [error] 309#309: *43363 upstream sent too big header while reading response header from upstream, client: 10.20.51.1, server: foo.example.com, request: "GET /admin/pages/listview HTTP/2.0", upstream: "http://10.20.66.97:80/admin/pages/listview", host: "foo.example.com", referrer: "https://foo.example.com/admin/pages"
奇怪的是,只有当XmlHttpRequest请求URL时,才会出现504错误。如果我用curl请求相同的URL,它可以正常工作,响应头如下所示。同一URL的AJAX/XmlHttpRequest会使响应头过大吗

HTTP/1.1 200 OK
Server: nginx/1.11.3
Date: Thu, 27 Oct 2016 20:15:16 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 6596
Connection: keep-alive
X-Frame-Options: SAMEORIGIN
X-Powered-By: PHP/5.5.9-1ubuntu4.19
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: max-age=0, must-revalidate, no-transform, no-cache, no-store
Pragma: no-cache
X-Controller: CMSPagesController
X-Title: Example+Site+-+Pages
X-Frame-Options: SAMEORIGIN
Vary: X-Requested-With,Accept-Encoding,User-Agent
Strict-Transport-Security: max-age=15724800; includeSubDomains; preload

我解决了这个问题。只有XmlHttpRequests失败的原因是,应用程序在看到XmlHttpRequest请求时有一种特殊的行为,它将大约3000字节的额外头转储到响应中。这使得总头大小大于默认的nginx头缓冲区

nginx阻塞大型HTTP头有效负载是常见的,因为它的默认缓冲区大小小于大多数其他web服务器,只有4k或8k。错误的解决方案是通过添加这些设置将用于头的缓冲区增加到16k

proxy_buffers         8 16k;  # Buffer pool = 8 buffers of 16k
proxy_buffer_size     16k;    # 16k of buffers from pool used for headers
nginx文档非常模糊,这些设置的名称含糊不清。据我所知,每个连接都有一个缓冲池。在这种情况下,每个16 K的8个缓冲器。这些缓冲区用于从上游web服务器接收数据并将数据传回客户端

因此,
proxy\u buffers
确定池。然后
proxy\u buffer\u size
确定主机缓冲池的大部分可用于接收来自上游服务器的HTTP头(我认为四舍五入到整个缓冲区大小)。第三个设置
proxy\u busy\u buffer\u size
确定发送到客户机的缓冲池中有多少是繁忙的(我认为四舍五入到整个缓冲池大小)。默认情况下,
proxy\u busy\u buffer\u size
自动设置为池中的缓冲区数减去1

因此,
proxy\u buffers
池必须足够大,以适应
proxy\u buffer\u size
,并且仍然有足够的剩余缓冲区,至少可以适应上游web服务器HTTP头的
proxy\u buffer\u size

这样做的净结果是,如果你增加代理忙缓冲区大小,你可能会立即得到令人困惑的错误:
“代理忙缓冲区大小”必须小于所有代理缓冲区的大小减去一个缓冲区,然后你必须增加池的大小

以及您询问的
代理缓冲关闭设置?这不会禁用代理缓冲!相反,这就是nginx是否会在将响应发送到浏览器时缓冲整个响应(缓冲池或磁盘),或者是否只缓冲缓冲池中适合的响应。因此,即使您关闭
代理缓冲
代理缓冲仍会发生


我看到了一系列关于设置大型缓冲池的建议,例如8 x 512kb缓冲区(=4MB)之类的大数字。每个连接都有一个缓冲池,因此保留的缓冲池越小,可以处理的连接就越多。

我解决了这个问题。只有XmlHttpRequests失败的原因是,应用程序在看到XmlHttpRequest请求时有一种特殊的行为,它将大约3000字节的额外头转储到响应中。这使得总头大小大于默认的nginx头缓冲区

nginx阻塞大型HTTP头有效负载是常见的,因为它的默认缓冲区大小小于大多数其他web服务器,只有4k或8k。错误的解决方案是通过添加这些设置将用于头的缓冲区增加到16k

proxy_buffers         8 16k;  # Buffer pool = 8 buffers of 16k
proxy_buffer_size     16k;    # 16k of buffers from pool used for headers
nginx文档非常模糊,这些设置的名称含糊不清。据我所知,每个连接都有一个缓冲池。在这种情况下,每个16 K的8个缓冲器。这些缓冲区用于从上游web服务器接收数据并将数据传回客户端

因此,
proxy\u buffers
确定池。然后
proxy\u buffer\u size
确定主机缓冲池的大部分可用于接收来自上游服务器的HTTP头(我认为四舍五入到整个缓冲区大小)。第三个设置
proxy\u busy\u buffer\u size
确定发送到客户机的缓冲池中有多少是繁忙的(我认为四舍五入到整个缓冲池大小)。默认情况下,
proxy\u busy\u buffer\u size
自动设置为池中的缓冲区数减去1

因此,
proxy\u buffers
池必须足够大,以适应
proxy\u buffer\u size
,并且仍然有足够的剩余缓冲区,至少可以适应上游web服务器HTTP头的
proxy\u buffer\u size

这样做的净结果是,如果你增加代理忙缓冲区大小,你可能会立即得到令人困惑的错误:
“代理忙缓冲区大小”必须小于所有代理缓冲区的大小减去一个缓冲区,然后你必须增加池的大小

以及您询问的
代理缓冲关闭设置?这不会禁用代理缓冲!相反,这是nginx是否将缓冲到