outbound: Discover profiles for each unique TCP target#704
Conversation
`RequestFilter` and `Admit` are basically exactly the same. This change moves `RequestFilter` into the `stack` crate and moves all `Admit` implementations to `RequestFilter`. This change also restores a `Stack` helper for `RequestFilter`, as there are now many uses.
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. Co-authored-by: Eliza Weisman <[email protected]>
hawkw
left a comment
There was a problem hiding this comment.
Overall, this looks great, although I basically just clicked "viewed" on all the test changes I made --- we may want another set of eyes on that part.
Because we're no longer relying on DNS name canonicalization, I think this closes linkerd/linkerd2#4660 and linkerd/linkerd2#2706. :)
| type Service = Gateway<O::Service>; | ||
|
|
||
| fn call(&mut self, target: inbound::Target) -> Self::Future { | ||
| fn new_service(&mut self, (profile, target): Target) -> Self::Service { |
There was a problem hiding this comment.
this looks much nicer as a new_service! <3
| R::Resolution: Unpin + Send, | ||
| I: tokio::io::AsyncRead + tokio::io::AsyncWrite + std::fmt::Debug + Unpin + Send + 'static, | ||
| { | ||
| let watchdog = self.proxy.cache_max_idle_age * 2; |
There was a problem hiding this comment.
nit/tioli: seems like we could just stick a fn watchdog_timeout on Config or on Proxy?
There was a problem hiding this comment.
will address this in a followup cleanup
| .push_on_response( | ||
| svc::layers() | ||
| // Strips headers that may be set by this proxy. | ||
| .push(http::strip_header::request::layer(DST_OVERRIDE_HEADER)) | ||
| .push(svc::layers().box_http_response()), | ||
| ) |
There was a problem hiding this comment.
since we no longer honor DST_OVERRIDE, does this still need to be here at all? or can we just stop caring about it?
There was a problem hiding this comment.
We should continue to strip the header through at least the stable release so that we're not all-of-a-sudden passing through the header if it's set by config.
This release overhauls the discovery and routing logic implemented by the proxy: instead of looking at HTTP request metadata for service discovery, the outbound proxy now exclusively use each connection's target IP:PORT. 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. - `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. --- * Unify RequestFilter and Admit middlewares (linkerd/linkerd2-proxy#692) * Only allow name-based profile discovery for inbound requests (linkerd/linkerd2-proxy#695) * outbound: initial tests for TCP mTLS (with fewer moving parts) (linkerd/linkerd2-proxy#693) * Stop honoring DESTINATION_GET_* configuration (linkerd/linkerd2-proxy#696) * stack: add SwitchReady service (linkerd/linkerd2-proxy#694) * telemetry: Remove trailing comma in build_info labels (linkerd/linkerd2-proxy#699) * Update Rust to 1.47.0 (linkerd/linkerd2-proxy#701) * cache: Delete benchmarks (linkerd/linkerd2-proxy#705) * outbound: Discover profiles for each unique TCP target (linkerd/linkerd2-proxy#704)
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
TrafficSplitwith non-HTTP services.This has a few side effects:
l5d-dst-overrideheader is no longer honored.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).
TrafficSplitsare only applied when a client targets a service's IP.relative host header names to a fully-qualified form.
Co-authored-by: Eliza Weisman [email protected]