-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Ingress GA, updated KEP, merged review comments (recovered version of #1036) #1113
Conversation
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 nit but overall /lgtm
f8bba27
to
3994b90
Compare
/assign @thockin @cmluciano |
cc: @liggitt |
@@ -425,9 +436,10 @@ type IngressBackend struct { | |||
} |
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 API server will automatically populate the Resource field below.
...
If both ServiceName and Resource are specified, then they must reference the same Service object.
this sounds like cross-field defaulting, which got us in trouble with workload label selectors. consider the following scenario:
- user creates ingress not knowing about the new fields, populating service name with "foo"
- the apiserver populates resource with
type: Service, name: foo, apiGroup: ""
- the user modifies the ingress to change service name to "bar"
- apiserver fails validation because service name and resource.name no longer match
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.
Agree. Can we call this a one-of without a discriminator (we have high confidence it will only be 2 options)? Do we need to structure it as below?
BackendType string
Service ServicBackend // {name string, port int or string}
Resource v1.TypedLocalObjectReference
Or can we leave it like this get away with it?
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'd also like to consider not using IntOrString and instead doing something like:
Port BackendPort
type BackendPort {
Number int
Name string
}
Do we need a discriminator if we know it is A or B and there will never be a C ?
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 not, as all clients know they have to reset the other value.
As a side note, Name
is usually used as a key for associative lists though, so that's slightly confusing outside the context.
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.
@thockin I would even like to have just an int32
, but I think this kind of change is bigger than beta -> GA
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've changed the proposal to have a one-of union between ServiceBackend, Resource. If someone wants to reference a Service using the Resource, that should still be ok, just more verbose for them.
@thockin -- is IntOrString considered something we wish to move away from?
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.
IntOrString is generally seen as a mistake at this point.
If I interpret @apelisse correctly, he wants a discriminator field. Is that right?
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 they can get away without the discriminator since there are no other non-union members in that structure and it's not embedded anywhere.
My "Probably not" was an answer to:
Do we need a discriminator if we know it is A or B and there will never be a C ?
// Prefix - matches based on a URL path prefix split | ||
// by '/'. This is not a substring match. For example: | ||
// "/foo/bar" will match "/foo/bar", "/foo/bar/abc", but | ||
// will not match "/foo/barzzz". A Prefix Path of "/" will |
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 most common semantic? It's different from other things I have seen, e.g. Istio and Envoy (I think) would match /foo/barzzz and require 2 rules to express /foo/bar (exact) and /foo/bar/* (prefix). I though nginx did too but I can't tell from docs...
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.
Envoy has a few options to determine the route that it is matching on.
-
RouteMatch prefix validates that the prefix specified matches the beginning of the :path header
-
RouteMatch path is similar to the Exact case that Tim mentioned below. It validates that the path matches the :path header exactly after the query string is removed.
-
RouteMatch regex utilizes the C++ std::regex semantics to match the entire path specified in the :path header (minus the query bits). This does not work if only a subset of the :path header matches.
-
There is also a new safe_regex that will utilize the Google RE2 library. This new option is under development and is a response to some unsafe (normally user provided) regular expressions that could cause Envoy to crash.
Nginx locations also have similar options but rely on several key symbols for exact vs more fuzzy matching
I'm not sure if this helps much but figured it would at least add some more context in comparison to a few open source implementations.
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.
/foo/bar (exact) and /foo/bar/* (prefix).
Same for nginx http://nginx.org/en/docs/http/ngx_http_core_module.html#location
location = /foo/bar {} -> exact match
location /foo/bar {} -> /foo/bar/*
Just in case, ingress-nginx does not provide "exact match" locations.
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.
location /foo/bar {} -> /foo/bar/*
I'm not sure if this is the case.
Nginx matches /foo/barzzz
in this case. It is a string prefix match and not a path 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.
Add clarification of the behavior
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.
GCE will implement as "/foo/bar/*".
Nginx will implement as location "/foo/bar/"
and location "=/foo/bar"
. (prefix + equality)
Envoy will use path match.
It does not seem like a good idea to define this as string-based matching "/foobar", as that has fewer use cases and somewhat unexpected behavior.
@@ -425,9 +436,10 @@ type IngressBackend struct { | |||
} |
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.
Agree. Can we call this a one-of without a discriminator (we have high confidence it will only be 2 options)? Do we need to structure it as below?
BackendType string
Service ServicBackend // {name string, port int or string}
Resource v1.TypedLocalObjectReference
Or can we leave it like this get away with it?
@@ -425,9 +436,10 @@ type IngressBackend struct { | |||
} |
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'd also like to consider not using IntOrString and instead doing something like:
Port BackendPort
type BackendPort {
Number int
Name string
}
Do we need a discriminator if we know it is A or B and there will never be a C ?
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 have concerns about API changes in ingress, please check the details in my other comments.
Thanks for attention your heavy production user (>70
production clusters with >10000
ingress).
@@ -425,9 +436,10 @@ type IngressBackend struct { | |||
} |
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.
@thockin I would even like to have just an int32
, but I think this kind of change is bigger than beta -> GA
I've tried to address many of the comments above, but I'm fairly certain that there are some that are missed. Please take a look. We might just want to merge the update into the repo to cleaner diff and better discussion. |
@thockin probably should merge this and keep accumulating comments on a new PR. |
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.
lots of open comments
Interoperability between versions will be as follows: | ||
|
||
1. v1beta1 will default to `ImplementationSpecific`. | ||
1. v1 will default to `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.
Problem.
...says "Adding a new field with a default value: the default values must be semantically equivalent in all currently supported API versions."
I am struggling to recall the exact reason for this rule. @liggitt is better at this game than me.
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.
Defaulting to a different value in a new version is perfectly fine. The emphasis on the rule is on "currently supported versions", so that the current implicit behavior is maintained.
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.
That said, would it be better to make v1 writers specify a PathType (e.g. make it required with no default in v1)? The downside is it makes every consumer be explicit in v1, which makes the manifests more verbose. The upside is it makes every consumer be explicit in v1, which reduces surprise.
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.
That is a handy doc -- is there any plan to merge the content into the API conventions doc? The current "defaults" section is pretty short.
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.
Changing to require being explicit, let's see how we feel about the (slight) increase in verbosity.
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.
Actually -- wouldn't defaulting to ImplementationSpecific be more behavior preserving?
// Service is the name of the referenced service. The service must exist in | ||
// the same namespace as the Ingress object. | ||
// +optional | ||
Service string |
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.
shouldnt this be called "Name"
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 was in response to @apelisse 's comment about the use of the "Name" field as reserved for key-like.
It is more natural as "Name".
@@ -425,9 +436,10 @@ type IngressBackend struct { | |||
} |
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.
IntOrString is generally seen as a mistake at this point.
If I interpret @apelisse correctly, he wants a discriminator field. Is that right?
Note: I'm clicking on "resolve conversation" as a way to keep track of what has been merged into the text and to make the github review page more readable. Does not mean discussion has been resolved, please keep commenting. |
95b5da5
to
91c87b7
Compare
91c87b7
to
2951204
Compare
There were are some comments around the newly introduced union types; we will resolve them as part of the API review process, I think on the general direction there is consensus. |
Let's merge and iterate. This is close. /lgtm |
@thockin -- needs relgtm due to ToC verify issue |
Thanks! /lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: bowei, thockin 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 |
This is a recovered version of #1036, which I closed by accident.