-
Notifications
You must be signed in to change notification settings - Fork 25
Conversation
@@ -7,6 +7,21 @@ function _M.get_backends_data() | |||
return configuration_data:get("backends") | |||
end | |||
|
|||
function _M.new_backends() |
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.
I think the convention is to name these kind of functions _handler
, no? i.e backends_handler
in this case.
--
Also since you are using this only locally, you don't have to export it. You can do
local function backends_handler()
...
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.
Oh wait this is just for extracting request body. IMO we should not make it backends specific - there's nothing in the function body that's backends specific - this should just be a helper function that returns request body and nil
or in case of error nil
and error message
ngx.req.read_body() | ||
local backends = _M.new_backends() | ||
if not backends then | ||
ngx.log(ngx.ERR, "dynamic-configuration: POST carries empty response body") |
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.
dynamic-configuration
I'm not sure what value this adds. Can you describe a real use case?
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.
Other users might see the error, and see that it originated from this line in configuration.lua, but still might not know what "component" of ingress-nginx is not working. Given the annotation is named dynamic-configuration
, I figured that this is a good way of making error logs from this lua module more meaningful.
test/e2e/framework/framework.go
Outdated
@@ -270,7 +270,7 @@ func UpdateDeployment(kubeClientSet kubernetes.Interface, namespace string, name | |||
return err | |||
} | |||
|
|||
err = WaitForPodsReady(kubeClientSet, 60*time.Second, replicas, namespace, metav1.ListOptions{ | |||
err = WaitForPodsReady(kubeClientSet, 90*time.Second, replicas, namespace, metav1.ListOptions{ |
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.
was flaky?
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.
yep :/
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.
probably started to be an issue with 60s because you're spinning up 30 replicas
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.
haha yeah, I'm pretty sure that's it.
|
||
cm.Data["client-body-buffer-size"] = "1k" | ||
_, updateErr := f.KubeClientSet.CoreV1().ConfigMaps("ingress-nginx").Update(cm) | ||
Expect(updateErr).ToNot(HaveOccurred()) |
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.
There's no helper function in the test framework for updating configmap? If not I suggest we extract it out into the framework code so that it can be reused.
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.
I'll take a closer look. I notice that Zenara made a similar updateConfigmap method in her session affinity PR as well, so definitely should be made generic if there isn't already a way.
Expect(getErr).ToNot(HaveOccurred()) | ||
oldClientBodyBufferSize, oldClientBodyBufferSizeExists := cm.Data["client-body-buffer-size"]; | ||
|
||
cm.Data["client-body-buffer-size"] = "1k" |
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.
is this the lowest possible value?
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.
From here: http://nginx.org/en/docs/syntax.html - I think so. Could also always make it 0 to make sure it such that it's always writing out to the temp file. What do you think?
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.
if possible I'd go lower than this so that we don't have to spin up 30 replicas in 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.
I think 0
means never write to temp file
--
reading http://nginx.org/en/docs/syntax.html I think you can set in bytes
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.
Makes sense. Re-read that link, so without suffix denotes bytes.
Will do, thanks Elvin
@@ -7,6 +7,21 @@ function _M.get_backends_data() | |||
return configuration_data:get("backends") | |||
end | |||
|
|||
local function fetch_request_body() | |||
ngx.req.read_body() | |||
local backends = ngx.req.get_body_data() |
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.
just body
? since this is not backends specific
Set("Host", "foo.com"). | ||
End() | ||
Expect(len(errs)).Should(BeNumerically("==", 0)) | ||
Expect(resp.StatusCode).Should(Equal(http.StatusOK)) |
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.
what's this for? we already assert that backend i s available at https://github.com/Shopify/ingress/pull/44/files#diff-8700c46a8379c603b5e41ccbaff6b71eR60
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.
I think you wanna send this request after updating the client max body size, to make sure we parsed request body correctly
_, updateErr := f.KubeClientSet.CoreV1().ConfigMaps("ingress-nginx").Update(cm) | ||
Expect(updateErr).ToNot(HaveOccurred()) | ||
|
||
replicas := 4 |
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 replica is not enough to generate a payload with sie of over 1 byte?
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.
Not enough. I'm not entirely certain why.
Did some looking into upstream, might be possibly happening because Nginx might be pre-reading part of the request body. If it's able to pre-read the entire request body in its pre-read buffer - it might not even check the client_body_buffer_size
.
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.
But 2 replicas does look like it is enough :)
if not backends then | ||
-- request body might've been wrote to tmp file if body > client_body_buffer_size | ||
local file_name = ngx.req.get_body_file() | ||
local file = assert(io.open(file_name, "rb")) |
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.
what does assert
do? what happens if io.open
fails?
local file_name = ngx.req.get_body_file() | ||
local file = assert(io.open(file_name, "rb")) | ||
backends = file:read("*all") | ||
file:close() |
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.
what happens any of this function calls fail?
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.
lines 18, 19 should be safe.
file:read
& file:close
will return a nil if the read or close operations are problematic.
And then since backends
is nil, this will be handled appropriately here: https://github.com/Shopify/ingress/pull/44/files#diff-27d52aa3bacfc9feff2d5eb208af0a17R52
ngx.log(ngx.ERR, "dynamic-configuration: POST carries empty response body") | ||
ngx.status = ngx.HTTP_BAD_REQUEST | ||
return | ||
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 is a change of behaviour - i can not think of anything bad with it, but also don't see why it it necessary. Did you add it merely so that you can assert for absence of this logs in the e2e 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.
The intention with this is to not update the config if the request_body is nil
, as we were doing previously. This could be problematic, and is essentially a silent failure mode - since there are no symptoms i.e. 200 was being returned.
Understandably, if the balancer module cannot parse the backends data, then it doesn't sync the update - so the failure is somewhat limited, but I still think that the logging and 5xx response increases visibility here.
00880b8
to
f593663
Compare
Actually read from the file Logs probably shouldn't assume knowledge of implementation detail Typos Added integration test, and dynamic update config refactor Don't force the 8k default Minimal test case to make the configuration/backends request body write to temp file Leverage new safe config updating methods, and use 2 replicas instead of 4
f593663
to
d4a395c
Compare
Closing in favour of kubernetes#2408 |
Superseded by kubernetes#2408
What this PR does / why we need it:
nil
if the controller POST body is larger than 10m.Which issue this PR fixes
Special notes for your reviewer:
client-body-buffer-size
to be set to1k
so I can reproduce the problem.r/ @ElvinEfendi @zrdaley @fmejia97