-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Add a validating webhook for ingress sanity check #3802
Conversation
@tjamet first, thank you for working on this!
|
@tjamet as you said, we need tests for this :) |
ings := n.store.ListIngresses() | ||
ings = append(ings, &ingress.Ingress{*ing, annotations.NewAnnotationExtractor(n.store).Extract(ing)}) | ||
|
||
// sort Ingresses using the CreationTimestamp field |
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 not required because ListIngresses alredy sorts the ingresses
@aledbf thanks for the fast feedback Indeed I will then work on tests and documentation! |
Yes, I saw that but I am not sure about the webhook behavior with multiple deployments |
This PR may require API review. If so, when the changes are ready, complete the pre-review checklist and request an API review. Status of requested reviews is tracked in the API Review project. |
Also fixes #3588 |
@tjamet thanks for working on this! It'd be great if you describe your approach, discuss how much overhead this is adding to the core event loop, and why would I not want to have this always on. |
40a177d
to
da477d0
Compare
@aledbf I am seeing so far 2 parameters that can change the set of ingresses considered for configuration generation in a given controller:
Following your comment, I added the filter based on the namespace name as well for to behave consistently with the deployment. This should handle all combinations of The approach @ElvinEfendi is pretty simple in the end, it consists of exposing, outside of the core event loop an HTTP handler, compliant with Kubernetes validating webhook interface, to ensure any ingress that is about to be inserted in the cluster would generate a syntactically valid configuration together with the rest of the known ingresses using the pre-existing features. This handler should be exposed through a service to a ValidatingWebhookConfiguration object. As this handler is run outside of the core event loop, I have tested a benchmark that shows the following results (reported by
Because the request is served through a service to using the ingress controller as a backend, webhook requests are load-balanced through all ingress controllers and hence reduces the load on a single pod in case multiple ingresses are inserted at the same time. Another option to get better performances could be to drop the test with all pre-existing ingresses, which could probably be good enough to detect most configuration errors (syntax errors mainly). Regarding the default enabling of the feature, I would tend to, as a system operator, to recommend to enable it systematically. |
da477d0
to
61f6d32
Compare
61f6d32
to
a0a4015
Compare
👍
This must be optional (at least for now)
We can provide a script like https://gist.github.com/aledbf/11b3b4f882c632d021532edda8a5dc52 (I need to cleanup that) to use the feature already available in k8s to generate such certificate |
Sure!
This could also be integrated afterwards to the helm chart, that I could contribute to as well Regarding impact on resources, here are graphs, with the deployment in the middle. |
50dd1ab
to
fd69b0b
Compare
Just a silly question, would this validating webhook reject ingress resource that are valid for ingress controller of other kind? For example, the regular expression syntax for traefik is weird and would cause nginx ingress controller crash, if I deploy nginx ingress controller with this validating webhook, can I use traefik within the same cluster? (To be honest, the metrics endpoint for traefik is way more useful than nginx's) |
fd69b0b
to
21efe30
Compare
The validating webhook is filtering on the In case both ingresses are run with the same class, both ingress controllers would generate a configuration for the ingress and hence the validating webhook will check the validity of the generated configuration |
Hi, |
@tjamet please rebase and squash the commits |
21efe30
to
5e6478c
Compare
Rebased and commits squashed |
@tjamet please rebase. After that, I plan to build a dev image to test and merge this PR |
In case some ingress have a syntax error in the snippet configuration, the freshly generated configuration will not be reloaded to prevent tearing down existing rules. Although, once inserted, this configuration is preventing from any other valid configuration to be inserted as it remains in the ingresses of the cluster. To solve this problem, implement an optional validation webhook that simulates the addition of the ingress to be added together with the rest of ingresses. In case the generated configuration is not validated by nginx, deny the insertion of the ingress. In case certificates are mounted using kubernetes secrets, when those changes, keys are automatically updated in the container volume, and the controller reloads it using the filewatcher. Related changes: - Update vendors - Extract useful functions to check configuration with an additional ingress - Update documentation for validating webhook - Add validating webhook examples - Add a metric for each syntax check success and errors - Add more certificate generation examples
5e6478c
to
1cd17cd
Compare
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: ElvinEfendi, tjamet The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Thanks @tjamet! |
This is really cool. Thanks @tjamet. |
What this PR does / why we need it:
Running nginx ingress controller in production for a while, we are pretty happy about it, but we occasionally have an issue where an ingress with a corrupted configuration is injected, and prevents from any other future update of the ingress nginx configuration.
Subsequently, we need to find out the ingress causing problems and fix it.
This PR increases the feedback loop by allowing, optionally, to reject the ingress, before it gets inserted and hence preserves the sanity of the configuration.
Once the patch is applied, and the controller configured, this is the user experience in case of an invalid ingress:
Which issue this PR fixes (optional, in
fixes #<issue number>(, fixes #<issue_number>, ...)
format, will close that issue when PR gets merged): fixes #fixes #2833
fixes #3218
fixes #3435
fixes #3459
Special notes for your reviewer:
I am aware that this PR needs testing and documentation.
In case the option of adding this feature is accepted, I will as well contribute documentation and tests.