Linux BPF Map이란? eBPF 프로그램이 데이터를 저장하고 공유하는 핵심 구조 이해

eBPF 프로그램은 Linux Kernel 내부에서 실행되지만 일반 프로그램처럼 전역 변수를 자유롭게 사용할 수 없습니다. 또한 커널에서 수집한 데이터를 사용자 공간(User Space)으로 전달하거나 여러 eBPF 프로그램 간에 데이터를 공유해야 하는 경우도 많습니다.

이때 사용하는 핵심 기능이 BPF Map입니다.

BPF Map은 eBPF 프로그램이 사용하는 데이터 저장소이며, Kernel과 User Space가 데이터를 안전하게 공유하는 통로 역할을 합니다.

이번 글에서는 BPF Map의 개념과 동작 원리, 다양한 Map 종류, 관리 방법, 그리고 실무 활용 사례를 자세히 알아보겠습니다.

BPF Map이란?

BPF Map은 eBPF 프로그램이 데이터를 저장하고 조회하기 위해 사용하는 Kernel 내부의 자료구조입니다.

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

User Space

↓

BPF Syscall

↓

BPF Map

↑      ↓

eBPF Program

Kernel 내부에서 생성되지만 사용자 프로그램도 접근할 수 있습니다.

BPF Map이 필요한 이유

예를 들어 eBPF 프로그램이 초당 네트워크 패킷 수를 계산한다고 가정해 보겠습니다.

패킷이 들어올 때마다 값을 저장해야 합니다.

Packet

↓

eBPF Program

↓

Counter 증가

↓

BPF Map 저장

User Space 프로그램은 BPF Map에서 현재 값을 읽어 화면에 출력합니다.

BPF Map의 특징

BPF Map은 다음과 같은 특징을 가집니다.

  • Kernel 내부 저장
  • User Space 접근 가능
  • 여러 eBPF 프로그램이 공유 가능
  • 다양한 자료구조 제공
  • 매우 높은 성능

일반적인 메모리 공유 방식보다 안전하게 설계되어 있습니다.

BPF Map 동작 과정

전체 흐름은 다음과 같습니다.

Packet

↓

eBPF Program

↓

Map Update

↓

Kernel Memory

↓

User Program Read

커널과 사용자 프로그램이 동일한 Map을 공유합니다.

BPF Map 종류

Linux는 다양한 Map 타입을 제공합니다.

Map 종류설명
HashKey-Value 저장
Array고정 크기 배열
Per-CPU HashCPU별 독립 Hash
Per-CPU ArrayCPU별 배열
QueueFIFO 구조
StackLIFO 구조
Ring Buffer이벤트 전달
LRU Hash오래된 데이터 자동 제거

사용 목적에 따라 적절한 자료구조를 선택합니다.

Hash Map

가장 많이 사용하는 형태입니다.

Key

↓

Value

예시

PID

↓

Packet Count

프로세스별 네트워크 사용량을 저장할 때 많이 사용합니다.

Array Map

고정된 인덱스를 사용하는 구조입니다.

Index

↓

Value

예시

CPU0

CPU1

CPU2

CPU3

CPU별 통계를 저장하는 데 적합합니다.

Per-CPU Map

멀티코어 환경에서는 Lock 경쟁이 발생할 수 있습니다.

Per-CPU Map은

CPU0

↓

Local Data

CPU1

↓

Local Data

각 CPU마다 독립된 저장 공간을 사용하여 성능을 높입니다.

고성능 모니터링 도구에서 자주 사용됩니다.

Ring Buffer

Ring Buffer는 Kernel에서 User Space로 이벤트를 전달하는 구조입니다.

Kernel

↓

Ring Buffer

↓

User Space

Falco나 bpftrace 같은 도구에서 이벤트 전달에 사용됩니다.

Map 생성

eBPF 프로그램에서는 다음과 같이 Map을 생성합니다.

struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 1024);
} my_map SEC(".maps");

Hash Map을 생성하는 예시입니다.

bpftool로 Map 확인

현재 생성된 Map은 다음 명령으로 확인할 수 있습니다.

sudo bpftool map show

예시

1:

type hash

name packet_count

현재 Kernel에 존재하는 Map 목록을 확인할 수 있습니다.

Map 내용 조회

특정 Map의 데이터를 확인하려면

sudo bpftool map dump id 1

예시

key:

value:

Map 내부의 Key와 Value를 확인할 수 있습니다.

Map 삭제

Map을 제거하려면 eBPF 프로그램을 언로드하거나 핀(Pin)된 Map을 삭제합니다.

핀된 Map 확인

ls /sys/fs/bpf

삭제

sudo rm /sys/fs/bpf/map_name

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

Map 목록

sudo bpftool map show

Map 내용

sudo bpftool map dump id 1

Program 확인

sudo bpftool prog show

BPF 파일 시스템 확인

mount | grep bpf

Pin된 객체 확인

ls /sys/fs/bpf

Kernel 버전

uname -r

실무 사례

예를 들어 웹 서버의 초당 요청 수(RPS)를 실시간으로 분석한다고 가정해 보겠습니다.

다음 순서로 동작합니다.

  1. eBPF 프로그램이 HTTP 요청 감지
  2. PID를 Key로 사용
  3. 요청 수를 Value로 저장
  4. Hash Map 업데이트
  5. User Space 프로그램이 Map 읽기
  6. Grafana 대시보드에 실시간 표시

이처럼 BPF Map은 커널에서 수집한 데이터를 외부 모니터링 시스템과 연결하는 핵심 역할을 수행합니다.

자주 묻는 질문

BPF Map은 일반 Hash Table과 같은 것인가요?

개념은 비슷하지만 BPF Map은 Kernel 내부에서 동작하며, eBPF 프로그램과 User Space가 안전하게 데이터를 공유할 수 있도록 설계된 특수한 자료구조입니다.

Per-CPU Map은 왜 필요한가요?

여러 CPU가 하나의 Map을 동시에 수정하면 Lock 경쟁이 발생할 수 있습니다. Per-CPU Map은 CPU마다 별도의 저장 공간을 사용하여 성능 저하를 줄입니다.

BPF Map은 영구적으로 저장되나요?

기본적으로는 eBPF 프로그램이 종료되면 함께 제거됩니다. 하지만 Pin 기능을 사용하면 /sys/fs/bpf 아래에 유지하여 여러 프로그램이 계속 사용할 수 있습니다.

마무리

BPF Map은 eBPF 프로그램이 데이터를 저장하고 공유하기 위한 핵심 자료구조입니다. Hash, Array, Per-CPU Map, Ring Buffer 등 다양한 형태를 제공하며, 커널과 사용자 공간 간의 안전하고 효율적인 데이터 교환을 가능하게 합니다. bpftool을 활용하면 Map 생성 상태와 저장된 데이터를 확인할 수 있으며, eBPF 기반 모니터링과 네트워크 분석, 보안 시스템을 이해하는 데 반드시 알아야 하는 기술입니다.

댓글 남기기