DR
Não consigo enviar uma solicitação HTTP para o contêiner docker local (acessível via 127.0.0.1:4002) por meio do gateway Kong.
Componentes do Gateway Kong:
- Serviço test_service :
url=http://127.0.0.1:4002
; - Rota test_route :
paths[]=/test
,name=test_route
;
Solicitação ao proxy Kong:
$ curl -X GET http://localhost:8000/test
{
"message":"An invalid response was received from the upstream server",
"request_id":"9aba1e35ea54222d9fd27c4e2eeea850"
}
Versão longa
Criei um aplicativo Express simples que responde a solicitações HTTP com "Foo" e "Bar" e o encaixei.
Aplicativo
index.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}`)
})
Arquivo Docker :
FROM node:lts-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 4002
CMD ["node", "index.js"]
Depois de compilá-lo e executá-lo, posso enviar solicitações HTTP para "localhost:4002" e obter as respostas corretamente.
Exemplo:
$ 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
Configuração do Kong
Segui as instruções para configurar o Kong Gateway no Docker e gerenciar serviços e rotas :
- Eu executo o contêiner Kong Gateway:
curl -Ls https://get.konghq.com/quickstart | bash
- Testei a conexão:
$ curl --head localhost:8001
HTTP/1.1 200 OK
[...]
- Criou um serviço:
$ 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 de serviço:
{
"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
}
- Criou uma rota:
$ curl -i -X POST http://localhost:8001/services/test_service/routes --data 'paths[]=/test' --data name=test_route
Rota 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
}
Problema
Quando tento enviar uma solicitação HTTP, recebo o erro "Uma resposta inválida foi recebida do servidor upstream.":
$ curl -X GET http://localhost:8000/test
{
"message":"An invalid response was received from the upstream server",
"request_id":"9aba1e35ea54222d9fd27c4e2eeea850"
}
Pergunta
Minha configuração (serviço/rota) está errada? Estou faltando alguma etapa de configuração?
O problema é principalmente como você conecta o Kong ao seu serviço no Docker.
O serviço
http://127.0.0.1:4002
significa que Kong chamará 127.0.0.1 (localhost) com a porta 4002, basicamente chamando o próprio contêiner Kong, não o aplicativo Expressjs.Para corrigir o problema, execute o aplicativo ExpressJS e o Kong na mesma rede definida pelo usuário e chame o aplicativo com o nome de serviço do Docker (nice_blackwell, neste caso).
Talvez crie um arquivo de composição apenas para facilitar o gerenciamento.
Tópico relacionado do GitHub
Conforme afirmado por Ponsakorn30214 , as solicitações estão falhando porque (obviamente)
url=http://127.0.0.1:4002
significa "localhost" do ponto de vista do contêiner do docker Kong.Solução alternativa
Outra possibilidade de resolver o problema seria usar o endereço IP privado da máquina em que ambos os contêineres estão sendo executados, mas isso será interrompido caso o endereço IP seja reatribuído.
Correção
Corrija o serviço Kong com o seguinte comando (suponha que o endereço IP do host seja
192.168.XXX.XXX
):Resultado
Teste a solicitação HTTP para o gateway: