-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Closed
Labels
Description
What is the issue?
Prometheus isn't able to scrape metrics on proxies injected as native sidecar containers in workloads with a restrictive inbound policy.
How can it be reproduced?
- Install linkerd with
proxy.nativeSidecar: true - Install linkerd viz
- Install emojivoto
- Set up authorization for the web workload:
apiVersion: policy.linkerd.io/v1beta3
kind: Server
metadata:
annotations:
name: admin
namespace: emojivoto
spec:
accessPolicy: deny
podSelector:
matchLabels:
app: web-svc
port: linkerd-admin
proxyProtocol: HTTP/1
---
apiVersion: policy.linkerd.io/v1alpha1
kind: AuthorizationPolicy
metadata:
namespace: emojivoto
name: web-http-sa
spec:
targetRef:
group: policy.linkerd.io
kind: Server
name: admin
requiredAuthenticationRefs:
- name: prometheus
kind: MeshTLSAuthentication
group: policy.linkerd.io
---
apiVersion: policy.linkerd.io/v1alpha1
kind: MeshTLSAuthentication
metadata:
namespace: emojivoto
name: prometheus
spec:
identities:
- "prometheus.linkerd-viz.serviceaccount.identity.linkerd.cluster.local"linkerd diagnostics policy po/web-xxx 4191 doesn't detect that policy:
labels:
group: ""
kind: default
name: deny
protocol:
Kind:
Detect:
http_routes:
- metadata:
Kind:
Default: default
rules:
- matches:
- path:
Kind:
Prefix: /
- authorizations:
- authentication:
Permit:
Unauthenticated: {}
labels:
group: ""
kind: default
name: probe
metadata:
Kind:
Default: probe
networks:
- net:
ip:
Ip:
Ipv4: 0
- net:
ip:
Ip:
Ipv6: {}
metadata:
Kind:
Default: probe
rules:
- matches:
- method:
Type:
Registered: 0
path:
Kind:
Exact: /live
- method:
Type:
Registered: 0
path:
Kind:
Exact: /ready
timeout:
seconds: 10Updating the linkerd config such that proxy.nativeSidecar: false results in the policy being detected:
authorizations:
- authentication:
Permit:
MeshTLS:
Clients:
Identities:
identities:
- name: prometheus.linkerd-viz.serviceaccount.identity.linkerd.cluster.local
labels:
group: policy.linkerd.io
kind: authorizationpolicy
name: web-http-sa
metadata:
Kind:
Resource:
group: policy.linkerd.io
kind: authorizationpolicy
name: web-http-sa
networks:
- net:
ip:
Ip:
Ipv4: 0
- net:
ip:
Ip:
Ipv6: {}
labels:
group: policy.linkerd.io
kind: server
name: admin
protocol:
Kind:
Http1:
routes:
- metadata:
Kind:
Default: default
rules:
- matches:
- path:
Kind:
Prefix: /
- authorizations:
- authentication:
Permit:
Unauthenticated: {}
labels:
group: ""
kind: default
name: probe
metadata:
Kind:
Default: probe
networks:
- net:
ip:
Ip:
Ipv4: 0
- net:
ip:
Ip:
Ipv6: {}
metadata:
Kind:
Default: probe
rules:
- matches:
- method:
Type:
Registered: 0
path:
Kind:
Exact: /live
- method:
Type:
Registered: 0
path:
Kind:
Exact: /readyLogs, error output, etc
No relevant logs in this case.
output of linkerd check -o short
Check is fine.
Environment
- k8s >= 1.29
- Linkerd >= 2.15 (when native sidecars where introduced)
Possible solution
When the policy controller indexes a pod, we use this function to retrieve its ports, but we iterate only through containers and ignore initContainers:
linkerd2/policy-controller/k8s/index/src/inbound/workload.rs
Lines 26 to 44 in 520435e
| /// Gets the set of named ports with `protocol: TCP` from a pod spec. | |
| pub(crate) fn pod_tcp_ports_by_name(spec: &k8s::PodSpec) -> HashMap<String, PortSet> { | |
| let mut ports = HashMap::<String, PortSet>::default(); | |
| for (port, name) in spec | |
| .containers | |
| .iter() | |
| .flat_map(|c| c.ports.iter().flatten()) | |
| .filter_map(named_tcp_port) | |
| { | |
| ports.entry(name.to_string()).or_default().insert(port); | |
| } | |
| ports | |
| } | |
| /// Gets the set of named ports withn `protocol: TCP` from an external workload | |
| /// spec. | |
| /// | |
| /// Since an external workload has only one set of ports, each name is | |
| /// guaranteed to be unique. |
Additional context
No response
Would you like to work on fixing this bug?
None