Log Feeder
Welcome back to the KubeArmor tutorial! In the previous chapters, we've learned how KubeArmor defines security rules using Security Policies, identifies workloads using Container/Node Identity, enforces policies with the Runtime Enforcer, and observes system activity with the System Monitor, all powered by the underlying BPF (eBPF) technology and orchestrated by the KubeArmor Daemon on each node.
We've discussed how KubeArmor can audit or block actions based on policies. But where do you actually see the results of this monitoring and enforcement? How do you know when a policy was violated or when suspicious activity was detected?
This is where the Log Feeder comes in.
What is the Log Feeder?
Think of the Log Feeder as KubeArmor's reporting and alerting system. Its primary job is to collect all the security-relevant events and telemetry that KubeArmor detects and make them available to you and other systems.
It receives structured information, including:
Security Alerts: Notifications about actions that were audited or blocked because they violated a Security Policy.
System Logs: Telemetry about system activities that KubeArmor is monitoring, even if no specific policy applies (e.g., process executions, file accesses, network connections, depending on visibility settings).
KubeArmor Messages: Internal messages from the KubeArmor Daemon itself (useful for debugging and monitoring KubeArmor's status).
The Log Feeder formats this information into standardized messages (using Protobuf, a language-neutral, platform-neutral, extensible mechanism for serializing structured data) and sends it out over a gRPC interface. gRPC is a high-performance framework for inter-process communication.
This gRPC interface allows various clients to connect to the KubeArmor Daemon on each node and subscribe to streams of these security events in real-time. Tools like karmor log
(part of the KubeArmor client tools) connect to this feeder to display events. External systems like Security Information and Event Management (SIEM) platforms can also integrate by writing clients that understand the KubeArmor gRPC format.
Why is Log Feeding Important? Your Window into Security
You've deployed KubeArmor and applied policies. Now you need to answer questions like:
Was that attempt to read
/etc/passwd
from the web server container actually blocked?Is any process on my host nodes trying to access sensitive files like
/root/.ssh
?Are my applications spawning unexpected shell processes, even if they aren't explicitly blocked by policy?
Did KubeArmor successfully apply the policies I created?
The Log Feeder provides the answers by giving you a stream of events directly from KubeArmor:
It reports when an action was Blocked by a specific policy, providing details about the workload and the attempted action.
It reports when an action was Audited, showing you potentially suspicious behavior even if it wasn't severe enough to block.
It reports general System Events (logs), giving you visibility into the normal or unusual behavior of processes, file accesses, and network connections on your nodes and within containers.
Without the Log Feeder, KubeArmor would be enforcing policies blindly from a monitoring perspective. You wouldn't have the necessary visibility to understand your security posture, detect attacks (even failed ones), or troubleshoot policy issues.
Use Case Example: You want to see every time someone tries to execute a shell (/bin/sh
, /bin/bash
) inside any of your containers. You might create an Audit Policy for this. The Log Feeder is how you'll receive the notifications for these audited events.
How the Log Feeder Works (High-Level)
Event Source: The System Monitor observes kernel events (process execution, file access, etc.). It enriches these events with Container/Node Identity and sends them to the KubeArmor Daemon. The Runtime Enforcer also contributes by confirming if an event was blocked or audited by policy.
Reception by Daemon: The KubeArmor Daemon receives these enriched events.
Formatting (by Feeder): The Daemon passes the event data to the Log Feeder component. The Feeder takes the structured event data and converts it into the predefined Protobuf message format (e.g.,
Alert
orLog
message types defined inprotobuf/kubearmor.proto
).Queueing: The Feeder manages internal queues or channels for different types of messages (Alerts, Logs, general KubeArmor Messages). It puts the newly formatted Protobuf message onto the appropriate queue/channel.
gRPC Server: The Feeder runs a gRPC server on a specific port (default 32767).
Client Subscription: External clients connect to this gRPC port and call specific gRPC methods (like
WatchAlerts
orWatchLogs
) to subscribe to event streams.Event Streaming: When a client subscribes, the Feeder gets a handle to the client's connection. It then continuously reads messages from its internal queues/channels and streams them over the gRPC connection to the connected client.
Here's a simple sequence diagram showing the flow:
This shows how events flow from the kernel, up through the System Monitor and Daemon, are formatted by the Log Feeder, and then streamed out to any connected clients.
Looking at the Code (Simplified)
The Log Feeder is implemented primarily in KubeArmor/feeder/feeder.go
and KubeArmor/feeder/logServer.go
, using definitions from protobuf/kubearmor.proto
and the generated protobuf/kubearmor_grpc.pb.go
.
First, let's look at the Protobuf message structures. These define the schema for the data that gets sent out.
Referencing protobuf/kubearmor.proto
:
These Protobuf definitions specify the exact structure and data types for the messages KubeArmor will send, ensuring that clients know exactly what data to expect. The .pb.go
and _grpc.pb.go
files are automatically generated from this .proto
file and provide the Go code for serializing/deserializing these messages and implementing the gRPC service.
Now, let's look at the Log Feeder implementation in Go.
Referencing KubeArmor/feeder/feeder.go
:
Explanation:
NewFeeder
: This function, called during Daemon initialization, sets up the data structures (EventStructs
) to manage client connections, creates a network listener for the configured gRPC port, and creates and registers the gRPC server (LogServer
). It passes a reference toEventStructs
and other data to theLogService
implementation.ServeLogFeeds
: This function is run as a goroutine by the KubeArmor Daemon. It callsLogServer.Serve()
, which makes the gRPC server start listening for incoming client connections and handling gRPC requests.PushLog
: This method is called by the KubeArmor Daemon (specifically, the part that processes events from the System Monitor) whenever a new security event or log needs to be reported. It takes KubeArmor's internaltp.Log
structure, converts it into the appropriate Protobuf message (pb.Alert
orpb.Log
), and then iterates through all registered client connections (stored inEventStructs
) broadcasting the message to their respective Go channels (Broadcast
). If a client isn't reading fast enough, the message might be dropped due to the channel buffer being full.
Now let's see the client-side handling logic within the Log Feeder's gRPC service implementation.
Referencing KubeArmor/feeder/logServer.go
:
Explanation:
LogService
: This struct is the concrete implementation of the gRPC service defined inprotobuf/kubearmor.proto
. It holds references to the feeder's state.WatchAlerts
: This method is a gRPC streaming RPC handler. When a client initiates aWatchAlerts
call, this function is executed. It creates a dedicated Go channel (conn
) for that client usingAddAlertStruct
. Then, it enters afor
loop. Inside the loop, it waits for either the client to disconnect (<-svr.Context().Done()
) or for a newpb.Alert
message to appear on the client's dedicated channel (<-conn
). When a message arrives, it sends it over the gRPC stream back to the client usingsvr.Send(resp)
. This creates the real-time streaming behavior.WatchLogs
: This method is similar toWatchAlerts
but handles subscriptions for general system logs (pb.Log
messages).
This shows how the Log Feeder's gRPC server manages multiple concurrent client connections, each with its own channel, ensuring that events pushed by PushLog
are delivered to all interested subscribers efficiently.
Connecting to the Log Feeder
The most common way to connect to the Log Feeder is using the karmor
command-line tool provided with KubeArmor.
To watch security alerts:
To watch system logs:
To watch both alerts and logs:
These commands are simply gRPC clients that connect to the KubeArmor Daemon's Log Feeder port on your nodes (or via the KubeArmor Relay service if configured) and call the WatchAlerts
and WatchLogs
gRPC methods.
You can also specify filters (e.g., by namespace or policy name) using karmor log
options, which the Log Feeder's gRPC handlers can process (although the code snippets above show a simplified filter handling).
For integration with other systems, you would write a custom gRPC client application in your preferred language (Go, Python, Java, etc.) using the KubeArmor Protobuf definitions to connect to the feeder and consume the streams.
Log Feeder Components Summary
gRPC Server
Listens for incoming client connections and handles RPC calls.
feeder/feeder.go
Exposes event streams to external clients.
LogService
Implementation of the gRPC service methods (WatchAlerts
, WatchLogs
).
feeder/logServer.go
Manages client connections and streams events.
EventStructs
Internal data structure (maps of channels) holding connections for each client type.
feeder/feeder.go
Enables broadcasting events to multiple clients.
Protobuf Defs
Define the structure of Alert
and Log
messages.
protobuf/kubearmor.proto
Standardizes the output format.
PushLog
method
Method on the Feeder
called by the Daemon to send new events.
feeder/feeder.go
Point of entry for events into the feeder.
Conclusion
The Log Feeder is your essential window into KubeArmor's activity. By collecting enriched security events and telemetry from the System Monitor and Runtime Enforcer, formatting them using Protobuf, and streaming them over a gRPC interface, it provides real-time visibility into policy violations (alerts) and system behavior (logs). Tools like karmor log
and integrations with SIEM systems rely on the Log Feeder to deliver crucial security insights from your KubeArmor-protected environment.
This chapter concludes our detailed look into the core components of KubeArmor! You now have a foundational understanding of how KubeArmor defines policies, identifies workloads, enforces rules, monitors system activity using eBPF, orchestrates these actions with the Daemon, and reports everything via the Log Feeder.
Thank you for following this tutorial series! We hope it has provided a clear and beginner-friendly introduction to the fascinating world of KubeArmor.
Last updated
Was this helpful?