-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(conf) add support to configure nginx directives via kong.conf #3530
Conversation
Problem ------- Kong ships with an NGINX template which is rendered when Kong starts. There exists no mechanisms to add/update any NGINX directive to the `nginx.conf` used to run Kong. To change or add any directive, user has to use a custom NGINX template which has to be synced with Kong for a release which introduces changes to Kong's template. Including options in `kong.conf` to configure NGINX directives is not a good solution since the list will be endless. This problem can be seen in #3010, #3323 and #3382. Solution -------- There needs to be a flexible way to specify any NGINX directive via Kong's config file without Kong needing to maintain a list of all NGINX directives. While a clean and ideal solution would be #2355, this commit adopts a simpler as discussed like the one proposed in #2675. NGINX directives can be specified using config variables with prefixes, which help determine the block in which to place a directive. eg: `nginx_proxy_add_header=Header-Name header-value` will add a `add_header Header-Name header-value;` directive in the proxy server block of Kong. `nginx_http_lua_shared_dict=custom_cache 2k` will add a a `lua_shared_dict custom_cache 2k;` directive to HTTP block of Kong.s
Signed-off-by: Harry Bagdi <[email protected]>
kong/conf_loader.lua
Outdated
|
||
for k, v in pairs(conf) do | ||
if type(k) == "string" then | ||
local _ , _ , directive= string.find(k, prefix .. "(.+)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: spacing (local _, _, directive = string.find
...)
A wild idea that came to mind for supporting duplicated nginx directives: how about taking the key and running (The downside is that the arguments would always become lowercase when sent via environment variables (which may or may not be okay for headers), but for kong.conf that wouldn't be a problem.) |
Signed-off-by: Harry Bagdi <[email protected]>
local fmt = string.format | ||
|
||
|
||
local cmd = [[ printenv ]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe there is no need for this extra variable anymore, it is used only once.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is used for the debug log as well.
kong/cmd/utils/env.lua
Outdated
local success, ret_code, stdout, stderr = pl_utils.executeex(cmd) | ||
if not success or ret_code ~= 0 then | ||
return nil, fmt("could not read environment variables (exit code: %d): %s", | ||
ret_code, stderr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: alignment
kong/cmd/utils/env.lua
Outdated
for line in stdout:gmatch("[^\r\n]+") do | ||
local i = string.find(line, "=") -- match first = | ||
if i then | ||
local k = string.sub(line,1, i-1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: sub(line, 1, i - 1)
kong/cmd/utils/nginx_signals.lua
Outdated
local ok, retcode, _, stderr = pl_utils.executeex(cmd) | ||
if not ok then | ||
return false, ("failed to validate nginx configuration " .. | ||
"(exit code %d):\n%s"):format(retcode ,stderr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: alignment and space after the comma
kong/cmd/utils/nginx_signals.lua
Outdated
return false, ("failed to validate nginx configuration " .. | ||
"(exit code %d):\n%s"):format(retcode ,stderr) | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's also add a debug log when the validation succeededs, otherwise the user just sees "checking nginx conf" and does not know what happened after that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UNIX philosophy of no output is good?
kong/conf_loader.lua
Outdated
find_dynamic_keys(from_file_conf, prefix) | ||
end | ||
|
||
defaults = tablex.merge(defaults, dynamic_keys, true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment that this is building the union? This way the intent is clearer (as discussed) to readers who see tablex.merge()
usage several times in this module. See below:
conf = tablex.merge(conf, defaults) -- intersection (remove extraneous properties)
init = function() | ||
end, | ||
} | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should go below the check for required shms, otherwise configs lacking the shm would error during the actual start
, and yet configuration validation would report a success...
Signed-off-by: Harry Bagdi <[email protected]>
local function start(config) | ||
return function() | ||
bp.routes:insert { | ||
hosts = { "headers-inspect.com" }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, a super minor thing but which I think we should start paying attention in our tests (perhaps worth an addition to the style guide even?) — I suggest we stop using "valid-looking" URLs in tests, even if we're not hitting them (we've had in the past tests that used an innocent-looking URL which ended up pointing to a porn site!) — we can use instead example.com
or any URL using the reserved .test
TLD (which then allows for "descriptive" test hostnames such as headers-inspect.test
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for sharing pointing this out!
I like the idea of using the .test
TLD. I've updated the code to use headers-inspect.test
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
we've had in the past tests that used an innocent-looking URL which ended up pointing to a porn site
I've also seen cases of test/example code in public documentation using "domain.com", which at one point hosted malware; customers who blindly copy-pasted were in for a nasty surprise :p
IANA has reserved example.com
for cases like this, FWIW. https://www.iana.org/domains/reserved
Just my $0.02.
I like @hishamhm's idea of specifying multiple directives as such. Another approach we discussed with @hbagdi was to use semicolons to separate multiple values for a directive ( |
Manually merged, thanks! |
This commit introduces a new shm, `kong_locks`, to be used by instances of lua-resty-lock across Kong or its libraries, if possible. Since #3543 bumped the mlcache dependency, the DB cache is the first consumer of this shm to store its locks, which helps in limiting the effects of LRU churning in certain workloads. More components should use this shm to store their resty-lock instances, especially instead of relying on the `kong` shm, which is to be considered "immutable". The chosen size for this shm is 8Mb: 1. In the not too far future, users should be able to customize the size of _any_ shm via configuration properties. Some additional work on top of #3530 is needed for this. 2. Such a size allows to store (based on estimations with a test script) about 65.000 lua-resty-lock items. While this number is very much workload specific, it should be appropriate even in situations where requests trigger cache misses in the runloop and the core, which would amount for up to 10, or maybe 15 locks (with very bad luck), which means we could still process several thousands of such cold requests concurrently, and comfortably. 3. Ideally, abstraction layers on top of eviction-sensitive shms should be built, in order to monitor LRU eviction on locks, or forbid them entirely on immutable shms. This commit is considered backwards-compatible and thus does not require the `kong_locks` shm to be defined.
This commit introduces a new shm, `kong_locks`, to be used by instances of lua-resty-lock across Kong or its libraries, if possible. Since #3543 bumped the mlcache dependency, the DB cache is the first consumer of this shm to store its locks, which helps in limiting the effects of LRU churning in certain workloads. More components should use this shm to store their resty-lock instances, especially instead of relying on the `kong` shm, which is to be considered "immutable". The chosen size for this shm is 8Mb: 1. In the not too far future, users should be able to customize the size of _any_ shm via configuration properties. Some additional work on top of #3530 is needed for this. 2. Such a size allows to store (based on estimations with a test script) about 65.000 lua-resty-lock items. While this number is very much workload specific, it should be appropriate even in situations where requests trigger cache misses in the runloop and the core, which would amount for up to 10, or maybe 15 locks (with very bad luck), which means we could still process several thousands of such cold requests concurrently, and comfortably. 3. Ideally, abstraction layers on top of eviction-sensitive shms should be built, in order to monitor LRU eviction on locks, or forbid them entirely on immutable shms. This commit is considered backwards-compatible and thus does not require the `kong_locks` shm to be defined. From #3550
I see that if we are trying to add multiple values for a directive, the later overrides the former value. |
Have you found a solution to this problem? |
Problem
Kong ships with an NGINX template which is rendered when Kong starts.
There exists no mechanisms to add/update any NGINX directive to the
nginx.conf
used to run Kong. To change or add any directive, user hasto use a custom NGINX template which has to be synced with Kong for a
release which introduces changes to Kong's template.
Including options in
kong.conf
to configure NGINX directives is not agood solution since the list will be endless.
This problem can be seen in #3010, #3323 and #3382.
Solution
There needs to be a flexible way to specify any NGINX directive
via Kong's config file without Kong needing to maintain a list of all
NGINX directives.
While a clean and ideal solution would be #2355, this commit
adopts a simpler as discussed like the one proposed in #2675.
NGINX directives can be specified using config variables with prefixes,
which help determine the block in which to place a directive.
eg:
nginx_proxy_add_header=Header-Name header-value
will add aadd_header Header-Name header-value;
directive in the proxy server block of Kong.nginx_http_lua_shared_dict=custom_cache 2k
will add a alua_shared_dict custom_cache 2k;
directive to HTTP block of Kong.