.png)
Eu estive na Cloud Native Security Con em Seattle com total intenção de entrar no dia de OTEL, então lendo o assunto de segurança aplicada a fluxos de trabalho Cloud Native nos dias seguintes até CTF como um exercício profissional. Isso foi felizmente finalizado por um novo entendimento de eBPF, que tem minhas telas, carreira, fluxos de trabalho e atitude com muita necessidade de uma melhoria com novas abordagens para resolver problemas de fluxo de trabalho.
Então, consegui chegar à festa do eBPF e desde então tenho participado de clínica após clínica sobre o assunto. Aqui, gostaria de "desempacotar" o eBPF como uma solução técnica, mapeada diretamente para o que fazemos na prática (mesmo que esteja um pouco fora), e passar pelo eBPF através da minha experimentação em suporte a cargas de trabalho InterSystems IRIS, particularmente no Kubernetes, mas não necessariamente vazio em cargas de trabalho autônomas.
.png)
eBPF
eBPF (extended Berkeley Packet Filter) é um recurso poderoso do kernel Linux que implementa uma VM dentro do espaço do kernel e torna possível executar aplicativos sandboxes de forma segura com guias. Esses aplicativos podem "mapear" dados para o espaço do usuário para observabilidade, rastreamento, segurança e redes. Eu penso nisso como um "cheirador" do SO, onde tradicionalmente estava associado ao BPF e redes, e a versão estendida "cheira" pontos de rastreamento, processos, agendamento, execução e acesso a dispositivos de bloco. Se você não comprou minha analogia de eBPF, aqui está uma dos prós:
"O que JavaScript é para o browser, eBPF é para o Linux Kernel"
JavaScript permite que você anexe callbacks a eventos no DOM para trazer recursos dinâmicos à sua página web. De maneira semelhante, o eBPF permite conectar-se a eventos do kernel e estender sua lógica quando esses eventos são acionados!
SE; a seguinte métrica Prometheus parece impossível para você, empregue eBPF para observar processos que devem estar lá e monitorar em banda através do kernel
# HELP iris_instance_status The thing thats down telling us its down.
# TYPE iris_instance_status gauge
iris_instance_status 0
ObjectScript
ObjectScript
SE; você está cansado de implorar para o seguinte para um sidecar obter a observabilidade necessária, Adeus sidecars
iris-sidecar:
resources:
requests:
memory: "2Mi"
cpu: "125m"
ObjectScript
ObjectScript
onde
Uma das coisas mais satisfatórias sobre como o eBPF é aplicado é onde ele roda... em uma VM, dentro do kernel. E graças ao Linux Namespacing, você pode adivinhar o quão poderoso isso é em um ambiente nativo da nuvem, quanto mais em um kernel baseado em algum tipo de virtualização ou uma grande máquina ghetto blaster de ferro com hardware admirável.
.png)
"Olá Mundi" Obrigatório
Para aqueles de vocês que gostam de experimentar coisas por si mesmos e desde o "começo", por assim dizer, eu saúdo vocês com um obrigatório "Olá Mundo", torcido para ser um pouco "iristico". No entanto, é amplamente entendido que programar em eBPF não se tornará uma habilidade exercida com frequência, mas concentrada em indivíduos que desenvolvem o kernel Linux ou constroem ferramentas de monitoramento de próxima geração.
Eu uso Pop OS/Ubuntu, e aqui está meu código de consulta para entrar rapidamente no mundo do eBPF em 23.04:
sudo apt install -y zip bison build-essential cmake flex git libedit-dev \
libllvm15 llvm-15-dev libclang-15-dev python3 zlib1g-dev libelf-dev libfl-dev python3-setuptools \
liblzma-dev libdebuginfod-dev arping netperf iperf libpolly-15-dev
git clone https://github.com/iovisor/bcc.git
mkdir bcc/build; cd bcc/build
cmake ..
make
sudo make install
cmake -DPYTHON_CMD=python3 ..
pushd ../src/python/
make
sudo make install
popd
cd bcc
make install
Bash
Bash
Primeiro assegure que o kernel objetivo tem as coisas necessárias...
cat /boot/config-$(uname -r) | grep 'CONFIG_BPF'
CONFIG_BPF=y
Bash
Bash
Se `CONFIG_BPF=y` está na sua janela em algum lugar, podemos seguir.
O que queremos alcançar aqui com esse simples olá mundo é obter visibilidade de quando o IRIS está fazendo chamadas de sistema LInux, sem o uso de nada além de ferramentas eBPF e o próprio kernel.
Aqui está uma boa maneira de seguir com a exploração:
1️⃣ Ache uma chamada de sistema Linux de interesse
sudo ls /sys/kernel/debug/tracing/events/syscalls
ObjectScript
ObjectScript
Para este exemplo, vamos
Para este exemplo, vamos interceptar quando alguém (modificado para interceptar IRIS), cria um diretório através da chamada de sistema sys_enter_mkdir
.
2️⃣ Insira isso no Olá Mundo que segue
Seu programa BPF para carregar e rodar está na variável BPF_SOURCE_CODE, modifique para incluir a syscall que você deseja interceptar.
from bcc import BPF
from bcc.utils import printb
BPF_SOURCE_CODE = r"""
TRACEPOINT_PROBE(syscalls, sys_enter_mkdir) {
bpf_trace_printk("Directory was created by IRIS: %s\n", args->pathname);
return 0;
}
"""
bpf = BPF(text = BPF_SOURCE_CODE)
print("Go create a dir with IRIS...")
print("CTRL-C to exit")
while True:
try:
(task, pid, cpu, flags, ts, msg) = bpf.trace_fields()
if "iris" in task.decode("utf-8"):
printb(b"%s-%-6d %s" % (task, pid, msg))
except ValueError:
continue
except KeyboardInterrupt:
break
Python
Python
3️⃣ Carregue no Kernel, Rode
.png)
Crie um diretório em IRIS
.png)
Inspecione o rastreio!
.png)
Binários Impulsionados por eBPF
Não leva muito tempo quando se passa pelo repositório bcc e percebe que há muitos exemplos, ferramentas e binários por aí que aproveitam o eBPF para fazer traçamentos divertidos, e "grep" nesse caso será suficiente para derivar algum valor.
Vamos fazer exatamente isso em um start e stop do IRIS com alguns exemplos fornecidos.
execsnoop Rastreie novos processes via syscalls exec().
Este aqui conta uma história dos argumentos ao irisdb no start/stop
sudo python3 execsnoopy.py | grep iris
iris 3014275 COMM PID PPID RET ARGS
3011645 0 /usr/bin/iris stop IRIS quietly restart
irisstop 3014275 3011645 0 /usr/irissys/bin/irisstop quietly restart
irisdb 3014276 3014275 0 ./irisdb -s/data/IRIS/mgr/ -cV
irisdb 3014277 3014275 0 ./irisdb -s/data/IRIS/mgr/ -U -B OPT^SHUTDOWN(1)
irisdb 3014279 3014275 0 ./irisdb -s/data/IRIS/mgr/ -cV
irisdb 3014280 3014275 0 ./irisdb -s/data/IRIS/mgr/ -cV
sh 3014281 3014275 0 /bin/sh -c -- /usr/irissys/bin/irisdb -s /data/IRIS/mgr/ -cL
irisdb 3014282 3014281 0 /usr/irissys/bin/irisdb -s /data/IRIS/mgr/ -cL
irisdb 3014283 3014275 0 ./irisdb -s/data/IRIS/mgr/ -cV
irisrecov 3014284 3014275 0 ./irisrecov /data/IRIS/mgr/ quietly
iriswdimj 3014678 3014284 0 /usr/irissys/bin/iriswdimj -t
iriswdimj 3014679 3014284 0 /usr/irissys/bin/iriswdimj -j /data/IRIS/mgr/
rm 3014680 3014284 0 /usr/bin/rm -f iris.use
irisdb 3014684 3014275 0 ./irisdb -s/data/IRIS/mgr/ -w/data/IRIS/mgr/ -cd -B -V CLONE^STU
sh 3014685 3014275 0 /bin/sh -c -- /usr/irissys/bin/irisdb -s /data/IRIS/mgr/ -cL
irisdb 3014686 3014685 0 /usr/irissys/bin/irisdb -s /data/IRIS/mgr/ -cL
irisdb 3014687 3014275 0 ./irisdb -s/data/IRIS/mgr/ -cV
irisrecov 3014688 3014275 0 ./irisrecov /data/IRIS/mgr/ quietly
iriswdimj 3015082 3014688 0 /usr/irissys/bin/iriswdimj -t
iriswdimj 3015083 3014688 0 /usr/irissys/bin/iriswdimj -j /data/IRIS/mgr/
rm 3015084 3014688 0 /usr/bin/rm -f iris.use
irisdb 3015088 3014275 0 ./irisdb -s/data/IRIS/mgr/ -w/data/IRIS/mgr/ -cc -B -C/data/IRIS/iris.cpf*IRIS
irisdb 3015140 3014275 0 ./irisdb -s/data/IRIS/mgr/ -w/data/IRIS/mgr/ -U -B -b1024 -Erunlevel=sys/complete QUIET^STU
irisdb 3015142 3015140 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p13 START^MONITOR
irisdb 3015143 3015140 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p13 START^CLNDMN
irisdb 3015144 3015140 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p13 ErrorPurge^Config.Startup
irisdb 3015145 3015140 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p13 START^LMFMON
irisdb 3015146 3015140 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p13 ^RECEIVE
irisdb 3015147 3015146 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p16 SCAN^JRNZIP
irisdb 3015148 3015140 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p13 OneServerJob^STU
irisdb 3015149 3015148 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p19 Master^%SYS.SERVER
irisdb 3015150 3015140 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p13 systemRestart^%SYS.cspServer2
irisdb 3015151 3015140 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p13 SERVERS^STU1
requirements_ch 3015152 3015140 0 /usr/irissys/bin/requirements_check
dirname 3015153 3015152 0 /usr/bin/dirname /usr/irissys/bin/requirements_check
httpd 3015215 3015151 0 /usr/irissys/httpd/bin/httpd -f /data/IRIS/httpd/conf/httpd.conf -d /usr/irissys/httpd -c Listen 52773
irisdb 3015362 3015140 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p13 OnSystemStartup^HS.FHIRServer.Util.SystemStartup
irisdb 3015363 3015140 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p13 OnSystemStartup^HS.HC.Util.SystemStartup
irisdb 3015364 3015151 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p21 RunManager^%SYS.Task
irisdb 3015365 3015151 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p21 Start^%SYS.Monitor.Control
irisdb 3015366 3015151 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p21 Daemon^LOGDMN
irisdb 3015367 3015151 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p21 RunDaemon^%SYS.WorkQueueMgr
irisdb 3015368 3015151 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p21 RunRemoteQueueDaemon^%SYS.WorkQueueMgr
irisdb 3015369 3015362 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p19 RunAll^HS.HC.Util.Installer.Upgrade.BackgroundItem
irisdb 3015370 3014275 0 ./irisdb -s/data/IRIS/mgr/ -cV
irisdb 3015436 3015367 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p25 startWork^%SYS.WorkQueueMgr
irisdb 3015437 3015367 0 /usr/irissys/bin/irisdb -s/data/IRIS/mgr -cj -p25 startWork^%SYS.WorkQueueMgr
Bash
Bash
statsnoop Rastreie stat() syscalls... retorna atributos de arquivo sobre um inode, acesso arquivo/diretório.
Este aqui é informativo para o acesso ao nível de diretório e arquivo durante uma inicialização/parada... um pouco loquaz, mas informativo sobre o que o iris está fazendo durante a inicialização, incluindo acesso cpf, diários, atividade wij e o uso de ferramentas de sistema para realizar o trabalho.
sudo python3 statsnoop.py | grep iris
3016831 irisdb 0 0 /data/IRIS/mgr/
3016831 irisdb 0 0 /data/IRIS/mgr/
3016825 irisstop 0 0 /data/IRIS/mgr
3016825 irisstop 0 0 /usr/irissys/bin/irisuxsusr
3016825 irisstop 0 0 ./irisdb
3016825 irisstop 0 0 ../bin
3016832 sh -1 2 /usr/irissys/bin/glibc-hwcaps/x86-64-v3/
3016832 sh -1 2 /usr/irissys/bin/glibc-hwcaps/x86-64-v2/
3016832 sh 0 0 /usr/irissys/bin/
3016832 sh 0 0 /home/irisowner
3016833 irisdb -1 2 /usr/irissys/bin/glibc-hwcaps/x86-64-v3/
3016833 irisdb -1 2 /usr/irissys/bin/glibc-hwcaps/x86-64-v2/
3016833 irisdb 0 0 /usr/irissys/bin/
3016833 irisdb 0 0 /data/IRIS/mgr/
3016833 irisdb 0 0 /data/IRIS/mgr/
3016833 irisdb 0 0 /data/IRIS/mgr/
3016834 irisstop 0 0 ./irisdb
3016834 irisstop 0 0 ../bin
3016834 irisdb -1 2 /usr/irissys/bin/glibc-hwcaps/x86-64-v3/
3016834 irisdb -1 2 /usr/irissys/bin/glibc-hwcaps/x86-64-v2/
3016834 irisdb 0 0 /usr/irissys/bin/
3016834 irisdb 0 0 /data/IRIS/mgr/
3016834 irisdb 0 0 /data/IRIS/mgr/
3016835 irisstop 0 0 ./irisrecov
3016835 irisstop 0 0 ../bin
3016835 irisrecov -1 2 /usr/irissys/bin/glibc-hwcaps/x86-64-v3/
3016835 irisrecov -1 2 /usr/irissys/bin/glibc-hwcaps/x86-64-v2/
3016835 irisrecov 0 0 /usr/irissys/bin/
3016835 irisrecov 0 0 /home/irisowner
3016835 irisrecov 0 0 .
3016835 irisrecov 0 0 iris.cpf
3016841 irisrecov 0 0 /usr/bin/cut
3016841 irisrecov 0 0 /usr/bin/tr
3016841 irisrecov 0 0 /usr/bin/sed
3017761 requirements_ch 0 0 /home/irisowner
3017761 requirements_ch -1 2 /usr/irissys/bin/requirements.isc
3017691 irisdb 0 0 /data/IRIS/iris.cpf
3017691 irisdb 0 0 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf_5275
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf_5275
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf_5275
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /data/IRIS/iris.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /data/IRIS/iris.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /data/IRIS/iris.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /data/IRIS/iris.cpf
3017691 irisdb -1 2 /usr/lib64/libcrypto.so.1.1
3017691 irisdb -1 2 /usr/lib64/libcrypto.so.3
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /data/IRIS/iris.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /data/IRIS/iris.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /data/IRIS/iris.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /data/IRIS/iris.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /data/IRIS/iris.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /data/IRIS/iris.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /data/IRIS/iris.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /data/IRIS/iris.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /data/IRIS/iris.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /data/IRIS/iris.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf_20240908
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /data/IRIS/_LastGood_.cpf_5275
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /data/IRIS/_LastGood_.cpf_5275
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb -1 2 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /etc/localtime
3017691 irisdb 0 0 /data/IRIS/_LastGood_.cpf
3017691 irisdb 0 0 /data/IRIS/mgr/irisaudit/
3017691 irisdb 0 0 /data/IRIS/mgr/irisaudit/
3017691 irisdb 0 0 /data/IRIS/mgr/irisaudit/
3017691 irisdb 0 0 /data/IRIS/mgr/irisaudit/
3017691 irisdb 0 0 /data/IRIS/mgr/irisaudit/
3017691 irisdb 0 0 /data/IRIS/mgr/irisaudit/
3017756 irisdb -1 2 /data/IRIS/mgr/journal/20240908.002
3017756 irisdb -1 2 /data/IRIS/mgr/journal/20240908.002
3017756 irisdb 0 0 /data/IRIS/mgr/journal/20240908.002z
3017756 irisdb -1 2 /data/IRIS/mgr/journal/20240908.002
3017756 irisdb 0 0 /data/IRIS/mgr/journal/20240908.002z
3017756 irisdb -1 2 /data/IRIS/mgr/journal/20240908.001
Bash
Bash
Flamegraphs

Uma das coisas mais legais que encontrei com a ferramenta eBPF foi a implementação de flamegraphs de Brendan Gregg por cima da saída bpf para entender desempenho e pilhas de chamadas.
Dado o seguinte registro de desempenho durante uma inicialização/parada de IRIS:
sudo perf record -F 99 -a -g -- sleep 60
[ perf record: Woken up 7 times to write data ]
[ perf record: Captured and wrote 3.701 MB perf.data (15013 samples) ]
Bash
Bash
Gere o seguinte flamegrapth com o descrito abaixo:
sudo perf script > out.perf
./stackcollapse-perf.pl out.perf > /tmp/gar.thing
./flamegraph.pl /tmp/gar.thing > flamegraph.svg
ObjectScript
ObjectScript
.png)
Eu tentei o upload do svg, mas não funcionou com este editor e, por algum motivo, não consegui anexá-lo. Entenda, porém, que ele é interativo e clicável para detalhar as pilhas de chamadas, além de apenas parecer legal.
- "A função na parte inferior é a função on-CPU. Quanto mais alto no eixo y, mais profundamente aninhada está a função.
- A largura de cada função no gráfico representa a quantidade de tempo que a função levou para executar como uma porcentagem do tempo total de sua função pai.
- Encontrar funções que são altas no eixo y (profundamente aninhadas) e largas no eixo x (intensivas em tempo) é uma ótima maneira de reduzir problemas de desempenho e otimização.
"altas e largas" <--- 👀
red == nível de usuário
orange == kernel
yellow == c++
green == JIT, java etc.
Eu realmente gostei dessa explicação da interpretação de flamegraphs apresentada aqui (crédito para o acima), onde derivei uma compreensão básica sobre como ler flamegraphs. Especialmente poderoso para aqueles que estão executando Python em IRIS em produções com código de usuário e procurando otimização.
Em frente, espero que isso desperte seu interesse, agora vamos passar para o mundo dos aplicativos eBPF, onde os profissionais reuniram soluções fenomenais para colocar o eBPF a trabalhar em frotas de sistemas de forma segura e leve.