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

new: driver selection in falco.yaml #2413

Merged
merged 29 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0548d46
wip: driver selection in falco.yaml
therealbobo Feb 6, 2023
1f3a1ce
refacotr(configuration): enhance readability of get_driver_mode
therealbobo Nov 6, 2023
d1989bd
new(falco.yaml): added driver selection section
therealbobo Nov 6, 2023
4fbd740
new(userspace/falco): select driver from config
therealbobo Nov 6, 2023
f72de02
chore(userspace,falco.yaml): rename new config key to `driver.kind`.
FedeDP Nov 14, 2023
49b8d7a
chore(userspace): renamed `driver.` config to `engine.`; renamed `eng…
FedeDP Nov 17, 2023
ffcbe37
cleanup: some renaming from `bpf` to `ebpf`
Andreagit97 Nov 17, 2023
8a8fdca
fix: use only new config instead of old command line options
Andreagit97 Nov 17, 2023
9e7f948
cleanup: move some initializations and add helpers
Andreagit97 Nov 17, 2023
5441cee
chore(userspace): properly let old config keys override new ones when…
FedeDP Nov 17, 2023
f9bfcf3
fix: always initialize the engine configs
Andreagit97 Nov 17, 2023
fc50b66
tests: add a basic test to check config precedence
Andreagit97 Nov 17, 2023
8649733
fix: use `drop_failed_exit` instead of just `drop_failed`
Andreagit97 Nov 18, 2023
2b3922b
new: allow to use only one between the config and the command line
Andreagit97 Nov 18, 2023
6cad918
fix: take into consideration that `load_yaml` is called more than once
Andreagit97 Nov 18, 2023
a7e3cb6
cleanup: rename `cpus_for_each_syscall_buffer`
Andreagit97 Nov 18, 2023
6e07a86
docs: add some descriptions in falco.yaml
Andreagit97 Nov 18, 2023
3892769
tests: call the callback `action` only once
Andreagit97 Nov 18, 2023
1eb6375
docs: fix some docs
Andreagit97 Nov 18, 2023
edb6e7c
docs: add a comment on missing config files
Andreagit97 Nov 18, 2023
dd9a1dd
docs: fix codespell
Andreagit97 Nov 19, 2023
e04b910
test: don't test load config if we are under wasm
Andreagit97 Nov 21, 2023
7b39c8e
chore(userspace,unit_tests): renamed `engine.replay.trace_file` to `e…
FedeDP Nov 22, 2023
8f3edcc
chore(userspace): small round of review-induced fixes.
FedeDP Nov 23, 2023
231e134
cleanup: move some macros inside a shared file
Andreagit97 Nov 23, 2023
4b083bb
new: add some deprecation warnings
Andreagit97 Nov 23, 2023
0c2f8c0
fix: fix some broken tests
Andreagit97 Nov 23, 2023
3dc8dad
docs: improve a log
Andreagit97 Nov 23, 2023
5ea1359
cleanup: rename `modern-ebpf` into `modern_ebpf`
Andreagit97 Nov 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
221 changes: 212 additions & 9 deletions falco.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
# (Falco environment variables)
# Falco rules files
# rules_file
# Falco engine
# engine
# Falco plugins
# load_plugins
# plugins
Expand Down Expand Up @@ -63,10 +65,10 @@
# syscall_event_drops
# metrics
# Falco performance tuning (advanced)
# syscall_buf_size_preset
# syscall_drop_failed_exit
# syscall_buf_size_preset [DEPRECATED]
# syscall_drop_failed_exit [DEPRECATED]
# base_syscalls
# modern_bpf.cpus_for_each_syscall_buffer
# modern_bpf.cpus_for_each_syscall_buffer [DEPRECATED]


################################
Expand Down Expand Up @@ -94,7 +96,7 @@
# - "HOST_ROOT": Specifies the prefix to the underlying host `/proc` filesystem
# when deploying Falco over a container with read-only host mounts instead of
# directly on the host. Defaults to "/host".
# - "FALCO_BPF_PROBE": Specify a custom path to the BPF object code file (`bpf`
# - "FALCO_BPF_PROBE": DEPRECATED. Specify a custom path to the BPF object code file (`bpf`
# driver). This is not needed for the modern_bpf driver.
# - "FALCO_HOSTNAME": Customize the hostname output field logged by Falco by
# setting the "FALCO_HOSTNAME" environment variable.
Expand Down Expand Up @@ -145,6 +147,196 @@ rules_file:
- /etc/falco/falco_rules.local.yaml
- /etc/falco/rules.d

################
# Falco engine #
################

# [Stable] `engine`
#
# --- [Description]
#
# Falco supports different engines to generate events.
# Choose the appropriate engine kind based on your system's configuration and requirements.
#
# Available engines:
# - `kmod`: Kernel Module (Kernel Module)
# - `ebpf`: eBPF (eBPF probe)
# - `modern-ebpf`: Modern eBPF (CO-RE eBPF probe)
# - `gvisor`: gVisor (gVisor sandbox)
# - `replay`: Replay a scap trace file
# - `none`: No event producer loaded, useful to run with plugins.
#
# Only one engine can be specified in the `kind` key.
# Moreover, for each engine multiple options might be available,
# grouped under engine-specific configuration keys.
# Some of them deserve an in-depth description:
#
################### `buf_size_preset`
#
# --- [Description]
#
# The syscall buffer index determines the size of the shared space between Falco
# and its drivers. This shared space serves as a temporary storage for syscall
# events, allowing them to be transferred from the kernel to the userspace
# efficiently. The buffer size for each online CPU is determined by the buffer
# index, and each CPU has its own dedicated buffer. Adjusting this index allows
# you to control the overall size of the syscall buffers.
#
# --- [Usage]
#
# The index 0 is reserved, and each subsequent index corresponds to an
# increasing size in bytes. For example, index 1 corresponds to a size of 1 MB,
# index 2 corresponds to 2 MB, and so on:
#
# [(*), 1 MB, 2 MB, 4 MB, 8 MB, 16 MB, 32 MB, 64 MB, 128 MB, 256 MB, 512 MB]
# ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
# | | | | | | | | | | |
# 0 1 2 3 4 5 6 7 8 9 10
#
#
# The buffer dimensions in bytes are determined by the following requirements:
# (1) a power of 2.
# (2) a multiple of your system_page_dimension.
# (3) greater than `2 * (system_page_dimension).
#
# The buffer size constraints may limit the usability of certain indexes. Let's
# consider an example to illustrate this:
#
# If your system has a page size of 1 MB, the first available buffer size would
# be 4 MB because 2 MB is exactly equal to 2 * (system_page_size), which is not
# sufficient as we require more than 2 * (system_page_size). In this example, it
# is evident that if the page size is 1 MB, the first index that can be used is 3.
#
# However, in most cases, these constraints do not pose a limitation, and all
# indexes from 1 to 10 can be used. You can check your system's page size using
# the Falco `--page-size` command-line option.
#
# --- [Suggestions]
#
# The buffer size was previously fixed at 8 MB (index 4). You now have the
# option to adjust the size based on your needs. Increasing the size, such as to
# 16 MB (index 5), can reduce syscall drops in heavy production systems, but may
# impact performance. Decreasing the size can speed up the system but may
# increase syscall drops. It's important to note that the buffer size is mapped
# twice in the process' virtual memory, so a buffer of 8 MB will result in a 16
# MB area in virtual memory. Use this parameter with caution and only modify it
# if the default size is not suitable for your use case.
#
################### `drop_failed_exit`
#
# --- [Description]
#
# Enabling this option in Falco allows it to drop failed system call exit events
# in the kernel drivers before pushing them onto the ring buffer. This
# optimization can result in lower CPU usage and more efficient utilization of
# the ring buffer, potentially reducing the number of event losses. However, it
# is important to note that enabling this option also means sacrificing some
# visibility into the system.
#
################### `cpus_for_each_buffer` (modern-ebpf only)
#
# --- [Description]
#
# The modern_bpf driver in Falco utilizes the new BPF ring buffer, which has a
# different memory footprint compared to the current BPF driver that uses the
# perf buffer. The Falco core maintainers have discussed the differences and
# their implications, particularly in Kubernetes environments where limits need
# to be carefully set to avoid interference with the Falco daemonset deployment
# from the OOM killer. Based on guidance received from the kernel mailing list,
# it is recommended to assign multiple CPUs to one buffer instead of allocating
# a buffer for each CPU individually. This helps optimize resource allocation
# and prevent potential issues related to memory usage.
#
# This is an index that controls how many CPUs you want to assign to a single
# syscall buffer (ring buffer). By default, for modern_bpf every syscall buffer
# is associated to 2 CPUs, so the mapping is 1:2. The modern BPF probe allows
# you to choose different mappings, for example, changing the value to `1`
# results in a 1:1 mapping and would mean one syscall buffer for each CPU (this
# is the default for the `bpf` driver).
#
# --- [Usage]
#
# You can choose an index from 0 to MAX_NUMBER_ONLINE_CPUs to set the dimension
# of the syscall buffers. The value 0 represents a single buffer shared among
# all online CPUs. It serves as a flexible option when the exact number of
# online CPUs is unknown. Here's an example to illustrate this:
#
# Consider a system with 7 online CPUs:
#
# CPUs 0 X 2 3 X X 6 7 8 9 (X means offline CPU)
#
# - `1` means a syscall buffer for each CPU so 7 buffers
#
# CPUs 0 X 2 3 X X 6 7 8 9 (X means offline CPU)
# | | | | | | |
# BUFFERs 0 1 2 3 4 5 6
#
# - `2` (Default value) means a syscall buffer for each CPU pair, so 4 buffers
#
# CPUs 0 X 2 3 X X 6 7 8 9 (X means offline CPU)
# | | | | | | |
# BUFFERs 0 0 1 1 2 2 3
#
# Please note that in this example, there are 4 buffers in total. Three of the
# buffers are associated with pairs of CPUs, while the last buffer is mapped to
# a single CPU. This arrangement is necessary because we have an odd number of
# CPUs.
#
# - `0` or `MAX_NUMBER_ONLINE_CPUs` mean a syscall buffer shared between all
# CPUs, so 1 buffer
#
# CPUs 0 X 2 3 X X 6 7 8 9 (X means offline CPU)
# | | | | | | |
# BUFFERs 0 0 0 0 0 0 0
#
# Moreover, you have the option to combine this parameter with
# `buf_size_preset` index. For instance, you can create a large shared
# syscall buffer of 512 MB (using buf_size_preset=10) that is
# allocated among all the online CPUs.
#
# --- [Suggestions]
#
# The default choice of index 2 (one syscall buffer for each CPU pair) was made
# because the modern bpf probe utilizes a different memory allocation strategy
# compared to the other two drivers (bpf and kernel module). However, you have
# the flexibility to experiment and find the optimal configuration for your
# system.
#
# When considering a fixed buf_size_preset and a fixed buffer dimension:
# - Increasing this configs value results in lower number of buffers and you can
# speed up your system and reduce memory usage
# - However, using too few buffers may increase contention in the kernel,
# leading to a slowdown.
#
# If you have low event throughputs and minimal drops, reducing the number of
# buffers (higher `cpus_for_each_buffer`) can lower the memory footprint.
#
engine:
kind: kmod
kmod:
buf_size_preset: 4
drop_failed_exit: false
ebpf:
# path to the elf file to load.
probe: /path/to/probe.o
FedeDP marked this conversation as resolved.
Show resolved Hide resolved
buf_size_preset: 4
drop_failed_exit: false
modern-ebpf:
cpus_for_each_buffer: 2
buf_size_preset: 4
drop_failed_exit: false
replay:
# path to the capture file to replay.
capture_file: /path/to/file.scap
FedeDP marked this conversation as resolved.
Show resolved Hide resolved
gvisor:
# A Falco-compatible configuration file can be generated with
# '--gvisor-generate-config' and utilized for both runsc and Falco.
config: /path/to/gvisor_config.yaml
leogr marked this conversation as resolved.
Show resolved Hide resolved
# Set gVisor root directory for storage of container state when used
# in conjunction with 'gvisor.config'. The 'gvisor.root' to be passed
# is the one usually passed to 'runsc --root' flag.
root: ""

#################
# Falco plugins #
#################
Expand Down Expand Up @@ -769,12 +961,15 @@ metrics:
convert_memory_to_mb: true
include_empty_values: false


#######################################
# Falco performance tuning (advanced) #
#######################################

# [Stable] `syscall_buf_size_preset`
# [DEPRECATED] `syscall_buf_size_preset`
#
# Deprecated in favor of engine.{kmod,ebpf,modern-ebpf}.buf_size_preset.
# This config is evaluated only if the default `engine` config block is not changed,
# otherwise it is ignored.
#
# --- [Description]
#
Expand Down Expand Up @@ -826,10 +1021,14 @@ metrics:
# if the default size is not suitable for your use case.
syscall_buf_size_preset: 4

# [Experimental] `syscall_drop_failed_exit`
# [DEPRECATED] `syscall_drop_failed_exit`
#
# Deprecated in favor of engine.{kmod,ebpf,modern-ebpf}.drop_failed_exit.
# This config is evaluated only if the default `engine` config block is not changed,
# otherwise it is ignored.
#
# Enabling this option in Falco allows it to drop failed system call exit events
# in the kernel driver before pushing them onto the ring buffer. This
# in the kernel drivers before pushing them onto the ring buffer. This
# optimization can result in lower CPU usage and more efficient utilization of
# the ring buffer, potentially reducing the number of event losses. However, it
# is important to note that enabling this option also means sacrificing some
Expand Down Expand Up @@ -951,7 +1150,11 @@ base_syscalls:
custom_set: []
repair: false

# [Stable] `modern_bpf.cpus_for_each_syscall_buffer`, modern_bpf only
# [DEPRECATED] `modern_bpf.cpus_for_each_syscall_buffer`, modern_bpf only
#
# Deprecated in favor of engine.modern-ebpf.cpus_for_each_buffer.
# This config is evaluated only if the default `engine` config block is not changed,
# otherwise it is ignored.
#
# --- [Description]
#
Expand Down
9 changes: 9 additions & 0 deletions unit_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,18 @@ FetchContent_MakeAvailable(googletest)
file(GLOB_RECURSE ENGINE_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/engine/*.cpp)
file(GLOB_RECURSE FALCO_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/falco/*.cpp)

# Create a libscap_test_var.h file with some variables used by our tests
# for example the kmod path or the bpf path.
configure_file (
"${CMAKE_CURRENT_SOURCE_DIR}/falco_test_var.h.in"
"${CMAKE_CURRENT_BINARY_DIR}/falco_test_var.h"
)

set(FALCO_UNIT_TESTS_SOURCES
"${ENGINE_TESTS}"
falco/test_configuration.cpp
falco/app/actions/test_select_event_sources.cpp
falco/app/actions/test_load_config.cpp
)

if (CMAKE_SYSTEM_NAME MATCHES "Linux")
Expand All @@ -45,6 +53,7 @@ set(FALCO_UNIT_TESTS_INCLUDES
${CMAKE_SOURCE_DIR}/userspace
${CMAKE_BINARY_DIR}/userspace/falco # we need it to include indirectly `config_falco.h` file
${CMAKE_SOURCE_DIR}/userspace/engine # we need it to include indirectly `falco_common.h` file
"${CMAKE_CURRENT_BINARY_DIR}" # we need it to include `falco_test_var.h`
)

set(FALCO_UNIT_TESTS_DEPENDENCIES
Expand Down
4 changes: 2 additions & 2 deletions unit_tests/falco/app/actions/app_action_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ limitations under the License.
#include <falco/app/state.h>
#include <falco/app/actions/actions.h>

#define EXPECT_ACTION_OK(r) { EXPECT_TRUE(r.success); EXPECT_TRUE(r.proceed); EXPECT_EQ(r.errstr, ""); }
#define EXPECT_ACTION_FAIL(r) { EXPECT_FALSE(r.success); EXPECT_FALSE(r.proceed); EXPECT_NE(r.errstr, ""); }
#define EXPECT_ACTION_OK(r) { auto result = r; EXPECT_TRUE(result.success); EXPECT_TRUE(result.proceed); EXPECT_EQ(result.errstr, ""); }
#define EXPECT_ACTION_FAIL(r) { auto result = r; EXPECT_FALSE(result.success); EXPECT_FALSE(result.proceed); EXPECT_NE(result.errstr, ""); }
20 changes: 10 additions & 10 deletions unit_tests/falco/app/actions/test_configure_syscall_buffer_num.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,30 @@ TEST(ActionConfigureSyscallBufferNum, variable_number_of_CPUs)
FAIL() << "cannot get the number of online CPUs from the system\n";
}

// not modern bpf engine, we do nothing
// not modern ebpf engine, we do nothing
{
falco::app::state s;
s.options.modern_bpf = false;
s.config->m_engine_mode = engine_kind_t::MODERN_EBPF;
EXPECT_ACTION_OK(action(s));
}

// modern bpf engine, with an invalid number of CPUs
// modern ebpf engine, with an invalid number of CPUs
// default `m_cpus_for_each_syscall_buffer` to online CPU number
{
falco::app::state s;
s.options.modern_bpf = true;
s.config->m_cpus_for_each_syscall_buffer = online_cpus + 1;
s.config->m_engine_mode = engine_kind_t::MODERN_EBPF;
s.config->m_modern_ebpf.m_cpus_for_each_buffer = online_cpus + 1;
EXPECT_ACTION_OK(action(s));
EXPECT_EQ(s.config->m_cpus_for_each_syscall_buffer, online_cpus);
EXPECT_EQ(s.config->m_modern_ebpf.m_cpus_for_each_buffer, online_cpus);
}

// modern bpf engine, with an valid number of CPUs
// modern ebpf engine, with a valid number of CPUs
// we don't modify `m_cpus_for_each_syscall_buffer`
{
falco::app::state s;
s.options.modern_bpf = true;
s.config->m_cpus_for_each_syscall_buffer = online_cpus - 1;
s.config->m_engine_mode = engine_kind_t::MODERN_EBPF;
s.config->m_modern_ebpf.m_cpus_for_each_buffer = online_cpus - 1;
EXPECT_ACTION_OK(action(s));
EXPECT_EQ(s.config->m_cpus_for_each_syscall_buffer, online_cpus - 1);
EXPECT_EQ(s.config->m_modern_ebpf.m_cpus_for_each_buffer, online_cpus - 1);
}
}
Loading
Loading