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

Label selector for services does not work correctly with multiple selectors #302

Closed
bpfoster opened this issue Apr 2, 2024 · 0 comments · Fixed by #303
Closed

Label selector for services does not work correctly with multiple selectors #302

bpfoster opened this issue Apr 2, 2024 · 0 comments · Fixed by #303

Comments

@bpfoster
Copy link
Contributor

bpfoster commented Apr 2, 2024




Describe the bug
If a service uses 2+ label selectors to identify the target pod, the Popeye scanner is incorrectly using the selectors to find the pod. The end result is you may have false positives reported by Popeye because it is comparing against the wrong pod.

To Reproduce
Steps to reproduce the behavior:

  1. Apply the following resources
apiVersion: v1
kind: Pod
metadata:
  name: aaa
  labels:
    part-of: foo
    instance: web
spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP

---
apiVersion: v1
kind: Pod
metadata:
  name: bbb
  labels:
    part-of: foo
    instance: bar
spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: http
          containerPort: 80
          protocol: TCP

---
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    part-of: foo
    instance: bar
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: http
  1. Note that both the aaa and bbb pods have the same part-of label, but different instance labels. The service is expecting to match a pod with part-of=foo AND instance=bar
  2. Scan the cluster using popeye
  3. Observe the error
  · default/my-service.............................................................................💥
    💥 [POP-1106] No target ports match service port TCP:http:80.
    😱 [POP-1109] Single endpoint is associated with this service.

Expected behavior
POP-1106 is not falsely reported.

Screenshots

Versions (please complete the following information):

  • OS: linux
  • Popeye: latest
  • K8s: 1.26

Additional context
The issue appears to lie in the MatchLabels() function in db.go:

popeye/internal/db/db.go

Lines 384 to 393 in f736e64

func MatchLabels(labels, sel map[string]string) bool {
var count int
for k, v := range sel {
if v1, ok := labels[k]; ok && v == v1 {
count++
}
}
return count > 0
}

aaa is processed first. The part-of selector matches on the aaa pod. count > 0, and so the aaa pod is returned as the matching pod for this selector set. Instead, both selector labels should match, as multiple selectors are treated as an AND.

My first impression is that MatchLabels() should be checking count == len(sel).

bpfoster added a commit to bpfoster/popeye that referenced this issue Apr 2, 2024
Treat label selectors as an AND, not an 'at least 1' match
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 a pull request may close this issue.

1 participant