Skip to content
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

outbound: Decouple endpoint & logical stacks #1002

Merged
merged 36 commits into from
May 11, 2021
Merged

Conversation

olix0r
Copy link
Member

@olix0r olix0r commented May 10, 2021

In #963 we began to split the outbound stack so that logical stack was
only built when a profile resolution was successful. However, this
incorrectly handled the case when a profile resolution included an
endpoint in its response.

This change introduces a outbound::switch_logical module that takes an
optional profile and builds either an endpoint stack or a logical stack.
Logical stacks always have a profile resolution and (named) logical
address. Endpoint stacks are built otherwise, optionally with metadata
from the profile resolution.

In order to test this--and to simplify/focus tests, in general--I've
moved tests from outbound/src/{tcp,http}/tests.rs into the modules
they test. Now each test more narrowly targets the stacks whose logic
they test, rather than composing an entire outbound stack. It was
becoming cumbersome to support mocking each component of the larger
stack. Now, we more intentionaly test targeted logic in each stack
(including the newly fixed endpoint/logical stack switching).

Supersedes #988

olix0r added 22 commits May 7, 2021 23:56
In #963 we began to split the outbound stack so that logical stack was
only built when a profile resolution was successful. However, this
incorrectly handled the case when a profile resolution included an
endpoint in its response.

This change introduces a `outbound::switch_logical` module that takes an
optional profile and builds either an endpoint stack or a logical stack.
Logical stacks always have a profile resolution and (named) logical
address. Endpoint stacks are built otherwise, optionally with metadata
from the profile resolution.

In order to test this--and to simplify/focus tests, in general--I've
moved tests from `outbound/src/{tcp,http}/tests.rs` into the modules
they test. Now each test more narrowly targets the stacks whose logic
they test, rather than composing an entire outbound stack. It was
becoming cumbersome to support mocking each component of the larger
stack. Now, we more intentionaly test targeted logic in each stack
(including the newly fixed endpoint/logical stack switching).

Supersedes #988
@olix0r olix0r requested a review from a team May 10, 2021 20:15
HSvc: svc::Service<http::Request<http::BoxBody>, Response = http::Response<http::BoxBody>>,
HSvc: Clone + Send + Sync + Unpin + 'static,
HSvc::Error: Into<Error>,
HSvc::Future: Send,
HTgt: From<(http::Version, T)> + svc::Param<http::Version> + 'static,
T: Param<SkipHttpDetection> + Clone + Send + Sync + 'static,
T: Param<Option<Skip>> + Clone + Send + Sync + 'static,
Copy link
Member Author

Choose a reason for hiding this comment

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

This change isn't strictly necessary. Can back it out if you'd prefer the other way. @hawkw

Copy link
Contributor

Choose a reason for hiding this comment

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

no strong preference; one fewer type param is nicer IMO

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.

overall this looks good, and i'm onboard with this direction, although i still think it could be good to have tests that exercise the entire outbound stack in addition.

i left some comments, mostly on minor nits. i tried to read through all the tests, but there's a lot of code here, so it would be nice to get more eyes on them...seems right as far as i can tell!

linkerd/app/outbound/src/discover.rs Outdated Show resolved Hide resolved
linkerd/app/outbound/src/discover.rs Outdated Show resolved Hide resolved
// Instantiate a service from the stack so that it instantiates the tracked inner service.
//
// The discover stack's buffer does not drive profile resolution (or the inner service)
// until the service is called?! So we drive this all on a background ask that gets canceled
Copy link
Contributor

Choose a reason for hiding this comment

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

The discover stack's buffer does not drive profile resolution (or the inner service) until the service is called?!

hmm, that seems...weird. should we try to change that behavior in a follow-up?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah... it's a little surprising. It would at least be good to understand it in more detail.

linkerd/app/outbound/src/discover.rs Show resolved Hide resolved
linkerd/app/outbound/src/discover.rs Outdated Show resolved Hide resolved
linkerd/app/outbound/src/ingress.rs Outdated Show resolved Hide resolved
linkerd/app/outbound/src/switch_logical.rs Outdated Show resolved Hide resolved
linkerd/app/outbound/src/switch_logical.rs Outdated Show resolved Hide resolved
linkerd/app/outbound/src/tcp/logical.rs Outdated Show resolved Hide resolved
linkerd/app/outbound/src/tcp/logical.rs Outdated Show resolved Hide resolved
@olix0r
Copy link
Member Author

olix0r commented May 11, 2021

@hawkw feedback addressed.

i also removed the (now unused) orig_dst field from Logical, which eliminates some of the awkward address stubbing we were doing in the ingress/gateway f5a4736

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.

okay, lgtm!

linkerd/app/outbound/src/discover.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@kleimkuhler kleimkuhler left a comment

Choose a reason for hiding this comment

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

This looks good 👍

linkerd/app/outbound/src/switch_logical.rs Outdated Show resolved Hide resolved
Co-authored-by: Kevin Leimkuhler <kevin@kleimkuhler.com>
@olix0r olix0r merged commit 626b2ee into main May 11, 2021
@olix0r olix0r deleted the ver/outbound-touchup branch May 11, 2021 19:03
olix0r added a commit to linkerd/linkerd2 that referenced this pull request May 12, 2021
This release simplifies internals so that endpoint-forwarding logic is
completely distinct from handling of load balanced services.

The ingress-mode outbound proxy has been simplified to *require* the
`l5d-dst-override` header and to fail non-HTTP communication. This
ensures that the ingress-mode proxy does not unexpectedly revert to
insecure communication.

Finally, a regression was recently introduced that caused all proxy logs
to be output with ANSI control characters. Logs are now output in
plaintext by default

---

* discover: replace `linkerd-channel` with `tokio-util` `PollSender` (linkerd/linkerd2-proxy#969)
* replace `linkerd-channel` with `tokio-stream` (linkerd/linkerd2-proxy#970)
* concurrency-limit: use `tokio-util`'s `PollSemaphore` (linkerd/linkerd2-proxy#968)
* http: Do not fail fuzz tests when all IO is not read (linkerd/linkerd2-proxy#973)
* transport: Fix orig-dst compilation on non-Linux targets  (linkerd/linkerd2-proxy#974)
* Update trust-dns to fix possible panic (linkerd/linkerd2-proxy#975)
*  addr: fix `to_http_authority` panic with IPv6 (linkerd/linkerd2-proxy#976)
* outbound: skip logical stacks when no profile is discovered (linkerd/linkerd2-proxy#963)
* split: change traffic splits to require a profile (linkerd/linkerd2-proxy#964)
* inbound: only build profile route stacks when a profile is resolved (linkerd/linkerd2-proxy#966)
* profiles: make receiver param in `route_request` non-optional (linkerd/linkerd2-proxy#967)
* outbound: move target types into stack modules (linkerd/linkerd2-proxy#971)
* outbound: only build logical stacks for profiles with logical addrs (linkerd/linkerd2-proxy#972)
* app: inbound: add fuzzer (linkerd/linkerd2-proxy#977)
* admin: Fail connections when HTTP detection fails (linkerd/linkerd2-proxy#979)
* reduce error boilerplate with `thiserror` (linkerd/linkerd2-proxy#980)
* app: inbound: fuzzer: generalise fuzzers and solve coverage build (linkerd/linkerd2-proxy#978)
* admin: Assume meshed connections are HTTP/2 (linkerd/linkerd2-proxy#982)
* chore: Fix deprecations on nightly (linkerd/linkerd2-proxy#983)
* fuzz: Add logging to fuzz targets (linkerd/linkerd2-proxy#985)
* fuzz: don't panic when the proxy closes the conn (linkerd/linkerd2-proxy#986)
* Commit lock files for fuzzers (linkerd/linkerd2-proxy#984)
* fuzz: allow client requests to fail  (linkerd/linkerd2-proxy#989)
* tower: update dependency to 0.4.7 (linkerd/linkerd2-proxy#990)
* outbound: Make the Endpoint::logical_addr field optional (linkerd/linkerd2-proxy#991)
* trace: explicitly disable ANSI terminal colors (linkerd/linkerd2-proxy#994)
* ingress: Require the l5d-dst-override header (linkerd/linkerd2-proxy#992)
* outbound: Do not support TCP-forwarding in ingress-mode (linkerd/linkerd2-proxy#995)
* Decouple tcp forward stack from Endpoint target (linkerd/linkerd2-proxy#996)
* Pickup linkerd-await wrapper in docker build (linkerd/linkerd2-proxy#999)
* docs: Add fuzzing report (linkerd/linkerd2-proxy#1000)
* tests: Use io::Error in mocked connector (linkerd/linkerd2-proxy#1001)
* outbound: Decouple endpoint & logical stacks (linkerd/linkerd2-proxy#1002)
olix0r added a commit to linkerd/linkerd2 that referenced this pull request May 18, 2021
This release simplifies internals so that endpoint-forwarding logic is
completely distinct from handling of load balanced services.

The ingress-mode outbound proxy has been simplified to *require* the
`l5d-dst-override` header and to fail non-HTTP communication. This
ensures that the ingress-mode proxy does not unexpectedly revert to
insecure communication.

Finally, a regression was recently introduced that caused all proxy logs
to be output with ANSI control characters. Logs are now output in
plaintext by default

---

* discover: replace `linkerd-channel` with `tokio-util` `PollSender` (linkerd/linkerd2-proxy#969)
* replace `linkerd-channel` with `tokio-stream` (linkerd/linkerd2-proxy#970)
* concurrency-limit: use `tokio-util`'s `PollSemaphore` (linkerd/linkerd2-proxy#968)
* http: Do not fail fuzz tests when all IO is not read (linkerd/linkerd2-proxy#973)
* transport: Fix orig-dst compilation on non-Linux targets  (linkerd/linkerd2-proxy#974)
* Update trust-dns to fix possible panic (linkerd/linkerd2-proxy#975)
*  addr: fix `to_http_authority` panic with IPv6 (linkerd/linkerd2-proxy#976)
* outbound: skip logical stacks when no profile is discovered (linkerd/linkerd2-proxy#963)
* split: change traffic splits to require a profile (linkerd/linkerd2-proxy#964)
* inbound: only build profile route stacks when a profile is resolved (linkerd/linkerd2-proxy#966)
* profiles: make receiver param in `route_request` non-optional (linkerd/linkerd2-proxy#967)
* outbound: move target types into stack modules (linkerd/linkerd2-proxy#971)
* outbound: only build logical stacks for profiles with logical addrs (linkerd/linkerd2-proxy#972)
* app: inbound: add fuzzer (linkerd/linkerd2-proxy#977)
* admin: Fail connections when HTTP detection fails (linkerd/linkerd2-proxy#979)
* reduce error boilerplate with `thiserror` (linkerd/linkerd2-proxy#980)
* app: inbound: fuzzer: generalise fuzzers and solve coverage build (linkerd/linkerd2-proxy#978)
* admin: Assume meshed connections are HTTP/2 (linkerd/linkerd2-proxy#982)
* chore: Fix deprecations on nightly (linkerd/linkerd2-proxy#983)
* fuzz: Add logging to fuzz targets (linkerd/linkerd2-proxy#985)
* fuzz: don't panic when the proxy closes the conn (linkerd/linkerd2-proxy#986)
* Commit lock files for fuzzers (linkerd/linkerd2-proxy#984)
* fuzz: allow client requests to fail  (linkerd/linkerd2-proxy#989)
* tower: update dependency to 0.4.7 (linkerd/linkerd2-proxy#990)
* outbound: Make the Endpoint::logical_addr field optional (linkerd/linkerd2-proxy#991)
* trace: explicitly disable ANSI terminal colors (linkerd/linkerd2-proxy#994)
* ingress: Require the l5d-dst-override header (linkerd/linkerd2-proxy#992)
* outbound: Do not support TCP-forwarding in ingress-mode (linkerd/linkerd2-proxy#995)
* Decouple tcp forward stack from Endpoint target (linkerd/linkerd2-proxy#996)
* Pickup linkerd-await wrapper in docker build (linkerd/linkerd2-proxy#999)
* docs: Add fuzzing report (linkerd/linkerd2-proxy#1000)
* tests: Use io::Error in mocked connector (linkerd/linkerd2-proxy#1001)
* outbound: Decouple endpoint & logical stacks (linkerd/linkerd2-proxy#1002)
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.

3 participants