feat: add k8s info in events with container id#194
Conversation
be9bda5 to
30f0378
Compare
Signed-off-by: hanshal101 <hanshalmehta10@gmail.com>
30f0378 to
2de20c2
Compare
|
Also if you're testing it you should run something like this, I was facing some issues previously here. sudo KUBECONFIG={you-kubeconfig-path} ./target/release/bombini --bpf-objs ./target/bpfel-unknown-none/release --config-dir ./config |
Signed-off-by: hanshal101 <hanshalmehta10@gmail.com>
|
Also here I am not sure whether I should push the |
Signed-off-by: hanshal101 <hanshalmehta10@gmail.com>
Please, do not push it. We need it to be regenerated in-place because of CO-RE support lack |
Yeah Cool |
|
|
||
| #[derive(Clone, Debug, Serialize)] | ||
| #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] | ||
| pub struct PodInfo { |
There was a problem hiding this comment.
Let's move this to transmuter::process module. bombini-common has definitions for types that are commonly used in bpf and user side. I think, we need no changes in common crate at all
| // Minimal container id length. It could be truncated in ebpf. | ||
| if container.len() >= 31 { | ||
| container[..31].to_string() | ||
| if container.len() >= 10 { |
There was a problem hiding this comment.
Why we need this check?
Maybe we can check that this is a hex string? Please have a look here.
| impl Process { | ||
| /// Constructs High level event representation from low eBPF | ||
| pub fn new(proc: &ProcInfo) -> Self { | ||
| pub fn new(proc: &ProcInfo, k8s_info: &K8sInfo) -> Self { |
There was a problem hiding this comment.
I think, it's better to pass something like Option<&Pod> here
| @@ -0,0 +1,151 @@ | |||
| use log; | |||
There was a problem hiding this comment.
Let's rename to pod_info and move this module to https://github.com/bombinisecurity/bombini/tree/main/bombini/src/transmuter/cache
| #[derive(Clone)] | ||
| pub struct K8sInfo { | ||
| pods: Arc<RwLock<HashMap<String, PodInfo>>>, | ||
| k8s_available: Arc<std::sync::atomic::AtomicBool>, |
There was a problem hiding this comment.
Let's name PodInfoCache, like we have ProcessCache. I think, we don't need to have k8s_available flag. We can hold Option, here . At initialization step we can check if k8s is available.
| log::error!("failed to list pods: {}", e); | ||
| } | ||
| } | ||
| time::sleep(Duration::from_secs(60)).await; |
There was a problem hiding this comment.
This should be a configurable parameter.
| async fn watch_pods(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | ||
| let client = Client::try_default().await?; | ||
| let pods: Api<Pod> = Api::all(client); | ||
| let lp = ListParams::default(); |
There was a problem hiding this comment.
We need to get pods, that are related to our node only.
|
|
||
| for pod in pod_list { | ||
| if let Some(status) = pod.status { | ||
| if let Some(container_statuses) = status.container_statuses { |
There was a problem hiding this comment.
get only "living" containers
|
|
||
| #[derive(Clone)] | ||
| pub struct K8sInfo { | ||
| pods: Arc<RwLock<HashMap<String, PodInfo>>>, |
There was a problem hiding this comment.
We need to think about another, concurent map here https://crates.io/crates/dashmap and move Arc to value: Arc to avoid copies.
Description
Add Kubernetes pod information to process events
Enhanced process events with pod context by mapping container IDs to Kubernetes pod metadata (name, namespace, service account, node).
Details
The events looks something like this:
{ "type": "ProcessExec", "process": { "start_time": "2026-01-27T13:26:44.733Z", "cloned": false, "pid": 264375, "tid": 264375, "ppid": 242089, "uid": 0, "euid": 0, "gid": 0, "egid": 0, "auid": 4294967295, "cap_inheritable": "", "cap_permitted": "CAP_CHOWN | CAP_DAC_OVERRIDE | CAP_FOWNER | CAP_FSETID | CAP_KILL | CAP_SETGID | CAP_SETUID | CAP_SETPCAP | CAP_NET_BIND_SERVICE | CAP_NET_RAW | CAP_SYS_CHROOT | CAP_MKNOD | CAP_AUDIT_WRITE | CAP_SETFCAP", "cap_effective": "CAP_CHOWN | CAP_DAC_OVERRIDE | CAP_FOWNER | CAP_FSETID | CAP_KILL | CAP_SETGID | CAP_SETUID | CAP_SETPCAP | CAP_NET_BIND_SERVICE | CAP_NET_RAW | CAP_SYS_CHROOT | CAP_MKNOD | CAP_AUDIT_WRITE | CAP_SETFCAP", "secureexec": "", "filename": "apk", "binary_path": "/sbin/apk", "args": "update", "container_id": "d370bc00d2adbf95b16374a5a2b0a5a359cd8a7190312a45bd4b776d923dd2d7", "pod": { "name": "alpine-critical", "namespace": "default", "service_account": "default", "node_name": "lol" } }, "parent": { "start_time": "2026-01-27T12:40:13.370Z", "cloned": false, "pid": 242089, "tid": 242089, "ppid": 7227, "uid": 0, "euid": 0, "gid": 0, "egid": 0, "auid": 4294967295, "cap_inheritable": "", "cap_permitted": "CAP_CHOWN | CAP_DAC_OVERRIDE | CAP_FOWNER | CAP_FSETID | CAP_KILL | CAP_SETGID | CAP_SETUID | CAP_SETPCAP | CAP_NET_BIND_SERVICE | CAP_NET_RAW | CAP_SYS_CHROOT | CAP_MKNOD | CAP_AUDIT_WRITE | CAP_SETFCAP", "cap_effective": "CAP_CHOWN | CAP_DAC_OVERRIDE | CAP_FOWNER | CAP_FSETID | CAP_KILL | CAP_SETGID | CAP_SETUID | CAP_SETPCAP | CAP_NET_BIND_SERVICE | CAP_NET_RAW | CAP_SYS_CHROOT | CAP_MKNOD | CAP_AUDIT_WRITE | CAP_SETFCAP", "secureexec": "", "filename": "busybox", "binary_path": "/bin/busybox", "args": "" }, "timestamp": "2026-01-27T13:26:44.733Z" }Improvements
Well i feel this is not the best way to do it, rather we have another methods like informers which we can use to watch the k8s client.