Kong / kong

🦍 The Cloud-Native API Gateway and AI Gateway.
https://konghq.com/install/#kong-community
Apache License 2.0
39.02k stars 4.79k forks source link

go plugins: Inconsistent environment variable handling when starting go plugin - os.Environ() empty #6974

Closed diefans closed 3 years ago

diefans commented 3 years ago

Summary

os.Environ() is empty on subsequent plugin starts

Steps To Reproduce

var env = os.Environ()
func New() interface{} {
    println(fmt.Sprintf("env: %v", env))
}
  1. Start kong with plugin
  2. Perform a request, which invokes plugin

Additional Details & Logs

Logs after start:

kong_1           | 2021/03/28 10:40:01 [debug] 1#0: [kong] process.lua:61 search config for pluginserver named: go
kong_1           | env: [KONG_ADMIN_ERROR_LOG=/dev/stderr KONG_PROXY_LISTEN=0.0.0.0:8080, 0.0.0.0:8443 ssl KONG_ADMIN_ACCESS_LOG=/dev/stdout KONG_VERSION=2.3.2 HOSTNAME=ab6e31752ee9 KONG_NGINX_PROXY_PROXY_BUFFERS=4 256k SHLVL=1 HOME=/home/kong KONG_AMD64_SHA=4c2e26b3719349d02fe0585a74fcb187e638095b42eea3d08f96d8a30e56e07e KONG_NGINX_HTTP_INCLUDE=/etc/kong/extra_http.conf KONG_CASSANDRA_CONTACT_POINTS=kong-db KONG_NGINX_PROXY_PROXY_BUSY_BUFFERS_SIZE=256k KONG_PG_PASSWORD=kong KONG_PLUGINSERVER_GO_SOCKET=/usr/local/kong/go_pluginserver.sock KONG_GO_PLUGINS_DIR=/go-plugins KONG_PORT_MAP=80:8080,443:8443 KONG_GO_PLUGINSERVER_EXE=/go-plugins/go-pluginserver KONG_PG_HOST=kong-db KONG_PROXY_ERROR_LOG=/dev/stderr KONG_PG_USER=kong KONG_DATABASE=postgres KONG_PROXY_ACCESS_LOG=/dev/stdout ASSET=ce KONG_NGINX_PROXY_PROXY_BUFFER_SIZE=128k KONG_ARM64_SHA=0f5770d67dda761437f365686f87ce821e5848ca0583e502bf5edfb0ba2bfbc3 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin KONG_NGINX_DAEMON=off KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl BM_AUTHX_LOG_PATH=/tmp/bm-authx.log KONG_PLUGINSERVER_GO_START_CMD=/go-plugins/go-pluginserver -kong-prefix /usr/local/kong/ -plugins-directory /go-plugins

Logs after request:

kong_1           | 2021/03/28 10:59:52 [info] 209#0: *18060 [go:217] env: [SHLVL=1 PWD=/], context: ngx.timer
javierguerragiraldez commented 3 years ago

What would be the expected behaviour? Nginx explicitly clears the environment before starting any subprocess. see http://nginx.org/en/docs/ngx_core_module.html#env if you need any of them preserved

diefans commented 3 years ago

I am wondering, since the first call of New has everything in the environment (contradicting your statement)... which made me fall into some kind of trap.

Basically I want to be able to setup the plugin e.g. to log to a certain file instead of the kong log - so there are global aspects of plugin config which should not be tweaked via kong config entites. For docker deployments it is the normal way to provide those settings via environment vars.

javierguerragiraldez commented 3 years ago

the first call of New has everything in the environment (contradicting your statement)

that happens during initialization, before starting the server itself, and via a completely different mechanism. I'd very much like to eliminate that step, but it's required so we can have the schema before parsing the configuration files. Note that it's currently a separate process invocation, so if you want to pass any information from that step to the actual processing instance you'll need to persist it externally. And, of course, there's no guarantee that it will happen always.

Basically I want to be able to setup the plugin e.g. to log to a certain file instead of the kong log - so there are global aspects of plugin config which should not be tweaked via kong config entites.

The ideal way to do it depends a lot on the infrastructure, platform and scale. Among the options would be to preprocess the YAML files, use a database to store that data, use the Kong API to change settings, a real Control Plane (via hybrid mode), etc.

diefans commented 3 years ago

There is a way to pass env vars:

nginx_main_env = LOG_PATH=/foobar.log

But here I can only inject one nginx env directive, a second one overrideds the first one.

javierguerragiraldez commented 3 years ago

closing this because it's not a planned feature to preserve and pass arbitrary environment variables.

diefans commented 3 years ago

...not a planned feature to preserve and pass arbitrary environment variables

are you saying, that nginx_main_env is implemented by accident and the fact that it is usable for just one env var is pure collateral damage caused by this accident?

lapwingcloud commented 2 years ago

related issues:

all suggested using KONG_NGINX_MAIN_ENV

but passing multiple environment variable via KONG_NGINX_MAIN_ENV is hacky (it's pretty much an injection because I can pass any nginx directive into that).

can we have better support for passing multiple environment variables to workers and plugins ? or should I create a separated ticket ?