Skip to content

Filtering in/out flows for another Kubernetes resource #530

Description

@maksym-iv-ef

Type

Feature Request

Dscription

Currently, there is a syntax to filter out flows related to a particular K8s object by using discovery.informer.k8s.selectors attribute

Example
discovery "informer" "k8s" {
  selectors = [
    {
      kind = "Pod"

      match_expressions = [{
        key      = "app.kubernetes.io/name"
        operator = "In"
        values   = ["netobserv-flow", "opensearch"]
      }]
      include = false
    }
  ]
}

However, flows are still read and processed up to the "K8s Decorator" component (docs).

It would be useful to allow filtering out the flows for other K8s objects in the filter.source block.

The proposal is to introduce a function to obtain an arbitrary K8s object field from an arbitrary K8s object. Signature:

k8s.attrMatchLabels(kind, namespace, label, label_value, json_path_to_attribute)
k8s.attrMatchLabels("pod", "some-ns", "app", "foobar", ".status.IP")

To make the following syntax possible

Example
filter "source" {
  address = {
    not_match = join(",", concat(
      [
        env("POD_IP")
        k8s.attrMatchLabels("pod", "some-ns", "app", "baz", ".status.IP"),
      ],
      k8s.attrMatchLabels("pod", "some-ns", "app", "foobar", ".status.IPs"),
    ))
  }
}

The downside of the approach is that Mermin would need to watch for the K8s events and reload config on every change to the matched resources (pods and IPs are ephemeral).


@svencowart has suggested another approach.

The function will allow us to internally track the IP addresses of the k8s matching condition, and build an internal ebpf map of those IPs to either black list or whitelist. Then, in the eBPF space, once we parse the IPs, we can perform a simple lookup and decide if we short-circuit all downstream processing based on the presence of an IP in that map and the IP values parsed out of a packet. We probably need two maps, one that is a whitelist and one that is a blacklist.

In this case the sole purpose of the function would be obtain the IP and update the eBPF map for the filtering purposes, than function should be exclusive to the filter.source block.
Function signature should also represent filterish nature of the function, may not retrieve arbitrary fields, and may look like:

filter.k8sIpMatchLabels(kind, namespace, label, label_value)
filter.k8sIpMatchLabels("pod", "some-ns", "app", "foobar")

Note, any approach would require join and concat functions.
We may also be inspired by Grafana Alloy function namespaces:

  • Change the env function signature - env -> sys.env
  • concat -> array.concat
  • join -> string.join

Version & Environment

v0.3.3

Component

eBPF / Flow capture

Checklist

  • I have searched existing issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions