为什么这个对 Ingress (GKE) 的 HTTP GET 请求总是返回 400(错误请求)错误?

Why this HTTP GET request to the Ingress (GKE) is always returning 400 (bad request) error?

我正在尝试向 Kubernetes (GKE) 中的应用程序发出 GET 请求,但总是 returning 400 Bad Request。

POST、PUT 和 DELETE 方法运行良好。

最奇怪的是,当我直接使用端口转发到 pod 时,GET 请求没有问题。

我尽量减少应用程序的代码,它看起来像这样:

const express = require('express')
const app = express()
const port = 3000

app.use(express.json())
app.use(express.urlencoded({ extended: true }))

app.get('/', (req, res) => {
  res.send(req.body)
})

app.post('/', function(req, res){
  res.send(req.body);
});

app.put('/', function(req, res){
  res.send(req.body);
});

app.delete('/', function(req, res){
  res.send(req.body);
});

app.listen(port, () => {
  console.log(`Listening to port ${port}`)
})

我认为问题出在我的入口配置中,因为使用端口转发它运行良好。这是我的 Ingress yaml:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
spec:
  tls:
    - hosts:
        - my-test-host
      secretName: tls-secret
  rules:
    - host: my-test-host
      http:
        paths:
        - path: /*
          backend:
            serviceName: my-test-service
            servicePort: 3000

最后,这是总是 return 400 的请求。

curl --location --request GET 'https://my-test-host/' \
--header 'Content-Type: application/json' \
--data-raw '{
    "test": "123"
}'

使用其他方法(POST、PUT 或 DELETE)的相同请求运行良好。请问我做错了什么?

我设法找到了问题的解决方案。

问题是 Ingress 不接受带正文的 HTTP GET 请求 并以错误 400 响应。

最可悲的是,我在任何地方的 Kubernetes 文档中都没有发现任何关于这个问题的信息。

我搜索了有关在 GET 请求中发送正文的最佳实践信息,然后找到了这两个链接:

https://www.rfc-editor.org/rfc/rfc7231#section-4.3.1

https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET

据我了解,不禁止发送带正文的 GET,但不建议这样做。

因此,为了解决我的问题,我更改了代码以从 GET 请求中的“query”而不是“body”获取参数:

app.get('/', (req, res) => {
  res.send(req.query)
})

因此,我需要更改 GET 请求中的发送参数:

curl --location --request GET 'https://my-test-host?test=123'

经验教训:为避免出现问题,切勿接受带正文的 GET 请求。

谢谢。