Linux eBPF Skeleton이란? libbpf Skeleton 자동 생성과 활용 방법 완벽 이해

과거에는 eBPF 프로그램을 작성한 후 커널에 로드하기 위해 수백 줄 이상의 C 코드를 직접 작성해야 했습니다. ELF 파일을 열고, Map을 생성하고, 프로그램을 로드한 뒤 Hook에 연결하는 작업을 모두 개발자가 구현해야 했기 때문입니다.

이러한 복잡함을 해결하기 위해 libbpf Skeleton이 등장했습니다.

Skeleton은 bpftool이 자동으로 생성하는 C 헤더 파일로, eBPF 프로그램을 매우 간단하게 로드하고 관리할 수 있도록 만들어 줍니다.

현재 대부분의 최신 eBPF 프로젝트(Cilium, Katran, Falco 일부 구성, libbpf-bootstrap 예제)는 Skeleton 방식을 사용합니다.

이번 글에서는 eBPF Skeleton의 개념과 동작 원리, 생성 방법, 주요 함수, 실무 활용 방법을 자세히 알아보겠습니다.

Linux eBPF Skeleton이란?

Skeleton은 eBPF Object 파일(.o)을 기반으로 bpftool이 자동 생성하는 C Header 파일입니다.

기본 구조는 다음과 같습니다.

program.bpf.c

↓

clang

↓

program.bpf.o

↓

bpftool

↓

program.skel.h

↓

Application

개발자는 Skeleton을 포함(Include)하기만 하면 복잡한 Loader 코드를 직접 작성할 필요가 없습니다.

Skeleton이 필요한 이유

기존 방식에서는 다음과 같은 작업을 직접 구현해야 했습니다.

  • ELF Object 열기
  • Map 생성
  • Program Load
  • CO-RE Relocation
  • Verifier 실행
  • Hook 연결
  • 종료 처리

Skeleton은 이러한 과정을 자동으로 처리합니다.

Skeleton 생성 과정

전체 과정은 다음과 같습니다.

eBPF Source

↓

clang

↓

Object File

↓

bpftool gen skeleton

↓

Skeleton Header

↓

Application

자동 생성된 Header에는 프로그램을 제어하는 다양한 함수가 포함됩니다.

Skeleton 생성 방법

먼저 eBPF 프로그램을 컴파일합니다.

clang \
-target bpf \
-g \
-O2 \
-c program.bpf.c \
-o program.bpf.o

그다음 Skeleton을 생성합니다.

bpftool gen skeleton program.bpf.o > program.skel.h

이제 program.skel.h 파일을 프로젝트에서 사용할 수 있습니다.

Skeleton 내부 구조

Skeleton에는 다양한 정보가 포함됩니다.

Program

Map

BSS

RODATA

DATA

Link

Object

개발자는 이 구조체를 통해 모든 eBPF 리소스를 쉽게 제어할 수 있습니다.

Skeleton 사용 방법

헤더를 포함합니다.

#include "program.skel.h"

그다음 Object를 생성합니다.

struct program_bpf *skel;

이 구조체가 전체 eBPF 프로그램을 관리합니다.

Object 열기

Skeleton은 Object를 자동으로 엽니다.

skel = program_bpf__open();

내부적으로

  • ELF 분석
  • Map 확인
  • Object 초기화

등을 수행합니다.

Program Load

Kernel에 프로그램을 로드합니다.

program_bpf__load(skel);

내부적으로

  • CO-RE
  • Verifier
  • Map 생성

등이 자동으로 수행됩니다.

Hook 연결

Program을 Hook에 연결합니다.

program_bpf__attach(skel);

예를 들어

  • Tracepoint
  • XDP
  • Kprobe

등에 자동으로 연결됩니다.

Program 종료

프로그램 종료 시

program_bpf__destroy(skel);

Map과 Link를 정리하고 메모리를 해제합니다.

Skeleton의 주요 함수

함수설명
__open()Object 열기
__load()Kernel 로드
__attach()Hook 연결
__detach()Hook 해제
__destroy()메모리 해제

이 함수들만으로 대부분의 작업을 처리할 수 있습니다.

Skeleton의 장점

Skeleton을 사용하면 다음과 같은 장점이 있습니다.

  • 코드 양 감소
  • Loader 자동화
  • CO-RE 자동 지원
  • BTF 자동 처리
  • Map 접근 단순화
  • 유지보수 용이
  • 최신 libbpf와 높은 호환성

복잡한 초기화 코드를 크게 줄일 수 있습니다.

Skeleton과 기존 방식 비교

항목기존 방식Skeleton
코드 길이길다짧다
Loader 구현직접 작성자동
CO-RE 지원직접 구현자동
유지보수어려움쉬움
권장 여부기존 방식최신 표준

현재는 Skeleton 사용이 일반적인 개발 방식입니다.

Skeleton과 bpftool의 관계

bpftool은 Skeleton 생성 도구입니다.

예를 들어

bpftool gen skeleton program.bpf.o

명령을 실행하면

program.skel.h

파일이 생성됩니다.

이 파일을 애플리케이션에서 사용하면 됩니다.

실무에서 자주 사용하는 명령어

eBPF 프로그램 컴파일

clang -target bpf \
-c program.bpf.c \
-o program.bpf.o

Skeleton 생성

bpftool gen skeleton program.bpf.o > program.skel.h

Program 확인

sudo bpftool prog show

Map 확인

sudo bpftool map show

Kernel 기능 확인

sudo bpftool feature

libbpf 버전 확인

pkg-config --modversion libbpf

실무 사례

예를 들어 Tracepoint 기반 프로세스 모니터링 프로그램을 개발한다고 가정해 보겠습니다.

예전에는 다음 작업을 모두 직접 구현해야 했습니다.

  1. ELF 파일 열기
  2. Map 생성
  3. Program Load
  4. CO-RE 적용
  5. Verifier 처리
  6. Tracepoint Attach
  7. 종료 시 Link 해제

하지만 Skeleton을 사용하면 다음과 같이 단순화됩니다.

  1. program_bpf__open()
  2. program_bpf__load()
  3. program_bpf__attach()
  4. 이벤트 수집
  5. program_bpf__destroy()

코드가 훨씬 간결해지고 유지보수도 쉬워집니다.

자주 묻는 질문

Skeleton은 반드시 사용해야 하나요?

필수는 아닙니다. 직접 libbpf API를 호출하여 Loader를 구현할 수도 있습니다. 하지만 최신 eBPF 프로젝트에서는 Skeleton 사용이 일반적으로 권장됩니다.

Skeleton은 어떤 도구가 생성하나요?

bpftool gen skeleton 명령으로 자동 생성합니다. 생성된 헤더 파일에는 프로그램 로드와 관리에 필요한 함수와 구조체가 포함됩니다.

Skeleton은 CO-RE와 함께 사용되나요?

네. Skeleton은 libbpf와 함께 CO-RE를 자연스럽게 지원합니다. 실행 시 현재 커널의 BTF 정보를 이용해 필요한 Relocation을 자동으로 수행합니다.

마무리

Linux eBPF Skeleton은 libbpf 기반 개발을 크게 단순화한 자동 생성 코드입니다. bpftool이 생성한 Skeleton Header를 사용하면 프로그램 로드, Hook 연결, Map 관리, CO-RE 처리 등을 간단한 함수 호출만으로 수행할 수 있습니다. 현재 eBPF 개발에서는 Skeleton이 사실상의 표준으로 자리 잡았으며, 생산성과 유지보수성을 크게 향상시키는 핵심 기술입니다.

댓글 남기기