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
Removes TrafficSplit in favor of ForwardToTarget #57
Conversation
/assign @bowei |
fixes issue: #58 |
What decision parameters are we using here to limit the scope of what is included in the core API and what is part of extensions? This is one of those areas where implementations will have different implementations and behaviors. |
api/v1alpha1/trafficsplit_types.go
Outdated
// Support: extended | ||
// | ||
// +optional | ||
Filter *TrafficSplitFilter `json:"filter,omitempty"` |
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.
TODO: Should Filter
be invalid for passthrough tls connections?
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 yes. This should be valid only for HTTP routes. Filter
should not be interpreted for TCP routes all together, no matter it is plain-text or TLS pass through.
@hbagdi I believe the decision is "do most implementations support this feature". How it's supported is up to the implementation. IMO most implementations do support percentage-based traffic splitting. Do you disagree? Are there any other properties presented in this PR that you feel most implementations do not support... maybe Selector? |
I think selector is not a problem. Traffic splitting itself is a common enough construct but not all providers, especially cloud providers and managed offerings don't support injecting headers specifically for different splits. Most have support for injecting headers but not different headers in context of splits. |
@hbagdi I marked the |
I think it is fair to add support for filters and transformation but it would be better to do that in one place rather several different. How do you plan to connect TrafficSplit with Route? |
TODO:
|
api/v1alpha1/trafficsplit_types.go
Outdated
} | ||
|
||
// TrafficSplitHeaderFilter defines the filter behavior for a request match. | ||
type TrafficSplitHeaderFilter 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.
It seems to me this is more of Action, i.e. what happens to a request, than Filter.
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.
Manipulating a request is considered a filter in terms of Service API's. PTAL at the route types as a reference implementation.
api/v1alpha1/trafficsplit_types.go
Outdated
// Support: Extended | ||
// | ||
// +optional | ||
Add map[string]string `json:"add,omitempty"` |
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 a header with a given name already exists in the request, will this become a replace? Or it should be configurable, i.e. whether add or replace?
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.
@yiyangy I believe that is implementation-specific. cc: @bowei @youngnick
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.
Yes, for Contour we chose to make Add include an implicit replace in the case the header already existed, but I don't know if we want to dictate that at this level.
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.
@yiyangy note that api/v1alpha1/trafficsplit_types.go
has been removed in the latest iteration of the PR.
api/v1alpha1/trafficsplit_types.go
Outdated
// Support: Extended | ||
// | ||
// +optional | ||
Selector *metav1.LabelSelector `json:"selector,omitempty"` |
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.
Shall this Selector be at the upper level i.e. TrafficSplitSpec? In the sense that for all the traffic matches Selector, the traffic is split among multiple rules with each rule carrying a weight. In case I misunderstand, could you please maybe give an example to elaborate on the use of Selector?
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.
@yiyangy config/samples/networking_v1alpha1_trafficsplit.yaml
provides an example, PTAL.
@hbagdi xRoute performs transformations prior to routing traffic. We need the ability to support post-routing transformations for use cases such as Knative. This is why I added The following is an example usage of
|
f74e0fc
to
a9a1497
Compare
This could easily be confused with the SMI trafficsplit. I'm not sure that we should add more CRD types, it seems likely that if we go down this path, the number of types will grow very large. I cases like this, I think that a brief implementation survey is useful to give context to the design. Many ingress controllers already have support for this feature; how do they do it and what are the outcomes of theirs approaches? |
It's a good question regarding traffic spit, someone on the SMI side even mentioned trying to merge these two or to use the same resource, trying to find the reference. |
api/v1alpha1/httproute_types.go
Outdated
|
||
// Weight specifies the proportion of traffic to be forwarded to a targetRef. | ||
// A valid weight value is 0-100. The sum of weights across targetRefs must | ||
// equal 100. If only one targetRef is specified, weight is ignored and all |
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.
Another option is that instead of weight specifying the fraction, the fraction of traffic to be forwarded to a targetRef is computed as weight / (sum of all weights in targetRefs). Then the constraint of "A valid weight value is 0-100. The sum of weights across targetRefs must equal 100" can be removed.
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.
@yiyangy thanks for the review. I've updated the godocs based on your feedback.
f298fa1
to
3e83163
Compare
After some discussion about multicluster implications last week, I spent some time writing a doc that shows how this could work with multicluster services. At a high level, the theory is that traffic splitting as defined by Service APIs is focused on splitting traffic between Services. In a multicluster scenario, traffic can further be segmented by configuring how much traffic is distributed to each cluster. That would be accomplished either on the Service or ServiceExport resource. I've run that by @JeremyOT to confirm that this is compatible with his vision of multicluster services, and it sounds like it is. Would love additional feedback on that doc to ensure the approach makes sense. The doc is entirely based on the approach proposed by this PR, just translating it to multicluster use cases. If there's general consensus on that, I think we're good to proceed here as well. |
apis/v1alpha1/httproute_types.go
Outdated
// If only one targetRef is specified, weight is ignored and all traffic is | ||
// forwarded to the targetRef. If multiple targetRefs are specified without | ||
// weight, traffic is evenly distributed across all targetRefs. |
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.
Consider making weight required and using CRD defaults to set a default value. We can simplify by e.g. using weight: 1 when not specified. This makes behavior intuitive when a weight isn't supplied, and makes weighting functionality more discoverable as users will see a value to play with when viewing their configuration.
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.
@JeremyOT commit 9abadaa
updates weight
based on your feedback above. Thanks for the review.
9abadaa
to
d91ef3b
Compare
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.
/lgtm
/assign @bowei |
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 the work on this! Just had a couple small nits.
/lgtm
// Weight specifies the proportion of traffic to be forwarded to a targetRef, | ||
// computed as weight/(sum of all weights in targetRefs). The following example | ||
// sends 70% of traffic to service "my-trafficsplit-sv1" and 30% of the traffic | ||
// to service "my-trafficsplit-sv2": |
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.
Nit: It would be good to clarify that weight is not actually a percentage and that all weights do not need to add up to 100.
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.
@robscott commit d7e4c20
addresses your comment above.
// If only one targetRef is specified, weight is ignored and all traffic is | ||
// forwarded to the targetRef. If unspecified, defaults to 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.
Nit: I don't think we need this clarification. Weight doesn't need to be ignored. If there is only forwardTo it is guaranteed to include 100% of the total weight, even if that is only 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.
@robscott commit d7e4c20
addresses your comment above.
Thanks! /lgtm |
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: bowei, danehans 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 |
Currently,
TrafficSplit
is scaffolding. This PR removesTrafficSplit
in favor of implementing traffic splitting withinForwardToTarget
.forwardTo
to allow forwarding to multiple targets (i.e. destination objects).weight
target attribute used byforwardTo
to distribute traffic among multiple targets.Partially fixes #58.