Skip to content

implement traffic splitting on client policy HTTPRoutes#2034

Merged
hawkw merged 15 commits intoeliza/client-policy-apifrom
eliza/route-splitting
Dec 6, 2022
Merged

implement traffic splitting on client policy HTTPRoutes#2034
hawkw merged 15 commits intoeliza/client-policy-apifrom
eliza/route-splitting

Conversation

@hawkw
Copy link
Contributor

@hawkw hawkw commented Dec 2, 2022

Depends on #2029

This branch builds on #2021 and #2029 to implement traffic splitting
based on client policy HTTPRoute backends. This is everything necessary
to implement header-based routing using HTTPRoutes, by creating a route
that matches a header and routes to a different backendRef. In
addition, this means that we can also now do other forms of traffic
splitting (such as weights) with a HTTPRoute, as well.

The implementation here is pretty straightforward. Currently, the
traffic split middleware that's used for ServiceProfile traffic splits
(and for the top-level list of backends in a client policy lookup, which
are currently not used by the control plane) requires dynamically
updating the split service when the set of backends in the traffic split
changes. In the per-HTTPRoute case, however, this is not necessary, as
the set of HTTPRoutes is being watched by the client policy router, and
the whole stack for a route will be torn down and rebuilt if that
route's definition changes. Therefore, I've factored out the fixed
component of the traffic split (just shifting traffic across a weighted
distribution of services) from the dynamically updating component, so
that the client policy HTTPRoute traffic split can just build and
destroy fixed split middlewares. The dynamically changing traffic split
middleware is now implemented by mutating an inner fixed split
middleware.

@hawkw hawkw requested a review from a team as a code owner December 2, 2022 20:31
@hawkw hawkw marked this pull request as draft December 2, 2022 20:31
Base automatically changed from eliza/route-matching to eliza/client-policy-api December 6, 2022 17:32
@hawkw hawkw marked this pull request as ready for review December 6, 2022 17:35
@hawkw hawkw merged commit 3e60ed0 into eliza/client-policy-api Dec 6, 2022
@hawkw hawkw deleted the eliza/route-splitting branch December 6, 2022 17:35
hawkw added a commit that referenced this pull request Dec 6, 2022
This branch refactors the prototype client policy code to move the
discovery of client policies to still occur after profile discovery, but
before the HTTP logical stack. This means that SO_ORIGINAL_DST addresses
need not be stored in the `Logical` target type any longer, which I
think is significantly nicer, as we no longer have a `Logical` field
that's ignored by hashing and equality.

Instead, the client policy discovery now occurs in the stack produced by
`push_discover`. This is conceptually much more correct. In addition, it
allows us to remove the separate caching logic for client policy
lookups, and just use the same per-original-destination-address cache
that's used for service profile lookups. This simplifies the policy code
significantly, and allows moving stuff back out of
`linkerd-app-outbound` and into `linkerd-client-policy`, since the
policy receiver need no longer be wrapped in a `Cached` handle.

Depends on #2034
hawkw added a commit that referenced this pull request Dec 6, 2022
Depends on #2029

This branch builds on #2021 and #2029 to implement traffic splitting
based on client policy HTTPRoute backends. This is everything necessary
to implement header-based routing using HTTPRoutes, by creating a route
that matches a header and routes to a different `backendRef`. In
addition, this means that we can also now do other forms of traffic
splitting (such as weights) with a HTTPRoute, as well.

The implementation here is pretty straightforward. Currently, the
traffic split middleware that's used for ServiceProfile traffic splits
(and for the top-level list of backends in a client policy lookup, which
are currently not used by the control plane) requires dynamically
updating the split service when the set of backends in the traffic split
changes. In the per-HTTPRoute case, however, this is not necessary, as
the set of HTTPRoutes is being watched by the client policy router, and
the whole stack for a route will be torn down and rebuilt if that
route's definition changes. Therefore, I've factored out the fixed
component of the traffic split (just shifting traffic across a weighted
distribution of services) from the dynamically updating component, so
that the client policy HTTPRoute traffic split can just build and
destroy fixed split middlewares. The dynamically changing traffic split
middleware is now implemented by mutating an inner fixed split
middleware.
hawkw added a commit that referenced this pull request Dec 6, 2022
This branch refactors the prototype client policy code to move the
discovery of client policies to still occur after profile discovery, but
before the HTTP logical stack. This means that SO_ORIGINAL_DST addresses
need not be stored in the `Logical` target type any longer, which I
think is significantly nicer, as we no longer have a `Logical` field
that's ignored by hashing and equality.

Instead, the client policy discovery now occurs in the stack produced by
`push_discover`. This is conceptually much more correct. In addition, it
allows us to remove the separate caching logic for client policy
lookups, and just use the same per-original-destination-address cache
that's used for service profile lookups. This simplifies the policy code
significantly, and allows moving stuff back out of
`linkerd-app-outbound` and into `linkerd-client-policy`, since the
policy receiver need no longer be wrapped in a `Cached` handle.

Depends on #2034
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant