Add `policyController.probeNetworks` configuration value (#9091)

Closes #8945 

This adds the `policyController.probeNetworks` configuration value so that users
can configure the networks from which probes are expected to be performed.

By default, we allow all networks (`0.0.0.0/0`). Additionally, this value
differs from `clusterNetworks` is that it is a list of networks, and thus we
have to join the values in the Helm templating.

Signed-off-by: Kevin Leimkuhler <kleimkuhler@icloud.com>
This commit is contained in:
Kevin Leimkuhler 2022-08-05 10:43:22 -06:00 committed by GitHub
parent b15d5bb64b
commit c6693a5ae3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 139 additions and 12 deletions

View File

@ -175,6 +175,7 @@ Kubernetes: `>=1.21.0-0`
| policyController.image.pullPolicy | string | imagePullPolicy | Pull policy for the proxy container Docker image |
| policyController.image.version | string | linkerdVersion | Tag for the proxy container Docker image |
| policyController.logLevel | string | `"info"` | Log level for the policy controller |
| policyController.probeNetworks | list | `["0.0.0.0/0"]` | The networks from which probes are performed. By default, all networks are allowed so that all probes are authorized. |
| policyController.resources | object | destinationResources | policy controller resource requests & limits |
| policyController.resources.cpu.limit | string | `""` | Maximum amount of CPU units that the policy controller can use |
| policyController.resources.cpu.request | string | `""` | Amount of CPU units that the policy controller requests |

View File

@ -264,6 +264,9 @@ spec:
- --default-policy={{.Values.policyController.defaultAllowPolicy}}
- --log-level={{.Values.policyController.logLevel | default "linkerd=info,warn"}}
- --log-format={{.Values.controllerLogFormat}}
{{- if .Values.policyController.probeNetworks }}
- --probe-networks={{.Values.policyController.probeNetworks | join ","}}
{{- end}}
image: {{.Values.policyController.image.name}}:{{.Values.policyController.image.version | default .Values.linkerdVersion}}
imagePullPolicy: {{.Values.policyController.image.pullPolicy | default .Values.imagePullPolicy}}
livenessProbe:

View File

@ -78,6 +78,12 @@ policyController:
# -- Log level for the policy controller
logLevel: info
# -- The networks from which probes are performed.
#
# By default, all networks are allowed so that all probes are authorized.
probeNetworks:
- 0.0.0.0/0
# -- policy controller resource requests & limits
# @default -- destinationResources
resources:

View File

@ -72,6 +72,7 @@ func TestRender(t *testing.T) {
Request: "memory-request",
},
},
ProbeNetworks: []string{"1.0.0.0/0", "2.0.0.0/0"},
},
Proxy: &charts.Proxy{
Image: &charts.Image{

View File

@ -480,6 +480,8 @@ data:
pullPolicy: ""
version: ""
logLevel: info
probeNetworks:
- 0.0.0.0/0
resources:
cpu:
limit: ""
@ -1271,6 +1273,7 @@ spec:
- --default-policy=all-unauthenticated
- --log-level=info
- --log-format=plain
- --probe-networks=0.0.0.0/0
image: cr.l5d.io/linkerd/policy-controller:install-control-plane-version
imagePullPolicy: IfNotPresent
livenessProbe:

View File

@ -480,6 +480,8 @@ data:
pullPolicy: ""
version: ""
logLevel: info
probeNetworks:
- 0.0.0.0/0
resources:
cpu:
limit: ""
@ -1269,6 +1271,7 @@ spec:
- --default-policy=all-unauthenticated
- --log-level=info
- --log-format=plain
- --probe-networks=0.0.0.0/0
image: cr.l5d.io/linkerd/policy-controller:install-control-plane-version
imagePullPolicy: IfNotPresent
livenessProbe:

View File

@ -480,6 +480,8 @@ data:
pullPolicy: ""
version: ""
logLevel: info
probeNetworks:
- 0.0.0.0/0
resources:
cpu:
limit: ""
@ -1269,6 +1271,7 @@ spec:
- --default-policy=all-unauthenticated
- --log-level=info
- --log-format=plain
- --probe-networks=0.0.0.0/0
image: my.custom.registry/linkerd-io/policy-controller:install-control-plane-version
imagePullPolicy: IfNotPresent
livenessProbe:

View File

@ -480,6 +480,8 @@ data:
pullPolicy: ""
version: ""
logLevel: info
probeNetworks:
- 0.0.0.0/0
resources:
cpu:
limit: ""
@ -1269,6 +1271,7 @@ spec:
- --default-policy=all-unauthenticated
- --log-level=info
- --log-format=plain
- --probe-networks=0.0.0.0/0
image: cr.l5d.io/linkerd/policy-controller:install-control-plane-version
imagePullPolicy: IfNotPresent
livenessProbe:

View File

@ -480,6 +480,8 @@ data:
pullPolicy: ""
version: ""
logLevel: info
probeNetworks:
- 0.0.0.0/0
resources:
cpu:
limit: ""
@ -1269,6 +1271,7 @@ spec:
- --default-policy=all-unauthenticated
- --log-level=info
- --log-format=plain
- --probe-networks=0.0.0.0/0
image: cr.l5d.io/linkerd/policy-controller:install-control-plane-version
imagePullPolicy: IfNotPresent
livenessProbe:

View File

@ -480,6 +480,8 @@ data:
pullPolicy: ""
version: ""
logLevel: info
probeNetworks:
- 0.0.0.0/0
resources:
cpu:
limit: ""
@ -1258,6 +1260,7 @@ spec:
- --default-policy=all-unauthenticated
- --log-level=info
- --log-format=plain
- --probe-networks=0.0.0.0/0
image: cr.l5d.io/linkerd/policy-controller:install-control-plane-version
imagePullPolicy: IfNotPresent
livenessProbe:

View File

@ -507,6 +507,8 @@ data:
pullPolicy: ""
version: ""
logLevel: info
probeNetworks:
- 0.0.0.0/0
resources:
cpu:
limit: ""
@ -1397,6 +1399,7 @@ spec:
- --default-policy=all-unauthenticated
- --log-level=info
- --log-format=plain
- --probe-networks=0.0.0.0/0
image: cr.l5d.io/linkerd/policy-controller:install-control-plane-version
imagePullPolicy: IfNotPresent
livenessProbe:

View File

@ -507,6 +507,8 @@ data:
pullPolicy: ""
version: ""
logLevel: info
probeNetworks:
- 0.0.0.0/0
resources:
cpu:
limit: ""
@ -1397,6 +1399,7 @@ spec:
- --default-policy=all-unauthenticated
- --log-level=info
- --log-format=plain
- --probe-networks=0.0.0.0/0
image: cr.l5d.io/linkerd/policy-controller:install-control-plane-version
imagePullPolicy: IfNotPresent
livenessProbe:

View File

@ -411,6 +411,8 @@ data:
pullPolicy: ""
version: ""
logLevel: info
probeNetworks:
- 0.0.0.0/0
resources:
cpu:
limit: ""
@ -1200,6 +1202,7 @@ spec:
- --default-policy=all-unauthenticated
- --log-level=info
- --log-format=plain
- --probe-networks=0.0.0.0/0
image: cr.l5d.io/linkerd/policy-controller:install-control-plane-version
imagePullPolicy: IfNotPresent
livenessProbe:

View File

@ -456,6 +456,8 @@ data:
pullPolicy: ""
version: ""
logLevel: info
probeNetworks:
- 0.0.0.0/0
resources:
cpu:
limit: ""
@ -1242,6 +1244,7 @@ spec:
- --default-policy=all-unauthenticated
- --log-level=info
- --log-format=plain
- --probe-networks=0.0.0.0/0
image: cr.l5d.io/linkerd/policy-controller:linkerd-version
imagePullPolicy: IfNotPresent
livenessProbe:

View File

@ -483,6 +483,8 @@ data:
pullPolicy: ""
version: ""
logLevel: info
probeNetworks:
- 0.0.0.0/0
resources:
cpu:
limit: ""
@ -1370,6 +1372,7 @@ spec:
- --default-policy=all-unauthenticated
- --log-level=info
- --log-format=plain
- --probe-networks=0.0.0.0/0
image: cr.l5d.io/linkerd/policy-controller:linkerd-version
imagePullPolicy: IfNotPresent
livenessProbe:

View File

@ -487,6 +487,8 @@ data:
pullPolicy: ""
version: ""
logLevel: info
probeNetworks:
- 0.0.0.0/0
resources:
cpu:
limit: ""
@ -1382,6 +1384,7 @@ spec:
- --default-policy=all-unauthenticated
- --log-level=info
- --log-format=plain
- --probe-networks=0.0.0.0/0
image: cr.l5d.io/linkerd/policy-controller:linkerd-version
imagePullPolicy: IfNotPresent
livenessProbe:

View File

@ -478,6 +478,8 @@ data:
pullPolicy: ""
version: ""
logLevel: info
probeNetworks:
- 0.0.0.0/0
resources:
cpu:
limit: ""
@ -1360,6 +1362,7 @@ spec:
- --default-policy=all-unauthenticated
- --log-level=info
- --log-format=plain
- --probe-networks=0.0.0.0/0
image: cr.l5d.io/linkerd/policy-controller:linkerd-version
imagePullPolicy: IfNotPresent
livenessProbe:

View File

@ -480,6 +480,8 @@ data:
pullPolicy: ""
version: ""
logLevel: info
probeNetworks:
- 0.0.0.0/0
resources:
cpu:
limit: ""
@ -1228,6 +1230,7 @@ spec:
- --default-policy=all-unauthenticated
- --log-level=info
- --log-format=plain
- --probe-networks=0.0.0.0/0
image: cr.l5d.io/linkerd/policy-controller:install-control-plane-version
imagePullPolicy: IfNotPresent
livenessProbe:

View File

@ -473,6 +473,9 @@ data:
pullPolicy: ImagePullPolicy
version: PolicyControllerVersion
logLevel: log-level
probeNetworks:
- 1.0.0.0/0
- 2.0.0.0/0
resources:
cpu:
limit: cpu-limit
@ -1259,6 +1262,7 @@ spec:
- --default-policy=default-allow-policy
- --log-level=log-level
- --log-format=ControllerLogFormat
- --probe-networks=1.0.0.0/0,2.0.0.0/0
image: PolicyControllerImageName:PolicyControllerVersion
imagePullPolicy: ImagePullPolicy
livenessProbe:

View File

@ -480,6 +480,8 @@ data:
pullPolicy: ""
version: ""
logLevel: info
probeNetworks:
- 0.0.0.0/0
resources:
cpu:
limit: ""
@ -1269,6 +1271,7 @@ spec:
- --default-policy=all-unauthenticated
- --log-level=info
- --log-format=plain
- --probe-networks=0.0.0.0/0
image: cr.l5d.io/linkerd/policy-controller:install-control-plane-version
imagePullPolicy: IfNotPresent
livenessProbe:

View File

@ -480,6 +480,8 @@ data:
pullPolicy: ""
version: ""
logLevel: info
probeNetworks:
- 0.0.0.0/0
resources:
cpu:
limit: ""
@ -1269,6 +1271,7 @@ spec:
- --default-policy=all-unauthenticated
- --log-level=info
- --log-format=plain
- --probe-networks=0.0.0.0/0
image: cr.l5d.io/linkerd/policy-controller:install-control-plane-version
imagePullPolicy: IfNotPresent
livenessProbe:

View File

@ -143,6 +143,7 @@ type (
Resources *Resources `json:"resources"`
LogLevel string `json:"logLevel"`
DefaultAllowPolicy string `json:"defaultAllowPolicy"`
ProbeNetworks []string `json:"probeNetworks"`
}
// Image contains the details to define a container image

View File

@ -83,6 +83,7 @@ func TestNewValues(t *testing.T) {
Request: "",
},
},
ProbeNetworks: []string{"0.0.0.0/0"},
},
Proxy: &Proxy{
EnableExternalProfiles: false,

View File

@ -23,7 +23,11 @@ use linkerd_policy_controller_core::{
};
use linkerd_policy_controller_k8s_api::{self as k8s, policy::server::Port, ResourceExt};
use parking_lot::RwLock;
use std::{collections::hash_map::Entry, num::NonZeroU16, sync::Arc};
use std::{
collections::{hash_map::Entry, BTreeSet},
num::NonZeroU16,
sync::Arc,
};
use tokio::sync::watch;
use tracing::info_span;
@ -94,7 +98,7 @@ struct Pod {
/// In order for the policy controller to authorize probes, it must be
/// aware of the probe ports and the expected paths on which probes are
/// expected.
probes: pod::PortMap<HashSet<String>>,
probes: pod::PortMap<BTreeSet<String>>,
}
/// Holds the state of a single port on a pod.
@ -827,7 +831,7 @@ impl PodIndex {
name: String,
meta: pod::Meta,
port_names: HashMap<String, pod::PortSet>,
probes: PortMap<HashSet<String>>,
probes: PortMap<BTreeSet<String>>,
) -> Result<Option<&mut Pod>> {
let pod = match self.by_name.entry(name.clone()) {
Entry::Vacant(entry) => entry.insert(Pod {

View File

@ -1,8 +1,8 @@
use crate::DefaultPolicy;
use ahash::{AHashMap as HashMap, AHashSet as HashSet};
use ahash::AHashMap as HashMap;
use anyhow::{bail, Context, Result};
use linkerd_policy_controller_k8s_api as k8s;
use std::num::NonZeroU16;
use std::{collections::BTreeSet, num::NonZeroU16};
/// Holds pod metadata/config that can change.
#[derive(Debug, PartialEq)]
@ -63,8 +63,8 @@ pub(crate) fn tcp_ports_by_name(spec: &k8s::PodSpec) -> HashMap<String, PortSet>
///
/// The result is a mapping for each probe port exposed by a container in the
/// Pod and the paths for which probes are expected.
pub(crate) fn pod_http_probes(pod: &k8s::PodSpec) -> PortMap<HashSet<String>> {
let mut probes = PortMap::<HashSet<String>>::default();
pub(crate) fn pod_http_probes(pod: &k8s::PodSpec) -> PortMap<BTreeSet<String>> {
let mut probes = PortMap::<BTreeSet<String>>::default();
for (port, path) in pod.containers.iter().flat_map(container_http_probe_paths) {
probes.entry(port).or_default().insert(path);
}
@ -316,14 +316,14 @@ mod tests {
});
let port_5432 = u16::try_from(5432).and_then(NonZeroU16::try_from).unwrap();
let mut expected_5432 = HashSet::new();
let mut expected_5432 = BTreeSet::new();
expected_5432.insert("/liveness-container-1".to_string());
expected_5432.insert("/ready-container-1".to_string());
assert!(probes.get(&port_5432).is_some());
assert_eq!(*probes.get(&port_5432).unwrap(), expected_5432);
let port_6543 = u16::try_from(6543).and_then(NonZeroU16::try_from).unwrap();
let mut expected_6543 = HashSet::new();
let mut expected_6543 = BTreeSet::new();
expected_6543.insert("/liveness-container-2".to_string());
expected_6543.insert("/ready-container-2".to_string());
assert!(probes.get(&port_6543).is_some());

View File

@ -44,7 +44,10 @@ macro_rules! assert_protocol_detect {
kind: Some(inbound::proxy_protocol::Kind::Detect(
inbound::proxy_protocol::Detect {
timeout: Some(time::Duration::from_secs(10).try_into().unwrap()),
http_routes: vec![$crate::grpc::defaults::http_route()],
http_routes: vec![
$crate::grpc::defaults::http_route(),
$crate::grpc::defaults::probe_route(),
],
}
)),
}),
@ -188,7 +191,7 @@ pub mod defaults {
use inbound::proxy_protocol::{Http1, Kind};
inbound::ProxyProtocol {
kind: Some(Kind::Http1(Http1 {
routes: vec![http_route()],
routes: vec![http_route(), probe_route()],
})),
}
}
@ -214,4 +217,59 @@ pub mod defaults {
..HttpRoute::default()
}
}
pub fn probe_route() -> inbound::HttpRoute {
use http_route::{path_match, HttpRouteMatch, PathMatch};
use inbound::{
authn::{Permit, PermitUnauthenticated},
http_route::Rule,
Authn, Authz, HttpRoute, Network,
};
use ipnet::IpNet;
use maplit::{convert_args, hashmap};
use meta::{metadata, Metadata};
HttpRoute {
metadata: Some(Metadata {
kind: Some(metadata::Kind::Default("probe".to_string())),
}),
authorizations: vec![Authz {
networks: vec![Network {
net: Some("0.0.0.0/0".parse::<IpNet>().unwrap().into()),
..Network::default()
}],
authentication: Some(Authn {
permit: Some(Permit::Unauthenticated(PermitUnauthenticated {})),
}),
labels: convert_args!(hashmap!(
"kind" => "default",
"name" => "probe",
"group" => "",
)),
metadata: Some(Metadata {
kind: Some(metadata::Kind::Default("probe".to_string())),
}),
}],
rules: vec![Rule {
matches: vec![
HttpRouteMatch {
path: Some(PathMatch {
kind: Some(path_match::Kind::Exact("/live".to_string())),
}),
method: Some(hyper::Method::GET.into()),
..HttpRouteMatch::default()
},
HttpRouteMatch {
path: Some(PathMatch {
kind: Some(path_match::Kind::Exact("/ready".to_string())),
}),
method: Some(hyper::Method::GET.into()),
..HttpRouteMatch::default()
},
],
..Rule::default()
}],
..HttpRoute::default()
}
}
}

View File

@ -510,7 +510,7 @@ async fn default_http_routes() {
assert_protocol_detect!(config);
let routes = detect_routes(&config);
assert_eq!(routes.len(), 1);
assert_eq!(routes.len(), 2);
let route_authzs = &routes[0].authorizations;
assert_eq!(route_authzs.len(), 0);
})