Kong / ngx_wasm_module

Nginx + WebAssembly
Apache License 2.0
79 stars 7 forks source link

resolver error: Host not found with dispatch_http_call #573

Closed sluramod closed 1 month ago

sluramod commented 2 months ago

Environment: kong 3.6.1

Using Rust Wasm SDK

kong config:

_format_version: "1.1"

upstreams:
  - name: test_api
    algorithm: round-robin
    id: 31314F2A-F6BE-4ACA-B1D0-D9C8ED3895EC

targets:
  - target: "host.docker.internal:8080"
    upstream: { id: "31314F2A-F6BE-4ACA-B1D0-D9C8ED3895EC" }
    id: A9B0C735-4B86-4620-AEE0-53AEB089C968
    weight: 100

services:
  - name: demo
    url: http://httpbin.org
    # url: http://host.docker.internal:6502
    routes:
      - name: my-route
        paths:
          - /
        strip_path: false
        filter_chains:
          - filters:
              - name: test_filter
                config: >-
                  { 
                    "upstream": "test_api",
                    "base_uri": "host.docker.internal:8080"
                  }

test_filter is invoking dispatch_http_call during on_tick like so:

        let headers = vec![
            (":method", method), // "POST"
            (":path", path), // "/v1/tap/batch"
            (":scheme", "http"),
            (":authority", &self.config.env.base_uri), // "host.docker.internal:8080"
            ("accept", "*/*"),
            ("content-type", "application/json"),
            ("content-length", &content_length),
        ];

        log::error!(
            "Dispatching {} upstream {} request to {}{} with body {}",
            &self.config.env.upstream,
            method,
            &self.config.env.base_uri,
            path,
            bodystr
        );

        match self.dispatch_http_call(
            &self.config.env.upstream, // "test_api"
            headers,
            Some(&body),
            trailers,
            timeout,
        ) {

This is what shows up in the logs:

[proxy-wasm]["test_filter" #0] root context resuming "on_tick" step in "background" phase
[proxy-wasm]["test_filter" #0] Dispatching test_api upstream POST request to host.docker.internal:8080/v1/tap/batch with body [{"request":"whatever"}]
[proxy-wasm]["test_filter" #0] setting next action: pwctx->action = "PAUSE" (pwctx: 000055D53ED874E0)
[proxy-wasm]["test_filter" #0] Dispatched request to /v1/tap/batch and got token 0
[proxy-wasm]["test_filter" #0] setting next action: pwctx->action = "CONTINUE" (pwctx: 000055D53ED874E0)
[proxy-wasm]["test_filter" #0] root context resuming "on_tick" step in "background" phase
...
[wasm] dispatch failed: tcp socket - resolver error: Host not found

I tried various hosts and ip addresses besides host.docker.internal and still get the last line, upstream is never being called. I also pass --add-host host.docker.internal=host-gateway to Docker.

There is no diagnostic whatsoever to help with troubleshooting the issue. No documentation for how to properly use dispatch_http_call either.

thibaultcha commented 2 months ago

Hello,

This seems to be the about the same issue as one discussed last week. In Kong Gateway, it is not possible to make a Lua socket resolve the proxy "Upstream" entities; instead, Lua sockets expect a hostname which is resolved by the Gateway's configured DNS resolver. Upstreams and Targets are only interpreted by the Gateway's proxy itself.

I see you configure a Kong Upstream entity with a "test_api" name and expect this name to be resolved to a Target by the Wasm call. Just as it is not possible for Lua sockets, it is not supported by Wasm calls either (there are no existing ABIs in Kong that allow doing that for either implementation).

To resolve your issue you would have to invoke the dispatch by directly giving it the hostname and port: dispatch_http_call(&self.config.env.base_uri).

We did not foresee such usage would be expected of Wasm calls since we imagined users of this module to be Lua plugin authors moving to Wasm. Is this expectation coming from previous Envoy usage? Or something else? We will surely document this disparity with the Envoy implementation now.

Note that we are aware of other issues with the dispatch calls that have not yet been released in the Gateway, see #570. Finally, note as well that Wasm support in the Gateway is still experimental.

Thank you for bringing this to our attention.

sluramod commented 2 months ago

It would be ideal if wasm proxy plugins were portable across the vendors. In fact, I assumed that was the goal of Kong's implementation. For example, this video is explicitly referring to portability as being a desired property https://www.youtube.com/live/xPjh2eeMBQA?si=aLBA_yAoPL8iRgi1&t=1141 and also as differentiator compared to Lua plugins. I feel that having the same ABI between vendors, but different semantics is not in alignment with the stated goals.

thibaultcha commented 2 months ago

It would indeed be ideal. Alas, in practice we are facing limitations from achieving complete parity with Envoy. It also remains a goal for us but it will be a long term one, and it might have to involve revisions of the proxy-wasm specs. There are irreconcilable differences between Envoy and Nginx (and Kong) that have inevitable repercussions on how the current SDK will be used or behave. Some of these differences are documented here. It is worth noting the initial proxy-wasm specs are somewhat Envoy-centric, so not all concepts translate well into Nginx/Kong. For the time being, we will look at better highlighting the hosts differences in our docs.