Skip to content

outbound: Discover profiles for each unique TCP target#698

Merged
olix0r merged 9 commits intover/accept-profilesfrom
ver/accept-profiles-tcp-split
Oct 10, 2020
Merged

outbound: Discover profiles for each unique TCP target#698
olix0r merged 9 commits intover/accept-profilesfrom
ver/accept-profiles-tcp-split

Conversation

@olix0r
Copy link
Member

@olix0r olix0r commented Oct 8, 2020

The proxy has classically discovered profiles & endpoints by looking at
each HTTP request's headers. This change removes all per-request
discovery. Instead, resolution is now done for each unique outbound TCP
target (regardless of whether the connection serves HTTP or not). This
eager resolution eliminates per-request cache binding; and supports
using TrafficSplit with non-HTTP services.

This has a few side effects:

  • The l5d-dst-override header is no longer honored.
  • When the application attempts to connect to a pod IP, the proxy no
    longer load balances these requests among all pods in the service.
    The proxy will now honor session-stickiness as selected by an
    application-level load balancer (see Session Stickiness only works with TLS backends linkerd2#4956).
  • TrafficSplits are only applied when a client targets a service's IP.
  • The proxy no longer performs DNS "canonicalization" to translate
    relative host header names to a fully-qualified form.

@olix0r
Copy link
Member Author

olix0r commented Oct 8, 2020

Depends on #697

olix0r and others added 7 commits October 8, 2020 18:59
The `AcceptHttp` service is stateful. It builds the underlying HTTP,
HTTP/2, and TCP service stacks lazily the first time they're needed.
This interacts badly with the derived implementation of `Clone`: if it's
cloned before the state is set, the state will only be set for the
clone, rather than for the original instance in the cache. Since
`Prefix` clones and oneshots the underlying service (`AcceptHttp`), this
means that we rebuild the HTTP, HTTP/2, and TCP stacks on every
connection to the same orig dest. This basically breaks caching for
everything other than service profile discovery, causing us to do new
destination discovery for every connection to the same original
destination. Which...isn't great.

This branch fixes this issue by removing the `Clone` impl from
`AcceptHttp` and putting it behind a buffer instead. In the future, it
may be possible to fix this in a nicer way, but this resolves the issue
for now.
Removes defunct identity tests per linkerd/linkerd2#4947
The proxy has classically discovered profiles & endpoints by looking at
each HTTP request's headers. This change removes all per-request
discovery. Instead, resolution is now done for each unique outbound TCP
target (regardless of whether the connection serves HTTP or not). This
eager resolution eliminates per-request cache binding; and supports
using `TrafficSplit` with non-HTTP services.

This has a few side effects:

- The `l5d-dst-override` header is no longer honored.
- When the application attempts to connect to a pod IP, the proxy no
  longer load balances these requests among all pods in the service.
  The proxy will now honor session-stickiness as selected by an
  application-level load balancer (see
  linkerd/linkerd2#4956).
- TrafficSplits are only applied when a client targets a service's IP.
- The proxy no longer performs DNS "canonicalization" to translate
  relative host header names to a fully-qualified form.
@olix0r olix0r changed the title outbound: Implement TrafficSplit for TCP traffic outbound: Discover profiles for each unique TCP target Oct 9, 2020
@olix0r olix0r marked this pull request as ready for review October 9, 2020 23:54
@olix0r olix0r requested a review from a team October 9, 2020 23:54
Copy link
Contributor

@hawkw hawkw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i was surprised by how simple the actual functional change is; most of this is actually just the test changes. the change itself is very straightforward! this looks good to me 👍

H: NewService<(HttpVersion, T)>,
{
pub fn new(target: T, server: Server, new_http: H, new_tcp: F, drain: drain::Watch) -> Self {
tracing::trace!("new AcceptHttp");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we probably don't need this, i stuck it in while debugging and forgot to take it out

Suggested change
tracing::trace!("new AcceptHttp");

Some(HttpVersion::Http1) => {
debug!("Handling as HTTP");
let http1 = if let Some(svc) = self.http1.clone() {
trace!("HTTP service already exists");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these were also from debugging but i thought they might actually be worth having.

pub profile: Option<profiles::Receiver>,
}

#[derive(Clone, Debug)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: while working on the test changes i realized that it might not be great to derive Debug for TcpLogical, since it has a MPSC receiver in it, which dumps a bunch of internal state that we don't care about...we might want a custom Debug impl for TcpLogical because of that.

not a blocker, can fix it later; just something i remembered while looking at this.

@olix0r olix0r merged commit 48c209b into ver/accept-profiles Oct 10, 2020
@olix0r olix0r deleted the ver/accept-profiles-tcp-split branch October 10, 2020 00:02
@olix0r olix0r restored the ver/accept-profiles-tcp-split branch October 10, 2020 16:41
@olix0r olix0r deleted the ver/accept-profiles-tcp-split branch May 25, 2021 15:47
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.

2 participants