This document outlines the steps to set up a Google Kubernetes Engine (GKE) cluster, run Quark to capture eBPF events, and ship them to Elasticsearch using a repurposed Auditbeat. The goal is to verify that system events are enriched with Kubernetes ECS metadata (container.*, orchestrator.*, etc.).
Ensure you have the following tools installed on your local machine (Debian/Ubuntu assumed):
- Build Tools:
build-essentialis needed to compile Quark. - Go: A modern version of Go (>=1.18) is required to build Auditbeat.
sudo apt-get update
sudo apt-get install -y build-essential golang-goThis guide assumes you have an active Elastic Cloud deployment. When you create the deployment, note the following credentials, as you will need them to configure the agent:
- Cloud ID
elasticuser password
First, install gcloud, kubectl, and the GKE auth plugin.
# Add Google's apt repository and key
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee /etc/apt/sources.list.d/google-cloud-sdk.list
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg
# Update apt and install the required packages
sudo apt-get update
sudo apt-get install -y google-cloud-cli kubectl google-cloud-sdk-gke-gcloud-auth-pluginNext, initialize gcloud to log in and select your GCP project.
gcloud initEnable the Kubernetes Engine API for your project.
gcloud services enable container.googleapis.comFinally, configure kubectl to use gcloud for authentication, which is required for GKE.
export USE_GKE_GCLOUD_AUTH_PLUGIN=TrueCreate a simple, single-node GKE cluster with an Ubuntu image using containerd.
gcloud container clusters create demo-quark-cluster \
--num-nodes 1 \
--machine-type e2-standard-2 \
--image-type=ubuntu_containerd \
--enable-ip-alias \
--zone us-east1-bAfter the cluster is created, fetch its credentials to configure kubectl. This populates your ~/.kube/config file.
gcloud container clusters get-credentials demo-quark-cluster --zone us-east1-bVerify that kubectl is correctly configured by listing the cluster nodes.
kubectl get nodesQuark will be running directly on the Kubernetes node, not in a pod. Get the node's name and zone, then SSH into it.
# Get the name and zone of the first node in the cluster
NODE=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')
ZONE=$(kubectl get node "$NODE" -o jsonpath='{.metadata.labels.topology\.kubernetes\.io/zone}')
# SSH into the node
gcloud compute ssh "$NODE" --zone "$ZONE"All subsequent commands in this guide should be run on the GKE node itself.
On the GKE node, clone, build, and run Quark to ensure it can capture K8s-aware events on its own.
# Prerequisites for Quark and Auditbeat
sudo apt-get update
sudo apt-get install -y clang gcc make m4 golang zstd
sudo apt-get install -y librpm-dev rpm pkg-config build-essential
sudo apt-get install -y "linux-tools-$(uname -r)"
# Clone Quark and build the binaries
git clone --recursive https://github.com/elastic/quark.git
cd quark
git checkout eacf8ac5aaf1d58e4e57703f414c41bff0021013
makeThis produces two executables: quark-mon and quark-kube-talker.
Now, run quark-mon as root. The -K flag should pass kubeconfig which should already exist on the node. Pass NODE_NAME env with the name of the node (this is often the same as the hostname) This is necessary to allow Quark to communicate with the Kubelet and make API calls to request pod names and other metadata from the current node.
sudo env NODE_NAME="<node_name>" ./quark-mon -E -s -K /var/lib/kubelet/kubeconfigTo test, create a pod from your local machine (not the GKE node). quark-mon should output JSON ECS events related to this pod's creation and execution.
# Run this on your local machine in a separate terminal
kubectl run test-shell --image=ubuntu:24.04 --restart=Never -- /bin/sleep 30Verification: In the quark-mon output on the GKE node, look for JSON events. Confirm you see container.* and orchestrator.* fields populated. If these fields are missing, the link to the Kubelet has failed.
Example snippet for the above command:
"executable":"/usr/bin/sleep","command_line":["/bin/sleep","30"],"args_count":2,"working_directory":"/"},"container":{"id":"containerd://37e0112be444acbf0944ff48715ec00ff99d520eb5567650967b6f955ad81613","name":"test-shell","runtime":"docker"
Next, build a custom version of Auditbeat that will execute and manage our Quark binary.
On the GKE node:
# Clone Beats in a separate directory
cd ..
git clone https://github.com/elastic/beats.git
cd beats
git checkout a3f5c5a691fa0e3b984440411840bfd88c0f9c90
# Install the Mage build tool
go install github.com/magefile/mage@latest
# Navigate to the auditbeat directory
cd x-pack/auditbeat
# IMPORTANT: Copy the quark binaries into this directory
cp ~/quark/quark-mon .
cp ~/quark/quark-kube-talker .
# Build Auditbeat
~/go/bin/mage -init
~/go/bin/mage buildThis produces an auditbeat executable in the current directory (~/beats/x-pack/auditbeat).
Create an config.yml configuration file in the same directory. Give it permissions and ownership that auditbeat requires:
sudo chown root:root config.yml
sudo chmod go-w config.ymlPaste the following configuration, replacing the <...> placeholders with your Elastic Cloud credentials.
auditbeat.modules:
- module: system
datasets:
- process
- socket
period: 10s
state.period: 2m
process.backend: "kernel_tracing"
# Your Elastic Cloud details go here
cloud.id: <YOUR_CLOUD_ID>
cloud.auth: elastic:<YOUR_ELASTIC_PASSWORD>Run Auditbeat and pass NODE_NAME env like before:
sudo env NODE_NAME=<node_name> KUBECONFIG=/var/lib/kubelet/kubeconfig ./auditbeat -e -c config.ymlYou should see output logs indicating events are being published to Elasticsearch.
Finally, generate some activity in the cluster and find the corresponding enriched events in Kibana.
From your local machine, run a short-lived process in a pod.
kubectl run -it process-test-shell --image=ubuntu:24.04 --restart=Never -- /bin/bash
# then in the spawned shell run any process, for example /bin/false
/bin/falseIn Kibana:
- Go to Discover.
- Add a
auditbeat-*data view. - Use the following KQL query to find the event:
process.name : "false" and container.id : *
Verification: Inspect the event document for /bin/false process execution. You should see fields like container.id, container.name, orchestrator.resource.name: "process-test-shell", etc.