Artigo
· Out. 2, 2024 15min de leitura

eBPF: Rastreando eventos de Kernel para IRIS Workloads

 

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.

Passos eBee com eBPF e fluxos de trabalho InterSystems IRIS


 

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!

Immediatamente Aplicável

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
    

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"

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.

 

"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 .. # build python3 binding
pushd ../src/python/
make
sudo make install
popd
cd bcc
make install

Primeiro assegure que o kernel objetivo tem as coisas necessárias...

cat /boot/config-$(uname -r) | grep 'CONFIG_BPF'
CONFIG_BPF=y

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

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.

# Example eBPF program to a Linux kernel tracepoint
# Modified to trap irisdb
# requires bpfcc-tools
# To run: sudo python3 irismadeadir.py
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()
        #print(task.decode("utf-8"))
        if "iris" in task.decode("utf-8"):
            printb(b"%s-%-6d %s" % (task, pid, msg))
    except ValueError:
        continue
    except KeyboardInterrupt:
        break

 

3️⃣ Carregue no Kernel, Rode

Crie um diretório em IRIS 

Inspecione o rastreio!

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

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

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) ]

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

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.

  1. "A função na parte inferior é a função on-CPU. Quanto mais alto no eixo y, mais profundamente aninhada está a função.
  2. 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.
  3. 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.

Discussão (0)1
Entre ou crie uma conta para continuar