Pesquisar

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
Pergunta
· Out. 2, 2024

Possible contamination of full lock table between ECP application servers or via remote databases ?

If several application servers are connected using ECP, and one of them create many locks, so many that lock table became full :

Should we expect only that application server to be impacted ? (usually, when lock table is full the system became instable). Or, are other application servers going to be impacted the same way ? (because that lock table is synchronized and maintained in sync across all servers)

I have another question (which is related) : is this the same with remote databases ?
Let's say 2 application servers access the same remote database and one application server create many locks. Is the other application server going to be impacted as well ?

3 Comments
Discussão (3)1
Entre ou crie uma conta para continuar
Pergunta
· Out. 2, 2024

Python.net Install

This is for IRIS For Health 2024.2.0

We are migrating away from the .NET Gateway and trying to use the python integration instead.

I followed the instructions to install IRIS

Then I installed python following the IRIS documentation indicating that python should be installed globally.

I set up the PythonRuntimeLibrary and PythonRuntimeLibraryVersion options under System->Configuration->Advanced memory settings and when I run the shell function, I get python:

USER>do ##class(%SYS.Python).Shell()
 
Python 3.12.6 (tags/v3.12.6:a4a2d2b, Sep  6 2024, 20:11:23) [MSC v.1940 64 bit (AMD64)] on win32
Type quit() or Ctrl-D to exit this shell

To reach out to our C# DLL, I ran the following command to install python.net

pip install pythonnet, it reported downloading items succuessfully.

To test, I have a simple python script that is just "import clr" and when I run this from the cmd prompt, it does not error out. I did make a demo DLL with a namespace, class, and one function. If I reference that DLL, it calls the function and prints hello world. So, it appears to me that python.net is working.

 

But when I create a new class and have 'import clr" in the classmethod with Language = python, I am getting this error:

USER>d ##class(User.Test).Check()
 
D ##CLASS(User.Test).Check()
^
<THROW> *%Exception.PythonException <PYTHON EXCEPTION> 246 <class 'RuntimeError'>: Failed to initialize Python.Runtime.dll

 

From my reading, I'm pretty sure its a path issue of some kind because I don't have the right environment variables set up.

I tried adding in all of these lines into the classmethod before I call import clr, and none of them have helped.

os.environ["PYTHONPATH"] = r"C:\Program Files\Python312\Lib\site-packages"

os.environ["PYTHONNET_PYDLL"] = r"C:\Program Files\Python312\python312.dll"

 

Has anyone else gotten python.net to work with IRIS?

Discussão (0)1
Entre ou crie uma conta para continuar
Pergunta
· Out. 2, 2024

BP/External SQL Calls are creating IRIS.WorkQueue but is not purging the global

I have been trying to track down an issue we are seeing in our TEST environment with Memory usage.

We have Several BP's for years now that take a HL7 message, parse it apart, and make calls to a Custom EnsLib.SQL.OutboundAdapter to have it execute Insert/Select/Update/Delete stored procedures against a MS SQL Database via JDBC connection. We are using Microsoft's JDBC 12.2 driver to do this.

What we are seeing is that IRIS.WorkQueue globals are being defined for these calls but then the IRIS.WorkQueue is not being cleaned up and taking up large amounts of Memory.

I have tried ensuring the context variables are set to "" when we are done with them in the BP, and that the parameter array in the Custom BO is killed once the stored procedure is executed and we have a result.

Why would this not clean up on its own once the HL7 message has been processed (completed) through the BP? Any way to tell why IRIS.Workqueue globals are being created?

5 Comments
Discussão (5)2
Entre ou crie uma conta para continuar
Anúncio
· Out. 2, 2024

开发者社区回顾, 九月 2024

您好,欢迎阅读 九月 2024 开发人员社区通讯。
统计信息
✓ 九月发布了 45 篇新帖子:
 39篇新文章
 4个新公告
 2个新问题
✓ 九月有 47 位新成员加入
✓ 所有时间发布了 2,208 篇帖子
✓ 所有时间有 2,024 位成员加入
最高职位
本月最佳作家
文章
#InterSystems IRIS
 
#InterSystems IRIS for Health
第十二章 WS-Policy 配置类详细信息 - 配置类基础知识
按姚 鑫
第十三章 WS-Policy 配置类详细信息 - 添加扩展属性
按姚 鑫
第十四章 WS-Policy 配置类详细信息 - 配置 XData 块的详细信息(一)
按姚 鑫
第十五章 WS-Policy 配置类详细信息 - 配置 XData 块的详细信息(二)
按姚 鑫
第十六章 WS-Policy 配置类详细信息 - 自定义配置示例
按姚 鑫
第十八章 添加时间戳和用户名令牌
按姚 鑫
第十九章 添加时间戳和用户名令牌 - 时间戳和用户名令牌示例
按姚 鑫
第二十章 加密 SOAP 主体
按姚 鑫
第十七章 手动添加安全元素
按姚 鑫
第二十一章 加密 SOAP 主体 - 变体:使用可识别证书的信息
按姚 鑫
第二十二章 加密 SOAP 主体 - 变体:使用签名的 SAML 断言
按姚 鑫
第二十三章 加密安全标头元素
按姚 鑫
第二十四章 加密安全标头元素 - 基本示例
按姚 鑫
第二十五章 添加数字签名
按姚 鑫
第二十六章 添加数字签名 - 示例
按姚 鑫
第二十七章 添加数字签名 - 变体:使用签名的 SAML 断言
按姚 鑫
第二十八章 添加数字签名 - 指定摘要方法
按姚 鑫
第三十章 使用派生密钥令牌进行加密和签名
按姚 鑫
基于向量搜索的患者相似度匹配示例程序
按Nicky Zhu
第三十一章 使用派生密钥令牌进行加密和签名 - 变体:创建隐式 DerivedKeyToken
按姚 鑫
第三十二章 使用派生密钥令牌进行加密和签名 - 使用 DerivedKeyToken 进行加密
按姚 鑫
第三十三章 使用派生密钥令牌进行加密和签名 - 使用 DerivedKeyToken _进行加密(一)
按姚 鑫
第三十四章 使用派生密钥令牌进行加密和签名 - 使用 DerivedKeyToken 进行签名
按姚 鑫
第三十五章 结合加密和签名
按姚 鑫
第三十六章 结合加密和签名 - 使用对称密钥签名并加密
按姚 鑫
 
#Caché
 
公告
问题
#InterSystems IRIS
活动量
按wei su
 
#Caché
 
九月, 2024Month at a GlanceInterSystems Developer Community
Discussão (0)0
Entre ou crie uma conta para continuar