eBPF는 Linux Kernel 내부에서 동작하는 강력한 기술이지만, 과거에는 커널 버전마다 구조체(Layout)가 달라질 수 있기 때문에 eBPF 프로그램을 다시 컴파일해야 하는 문제가 있었습니다.
예를 들어 Ubuntu 22.04에서 만든 eBPF 프로그램이 Rocky Linux 9나 Debian 12에서는 정상적으로 동작하지 않는 경우가 발생했습니다. 커널 내부 구조체의 위치와 크기가 달라질 수 있기 때문입니다.
이 문제를 해결하기 위해 등장한 기술이 CO-RE(Compile Once – Run Everywhere) 입니다.
CO-RE는 한 번 컴파일한 eBPF 프로그램을 다양한 Linux Kernel 버전에서 다시 컴파일하지 않고 실행할 수 있도록 해주는 기술입니다.
이번 글에서는 CO-RE의 개념과 동작 원리, BTF와의 관계, 장점, 개발 방법, 그리고 실무 활용 사례를 자세히 알아보겠습니다.
Linux CO-RE란?
CO-RE는 커널 구조체의 차이를 실행 시점(Runtime)에 자동으로 보정하는 eBPF 기술입니다.
기본 구조는 다음과 같습니다.
eBPF Source
↓
한 번 컴파일
↓
ELF Object
↓
Linux Kernel
↓
BTF 정보 확인
↓
자동 구조체 보정
↓
정상 실행
즉, 프로그램은 한 번만 컴파일하고, 실행 시 현재 커널 환경에 맞게 자동으로 조정됩니다.
CO-RE가 필요한 이유
기존 방식에서는 다음과 같은 문제가 있었습니다.
- Ubuntu마다 커널 구조체 차이
- CentOS와 Debian의 구조체 차이
- Kernel 업데이트마다 재컴파일 필요
- 운영 서버마다 다른 바이너리 관리
예를 들어 서버가 100대라면 커널 버전에 따라 여러 개의 eBPF 바이너리를 관리해야 하는 경우도 있었습니다.
CO-RE를 사용하면 하나의 바이너리만 배포하면 됩니다.
기존 eBPF와 CO-RE 비교
기존 방식
Kernel A
↓
Compile
↓
Program A
Kernel B
↓
Compile
↓
Program B
CO-RE 방식
Program
↓
Kernel A
자동 적용
Program
↓
Kernel B
자동 적용
커널별 별도 컴파일이 필요하지 않습니다.
CO-RE의 동작 원리
CO-RE는 BTF 정보를 이용하여 구조체를 분석합니다.
eBPF Object
↓
BTF 정보 읽기
↓
Field Offset 계산
↓
자동 Relocation
↓
실행
이를 BTF Relocation이라고 합니다.
BTF(BPF Type Format)란?
CO-RE에서 가장 중요한 요소가 BTF입니다.
BTF는 Kernel 내부 구조체 정보를 저장한 메타데이터입니다.
예를 들어
struct task_struct
의
- 멤버 위치
- 자료형
- 크기
- Offset
등이 모두 BTF에 저장됩니다.
CO-RE는 이를 이용하여 구조체 접근을 자동 수정합니다.
Relocation이란?
Relocation은 구조체 멤버 위치를 실행 시점에 다시 계산하는 과정입니다.
예를 들어
Kernel A
task_struct
pid
comm
Kernel B
task_struct
flags
pid
comm
처럼 구조체가 변경되어도 CO-RE가 자동으로 Offset을 수정합니다.
CO-RE 개발 도구
대표적인 개발 도구는 다음과 같습니다.
| 도구 | 설명 |
|---|---|
| libbpf | CO-RE 공식 라이브러리 |
| clang | eBPF 컴파일 |
| bpftool | BTF 생성 |
| pahole | BTF 생성 지원 |
| llvm | 컴파일러 |
최근 eBPF 프로젝트는 대부분 libbpf 기반으로 개발됩니다.
BTF 확인
현재 Kernel의 BTF 확인
ls /sys/kernel/btf
대표 파일
ls /sys/kernel/btf/vmlinux
존재한다면 CO-RE를 사용할 수 있는 환경일 가능성이 높습니다.
bpftool로 BTF 확인
sudo bpftool btf show
또는
sudo bpftool btf dump file /sys/kernel/btf/vmlinux
Kernel 구조체 정보를 확인할 수 있습니다.
CO-RE 컴파일
대표적인 컴파일 예시
clang -target bpf \
-g \
-O2 \
-c xdp_prog.c \
-o xdp_prog.o
libbpf가 CO-RE Relocation 정보를 함께 생성합니다.
CO-RE에서 사용하는 매크로
대표적으로 사용하는 매크로는
BPF_CORE_READ()
예시
pid = BPF_CORE_READ(task, pid);
Kernel마다 Offset이 달라도 자동으로 올바른 위치를 읽습니다.
실무에서 자주 사용하는 명령어
Kernel BTF 확인
ls /sys/kernel/btf
BTF Dump
sudo bpftool btf dump file /sys/kernel/btf/vmlinux
BTF 목록
sudo bpftool btf show
Kernel 확인
uname -r
컴파일
clang -target bpf -c xdp_prog.c
Program 확인
sudo bpftool prog show
기존 방식과 CO-RE의 차이
| 항목 | 기존 eBPF | CO-RE |
|---|---|---|
| 컴파일 | 커널마다 필요 | 한 번만 |
| 유지보수 | 어려움 | 쉬움 |
| 배포 | 여러 바이너리 | 하나의 바이너리 |
| BTF 필요 | 아니오 | 예 |
| 최신 eBPF | 제한적 | 권장 방식 |
현재는 대부분의 신규 eBPF 프로젝트가 CO-RE 방식을 채택하고 있습니다.
실무 사례
예를 들어 SaaS 서비스를 운영하는 기업에서 Ubuntu, Rocky Linux, Debian 서버를 동시에 운영한다고 가정해 보겠습니다.
과거에는 운영체제와 커널 버전별로 각각 다른 eBPF 프로그램을 빌드해야 했습니다.
하지만 CO-RE를 사용하면 다음과 같은 흐름이 가능합니다.
- libbpf 기반으로 eBPF 프로그램 작성
- 한 번만 컴파일
- 모든 서버에 동일한 바이너리 배포
- 실행 시 각 서버의 BTF 정보를 읽어 자동으로 구조체 보정
- 별도 수정 없이 동일한 프로그램 실행
이 방식은 유지보수 비용을 크게 줄이고 배포 자동화에도 매우 유리합니다.
자주 묻는 질문
CO-RE는 모든 Linux Kernel에서 사용할 수 있나요?
아닙니다. 일반적으로 BTF를 지원하는 비교적 최신 Linux Kernel에서 사용할 수 있습니다. 오래된 커널에서는 BTF가 제공되지 않아 CO-RE 기능을 사용할 수 없는 경우가 있습니다.
CO-RE와 libbpf는 어떤 관계인가요?
libbpf는 CO-RE 기능을 구현하고 활용하기 위한 공식 라이브러리입니다. 대부분의 CO-RE 기반 eBPF 프로그램은 libbpf를 사용하여 개발됩니다.
CO-RE를 사용하면 커널 버전을 완전히 신경 쓰지 않아도 되나요?
대부분의 구조체 변경은 CO-RE가 자동으로 처리하지만, 특정 Helper 함수의 지원 여부나 새로운 커널 기능 사용 여부는 여전히 커널 버전에 영향을 받을 수 있습니다.
마무리
Linux CO-RE는 eBPF 프로그램을 한 번만 컴파일하여 다양한 Linux Kernel에서 실행할 수 있도록 해주는 핵심 기술입니다. BTF와 Relocation을 활용하여 구조체 차이를 자동으로 보정하므로, 운영 환경의 복잡성을 크게 줄이고 유지보수와 배포를 단순화할 수 있습니다. 최신 eBPF 개발에서는 CO-RE와 libbpf가 사실상 표준으로 자리 잡고 있으므로 반드시 이해해야 할 중요한 기술입니다.