Skip to content

Commit b33dbfd

Browse files
olix0rhawkw
andauthored
outbound: Discover profiles for each unique TCP target (#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 `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]>
1 parent 81ba3c7 commit b33dbfd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+963
-1568
lines changed

Cargo.lock

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -771,13 +771,11 @@ dependencies = [
771771
"linkerd2-metrics",
772772
"linkerd2-opencensus",
773773
"linkerd2-proxy-api",
774-
"quickcheck",
775774
"regex 1.3.9",
776775
"ring",
777776
"rustls",
778777
"tokio",
779778
"tokio-connect",
780-
"tokio-current-thread",
781779
"tokio-io",
782780
"tokio-rustls",
783781
"tonic",
@@ -840,7 +838,6 @@ dependencies = [
840838
"pin-project",
841839
"procinfo",
842840
"prost-types",
843-
"quickcheck",
844841
"rand 0.7.2",
845842
"regex 1.3.9",
846843
"serde_json",
@@ -882,7 +879,6 @@ dependencies = [
882879
"http 0.2.1",
883880
"indexmap",
884881
"linkerd2-app-core",
885-
"quickcheck",
886882
"tokio",
887883
"tower",
888884
"tracing",
@@ -904,7 +900,6 @@ dependencies = [
904900
"linkerd2-app-test",
905901
"linkerd2-metrics",
906902
"linkerd2-proxy-api",
907-
"quickcheck",
908903
"regex 0.1.80",
909904
"ring",
910905
"rustls",
@@ -933,7 +928,6 @@ dependencies = [
933928
"linkerd2-identity",
934929
"linkerd2-retry",
935930
"pin-project",
936-
"quickcheck",
937931
"tokio",
938932
"tower",
939933
"tracing",
@@ -1018,12 +1012,9 @@ dependencies = [
10181012
"futures 0.3.5",
10191013
"linkerd2-dns-name",
10201014
"linkerd2-error",
1021-
"linkerd2-stack",
10221015
"pin-project",
10231016
"tokio",
1024-
"tower",
10251017
"tracing",
1026-
"tracing-futures",
10271018
"trust-dns-resolver",
10281019
]
10291020

@@ -1094,7 +1085,6 @@ name = "linkerd2-exp-backoff"
10941085
version = "0.1.0"
10951086
dependencies = [
10961087
"futures 0.3.5",
1097-
"linkerd2-error",
10981088
"pin-project",
10991089
"quickcheck",
11001090
"rand 0.7.2",
@@ -1166,7 +1156,6 @@ dependencies = [
11661156
"pin-project",
11671157
"tokio",
11681158
"tokio-rustls",
1169-
"tokio-test",
11701159
]
11711160

11721161
[[package]]
@@ -1191,7 +1180,6 @@ dependencies = [
11911180
"http-body",
11921181
"linkerd2-error",
11931182
"linkerd2-metrics",
1194-
"linkerd2-stack",
11951183
"opencensus-proto",
11961184
"pin-project",
11971185
"tokio",
@@ -1254,9 +1242,7 @@ dependencies = [
12541242
"futures 0.3.5",
12551243
"linkerd2-error",
12561244
"pin-project",
1257-
"tokio",
12581245
"tower",
1259-
"tracing-futures",
12601246
]
12611247

12621248
[[package]]
@@ -1271,9 +1257,7 @@ dependencies = [
12711257
"linkerd2-stack",
12721258
"pin-project",
12731259
"tokio",
1274-
"tokio-test",
12751260
"tower",
1276-
"tower-test",
12771261
"tracing",
12781262
"tracing-futures",
12791263
]
@@ -1288,7 +1272,6 @@ dependencies = [
12881272
"linkerd2-error",
12891273
"linkerd2-proxy-core",
12901274
"tokio",
1291-
"tokio-test",
12921275
"tower",
12931276
"tracing",
12941277
"tracing-futures",
@@ -1307,15 +1290,12 @@ dependencies = [
13071290
"hyper",
13081291
"hyper-balance",
13091292
"indexmap",
1310-
"linkerd2-addr",
1311-
"linkerd2-dns",
13121293
"linkerd2-drain",
13131294
"linkerd2-duplex",
13141295
"linkerd2-error",
13151296
"linkerd2-http-box",
13161297
"linkerd2-identity",
13171298
"linkerd2-io",
1318-
"linkerd2-proxy-transport",
13191299
"linkerd2-stack",
13201300
"linkerd2-timeout",
13211301
"pin-project",
@@ -1348,11 +1328,9 @@ name = "linkerd2-proxy-resolve"
13481328
version = "0.1.0"
13491329
dependencies = [
13501330
"futures 0.3.5",
1351-
"indexmap",
13521331
"linkerd2-error",
13531332
"linkerd2-proxy-core",
13541333
"pin-project",
1355-
"tokio",
13561334
"tower",
13571335
"tracing",
13581336
]
@@ -1371,13 +1349,11 @@ dependencies = [
13711349
"linkerd2-error",
13721350
"linkerd2-identity",
13731351
"linkerd2-proxy-api",
1374-
"linkerd2-proxy-core",
13751352
"linkerd2-proxy-http",
13761353
"linkerd2-proxy-transport",
13771354
"linkerd2-stack",
13781355
"pin-project",
13791356
"prost-types",
1380-
"quickcheck",
13811357
"rand 0.7.2",
13821358
"tokio",
13831359
"tonic",
@@ -1405,7 +1381,6 @@ name = "linkerd2-proxy-transport"
14051381
version = "0.1.0"
14061382
dependencies = [
14071383
"async-stream",
1408-
"async-trait",
14091384
"bytes 0.5.4",
14101385
"futures 0.3.5",
14111386
"indexmap",
@@ -1417,7 +1392,6 @@ dependencies = [
14171392
"linkerd2-identity",
14181393
"linkerd2-io",
14191394
"linkerd2-metrics",
1420-
"linkerd2-proxy-core",
14211395
"linkerd2-stack",
14221396
"pin-project",
14231397
"ring",
@@ -2567,16 +2541,6 @@ dependencies = [
25672541
"tokio-io",
25682542
]
25692543

2570-
[[package]]
2571-
name = "tokio-current-thread"
2572-
version = "0.1.6"
2573-
source = "registry+https://github.com/rust-lang/crates.io-index"
2574-
checksum = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443"
2575-
dependencies = [
2576-
"futures 0.1.26",
2577-
"tokio-executor",
2578-
]
2579-
25802544
[[package]]
25812545
name = "tokio-executor"
25822546
version = "0.1.10"

linkerd/addr/src/lib.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ impl From<NameAddr> for Addr {
129129
}
130130
}
131131

132+
impl From<(Name, u16)> for Addr {
133+
fn from((n, p): (Name, u16)) -> Self {
134+
Addr::Name((n, p).into())
135+
}
136+
}
137+
132138
impl AsRef<Self> for Addr {
133139
fn as_ref(&self) -> &Self {
134140
self
@@ -137,11 +143,13 @@ impl AsRef<Self> for Addr {
137143

138144
// === impl NameAddr ===
139145

140-
impl NameAddr {
141-
pub fn new(name: Name, port: u16) -> Self {
146+
impl From<(Name, u16)> for NameAddr {
147+
fn from((name, port): (Name, u16)) -> Self {
142148
NameAddr { name, port }
143149
}
150+
}
144151

152+
impl NameAddr {
145153
pub fn from_str(hostport: &str) -> Result<Self, Error> {
146154
let mut parts = hostport.rsplitn(2, ':');
147155
let port = parts

linkerd/app/Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,9 @@ http = "0.2"
3939
hyper = "0.13.7"
4040
linkerd2-metrics = { path = "../metrics", features = ["test_util"] }
4141
linkerd2-proxy-api = { git = "https://github.com/linkerd/linkerd2-proxy-api", tag = "v0.1.14", features = ["arbitrary"] }
42-
quickcheck = { version = "0.9", default-features = false }
4342
ring = "0.16"
4443
rustls = "0.17"
4544
tokio-connect = { git = "https://github.com/carllerche/tokio-connect" }
4645
tokio-io = "0.1.6"
47-
tokio-current-thread = "0.1.4"
4846
tokio-rustls = "0.13"
4947
webpki = "0.21"

linkerd/app/core/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,3 @@ procinfo = "0.4.2"
100100
[dev-dependencies]
101101
linkerd2-proxy-api = { git = "https://github.com/linkerd/linkerd2-proxy-api", tag = "v0.1.14", features = ["arbitrary"] }
102102
prost-types = "0.6.0"
103-
quickcheck = { version = "0.9", default-features = false }

linkerd/app/core/src/addr_match.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ use linkerd2_addr::Addr;
33
use linkerd2_dns::{Name, Suffix};
44
use std::{net::IpAddr, sync::Arc};
55

6-
#[derive(Clone, Debug)]
6+
#[derive(Clone, Debug, Default)]
77
pub struct AddrMatch {
88
names: NameMatch,
99
nets: IpMatch,
1010
}
1111

12-
#[derive(Clone, Debug)]
12+
#[derive(Clone, Debug, Default)]
1313
pub struct NameMatch(Arc<Vec<Suffix>>);
1414

15-
#[derive(Clone, Debug)]
15+
#[derive(Clone, Debug, Default)]
1616
pub struct IpMatch(Arc<Vec<IpNet>>);
1717

1818
// === impl NameMatch ===

linkerd/app/gateway/src/config.rs

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,76 @@
11
use super::make::MakeGateway;
2-
use indexmap::IndexSet;
3-
use linkerd2_app_core::proxy::http;
4-
use linkerd2_app_core::{dns, transport::tls, Error};
2+
use linkerd2_app_core::{
3+
discovery_rejected, profiles, proxy::http, svc, transport::tls, Error, NameAddr, NameMatch,
4+
};
55
use linkerd2_app_inbound::endpoint as inbound;
66
use linkerd2_app_outbound::endpoint as outbound;
7-
use std::net::IpAddr;
7+
use std::net::SocketAddr;
88

99
#[derive(Clone, Debug, Default)]
1010
pub struct Config {
11-
pub suffixes: IndexSet<dns::Suffix>,
11+
pub allow_discovery: NameMatch,
1212
}
1313

14+
#[derive(Clone, Debug)]
15+
struct Allow(NameMatch);
16+
1417
impl Config {
15-
pub fn build<R, O, S>(
18+
pub fn build<O, P, S>(
1619
self,
17-
resolve: R,
1820
outbound: O,
21+
profiles: P,
22+
default_addr: SocketAddr,
1923
local_id: tls::PeerIdentity,
20-
) -> impl Clone
21-
+ Send
22-
+ tower::Service<
24+
) -> impl svc::NewService<
2325
inbound::Target,
24-
Error = impl Into<Error>,
25-
Future = impl Send + 'static,
26-
Response = impl Send
27-
+ tower::Service<
26+
Service = impl tower::Service<
2827
http::Request<http::boxed::Payload>,
2928
Response = http::Response<http::boxed::Payload>,
3029
Error = impl Into<Error>,
3130
Future = impl Send,
32-
> + 'static,
33-
>
31+
> + Send
32+
+ 'static,
33+
> + Clone
34+
+ Send
3435
where
35-
R: tower::Service<dns::Name, Response = (dns::Name, IpAddr)> + Send + Clone,
36-
R::Error: Into<Error> + 'static,
37-
R::Future: Send + 'static,
38-
O: tower::Service<outbound::HttpLogical, Response = S> + Send + Clone + 'static,
39-
O::Error: Into<Error> + Send + 'static,
40-
O::Future: Send + 'static,
41-
S: Send
42-
+ tower::Service<
36+
P: profiles::GetProfile<NameAddr> + Clone + Send + 'static,
37+
P::Future: Send + 'static,
38+
P::Error: Send,
39+
O: svc::NewService<outbound::HttpLogical, Service = S> + Clone + Send + 'static,
40+
S: tower::Service<
4341
http::Request<http::boxed::Payload>,
4442
Response = http::Response<http::boxed::Payload>,
45-
> + 'static,
46-
S::Error: Into<Error> + Send + 'static,
47-
S::Future: Send,
43+
> + Send
44+
+ 'static,
45+
S::Error: Into<Error>,
46+
S::Future: Send + 'static,
4847
{
49-
MakeGateway::new(resolve, outbound, local_id, self.suffixes.clone())
48+
svc::stack(MakeGateway::new(outbound, default_addr, local_id))
49+
.check_new_service::<super::make::Target, http::Request<http::boxed::Payload>>()
50+
.push(profiles::discover::layer(
51+
profiles,
52+
Allow(self.allow_discovery),
53+
))
54+
.check_new_service::<inbound::Target, http::Request<http::boxed::Payload>>()
55+
.into_inner()
56+
}
57+
}
58+
59+
impl svc::stack::FilterRequest<inbound::Target> for Allow {
60+
type Request = NameAddr;
61+
62+
fn filter(&self, target: inbound::Target) -> Result<NameAddr, Error> {
63+
// Skip discovery when the client does not have an identity.
64+
if target.tls_client_id.is_some() {
65+
// Discovery needs to have resolved a service name.
66+
if let Some(addr) = target.dst.into_name_addr() {
67+
// The service name needs to exist in the configured set of suffixes.
68+
if self.0.matches(addr.name()) {
69+
return Ok(addr);
70+
}
71+
}
72+
}
73+
74+
Err(discovery_rejected().into())
5075
}
5176
}

linkerd/app/gateway/src/gateway.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ pub(crate) enum Gateway<O> {
2020
impl<O> Gateway<O> {
2121
pub fn new(
2222
outbound: O,
23+
dst: NameAddr,
2324
source_identity: identity::Name,
24-
dst_name: NameAddr,
2525
local_identity: identity::Name,
2626
) -> Self {
2727
let fwd = format!(
2828
"by={};for={};host={};proto=https",
29-
local_identity, source_identity, dst_name
29+
local_identity, source_identity, dst
3030
);
3131
Gateway::Outbound {
3232
outbound,

0 commit comments

Comments
 (0)