长话短说
我无法通过 Kong 网关向本地 docker 容器(可通过 127.0.0.1:4002 访问)发送 HTTP 请求。
Kong网关组件:
- 服务测试服务:
url=http://127.0.0.1:4002
; - 路线test_route :
paths[]=/test
,name=test_route
;
向 Kong 代理请求:
$ curl -X GET http://localhost:8000/test
{
"message":"An invalid response was received from the upstream server",
"request_id":"9aba1e35ea54222d9fd27c4e2eeea850"
}
长版
我创建了一个简单的 Express 应用程序,它使用“Foo”和“Bar”响应 HTTP 请求,并将其进行了 Docker 化。
应用
索引.js:
const express = require('express');
const app = express();
var port = 4002;
app.use("/foo", (req, res) => {
res.send("Foo");
});
app.use("/bar", (req, res) => {
res.send("Bar");
});
app.use((req, res) => {
res.send("Test unknown path");
});
app.listen(port, () => {
console.log(`Foo-bar listening on port ${port}`)
})
Dockerfile:
FROM node:lts-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 4002
CMD ["node", "index.js"]
构建并运行它后,我可以将 HTTP 请求发送到“localhost:4002”并正确获取响应。
例子:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fce1cc4e7b24 mikyll/test-service:latest "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:4002->4002/tcp nice_blackwell
$ curl -X GET http://localhost:4002
Test unknown path
$ curl -X GET http://localhost:4002/foo
Foo
$ curl -X GET http://localhost:4002/bar
Bar
Kong设置
我按照说明在 Docker 上设置 Kong Gateway并管理服务和路由:
- 我运行 Kong Gateway 容器:
curl -Ls https://get.konghq.com/quickstart | bash
- 测试连接:
$ curl --head localhost:8001
HTTP/1.1 200 OK
[...]
- 创建了一个服务:
$ curl -i -s -X POST http://localhost:8001/services --data name=test_service --data url='http://127.0.0.1:4002'
HTTP/1.1 201 Created
[...]
服务 JSON:
{
"data":[
{
"retries":5,
"tls_verify":null,
"protocol":"http",
"port":4002,
"updated_at":1700054325,
"created_at":1700054325,
"connect_timeout":60000,
"read_timeout":60000,
"client_certificate":null,
"host":"127.0.0.1",
"path":null,
"name":"test_service",
"enabled":true,
"tags":null,
"write_timeout":60000,
"ca_certificates":null,
"id":"e79539ca-603b-4237-8abd-6ff07bd73160",
"tls_verify_depth":null
}
],
"next":null
}
- 创建了一条路线:
$ curl -i -X POST http://localhost:8001/services/test_service/routes --data 'paths[]=/test' --data name=test_route
路由 JSON:
{
"data":[
{
"https_redirect_status_code":426,
"service":{
"id":"e79539ca-603b-4237-8abd-6ff07bd73160"
},
"id":"4b04a262-6229-4361-9b2c-88f00b0fe6c2",
"hosts":null,
"path_handling":"v0",
"updated_at":1700054404,
"created_at":1700054404,
"preserve_host":false,
"headers":null,
"methods":null,
"sources":null,
"destinations":null,
"paths":[
"/test"
],
"snis":null,
"name":"test_route",
"tags":null,
"request_buffering":true,
"response_buffering":true,
"protocols":[
"http",
"https"
],
"regex_priority":0,
"strip_path":true
}
],
"next":null
}
问题
当我尝试发送 HTTP 请求时,收到错误“从上游服务器收到无效响应。”:
$ curl -X GET http://localhost:8000/test
{
"message":"An invalid response was received from the upstream server",
"request_id":"9aba1e35ea54222d9fd27c4e2eeea850"
}
问题
我的配置(服务/路由)是否错误?我是否缺少一些设置步骤?
问题主要在于如何将 Kong 与 Docker 上的服务连接起来。
该服务
http://127.0.0.1:4002
意味着 Kong 将使用端口 4002 调用 127.0.0.1 (localhost),基本上调用 Kong 容器本身,而不是 Expressjs 应用程序。要解决此问题,请在同一用户定义的网络上运行 ExpressJS 应用程序和 Kong ,并使用 Docker 的服务名称(在本例中为 Nice_blackwell)调用该应用程序。
也许创建一个撰写文件只是为了更容易管理。
相关 GitHub 线程
正如Ponsakorn30214所说,请求失败是因为(显然)
url=http://127.0.0.1:4002
从 Kong docker 容器的角度来看意味着“localhost”。替代解决方案
解决该问题的另一种可能性是使用两个容器都在其上运行的计算机的私有 IP 地址,但如果 IP 地址被重新分配,这种情况就会中断。
修补
使用以下命令修补 Kong 服务(假设主机 IP 地址为
192.168.XXX.XXX
):结果
测试对网关的 HTTP 请求: