Study/Linux

[Linux] eBPF의 활용 (BCC, bpftrace)

sn00py 2022. 8. 25. 00:49

1. BCC

BCC란?

BCC는 성능 분석이나 네트워크 트레픽 제어와 같은 작업에 적합한 툴으로, 커널 tracing이나 manipulation하는 프로그램을 효율적으로 작성할 수 있도록 한다. BCC의 특징으로는 데이터를 수집하는 코드는 C로 작성하고, 프론트엔드는 파이썬으로 작성하여 프로그램을 구현한다는 것이다.

BCC Tools

BCC는 코드를 작성하지 않아도 기본적으로 제공하는 tool들이 있다. 위의 그림이 bcc에서 제공하고있는 기본 tool이다. system call interface, tcp.udp, filesystem 등 많은 영역에 대해 trace할 수 있는 툴을 제공하고 있다.

 

Bcc에서 기본적으로 제공하는 툴을 활용하는것도 좋지만, 필요한 정보를 추출해주는 툴이 없거나 추가적인 정보를 더 얻고싶을때는 직접 코드를 작성하는 방법도 활용할 수 있다. BCC에서는 파이썬과 C언어 모두를 사용하는데, 기본적으로 BCC프로그램은 파이썬으로 작성한다. 파이썬 코드를 작성할 때는 BCC 라이브러리에서 BPF를 import한 후 C언어로 작성 된 데이터 수집 코드를 문자열의 형태로 BPF에 전달한다. 

 

BCC의 활용법

아래의 예시는 kporbe sys clone이라는 probe일 때 코드를 실행하도록 작성된 코드이다. 프로브는 소프트웨어나 하드웨어에서 bpf프로그램을 실행할 수 있는 이벤트를 생성하는 지점을 말한다. Kporbe sys clone은 커널 영역에서 프로세스가 클론될 때를 추적하기 때문에 클론 되는 시점의 정보를 출력한다.

  #!/usr/bin/python
  from bcc import BPF

  # define BPF program 
  prog = “””
  int kprobe__sys_clone(void *ctx) {
      bpf_trace_printk(“hello\\n”); 
      return 0; 
  } “””

  # load BPF program
  b = BPF(text=prog)
  b.trace_print()

실행 결과

 

2. bpftrace

bpftrace란?

BCC와 마찬가지로 커널 트레이스를 할 때 사용하는 툴이다. BCC가 C와 파이썬으로 작성된 코드를 ebpf 프로그램으로 변환해주는 툴킷이라면 bpftrace는 ebpf에서 커널 트레이싱을 할 수 있도록 별로도 정의된 고수준의 언어이다. bpftrace는 LLVM을 백엔드로 사용하여 BPF-bytecode로 스크립트를 컴파일하고, BCC를 활용하여 bpf시스템과 상호작용 할 수 있다.

bpftrace Tools

bpftrace는 BCC보다는 적은 수의 기본 툴을 제공하고 있다. BCC와 마찬가지로 여러 영역에 대해 trace 툴을 제공하고 있지만, 그 가지 수가 적다.  

 

bpftrace 또한 추가적으로 필요한 정보를 얻기위해 코드를 직접 작성할 수 있다. bpftrace에는 여러가지 옵션들이 존재하는데, 먼저 e 옵션이 있다. e 옵션은 실행할 프로그램을 지정할 수 있는데, 이 옵션을 통해 실행파일을 따로 만들지 않고 명령어 수준에서 한줄짜리 커멘드를 작성할 수 있다. 다음으로는 L 옵션이 있는데, Bpf프로그램을 실행할 수 있는 이벤트를 생성하는 측정 지점인 프로브를 검색할 수 있다.

 

https://github.com/iovisor/bpftrace/blob/master/docs/reference_guide.md

 

Bpftrace에서 제공되는 프로브는 다음과 같다. 유저 영역을 트레이싱할 수 있는 uprobe, 커널 영역을 트레이싱할 수 있는 kprobe 하드웨어, 소프트웨어 등 여러 프로브를 통해 추적할 수 있는 정보들이 주어진다. 스페셜 이벤트인 begin과 end는 프로그램을 실행시켰을 때 각각 시작과 끝에 수행할 동작을 정의할 수 있도록 만들어졌다.

 

bpftrace의 활용법

아래의 코드는 명령어 형식으로 한줄로 프로그램을 작성한 예시이다. 앞에서 언급했던 것 처럼 e옵션을 사용하여 명령어를 실행한 것을 확인할 수 있다. 사용된 프로브는 tracepoint system call enter nanosleep이고, 나노슬립이 실행된 지점에 중괄호 안의 코드를 실행하여 정보를 출력할 수 있게 작성한 코드이다. 

  $ sudo bpftrace -e 'tracepoint:syscalls:sys_enter_nanosleep { printf("%s is sleeping.\n", comm); }'
  Attaching 1 probe...
  iscsid is sleeping.
  irqbalance is sleeping.
  iscsid is sleeping.
  [...]

 

아래의 코드는 위에서 설명한 코드와 같은 내용을 담고있는 코드를 파일형식으로 작성한 것이다. 먼저 bt형식으로 코드를 작성하는데, 위와 동일하게 프로브를 지정해주고 해당 시점에 중괄호안의 코드를 실행할 수 있도록 한다. 작성된 코드는 bpftrace 명령어를 통해 실행한다.

  $ cat -n sleepers.bt
  tracepoint:syscalls:sys_enter_nanosleep
  {
      printf("%s is sleeping.\n", comm);
  }

  $ sudo bpftrace sleepers.bt
  Attaching 1 probe...
  iscsid is sleeping.
  iscsid is sleeping.
  [...]
 

'Study > Linux' 카테고리의 다른 글

[Linux] Extended Berkeley Packet Filter(eBPF)란?  (0) 2022.08.25