안녕하세요! 최신 기술 트렌드에 관심 많은 여러분, 오늘은 Observability, 네트워킹, 보안 분야의 게임 체인저로 불리는 eBPF의 핵심 비밀에 대해 이야기해보려고 합니다.
eBPF가 커널에서 강력한 기능을 수행한다는 건 많이 들어보셨을 거예요. 그런데 문득 이런 궁금증이 생기지 않으셨나요?
"커널 깊숙한 곳에서 실행되는 eBPF 프로그램은 도대체 어떻게 우리(사용자)와 소통하는 거지?" 🤔
eBPF 프로그램이 수집한 데이터를 어떻게 우리에게 보여주는지, 혹은 우리가 어떻게 eBPF 프로그램의 동작을 제어할 수 있는지. 오늘은 바로 이 질문에 대한 해답, eBPF Map에 대해 쉽고 깊이 있게 파헤쳐 보겠습니다!

💻 넘을 수 없는 벽? 커널 공간 vs 사용자 공간
eBPF Map을 이해하려면 먼저 우리 컴퓨터의 기본 구조인 커널 공간(Kernel Space)과 사용자 공간(User Space)을 알아야 합니다.
- 👑 커널 공간 (Kernel Space)
- 운영체제의 심장부입니다.
- 하드웨어와 직접 통신하고 시스템의 모든 것을 제어하는 특권 영역이죠.
- 안정성과 보안을 위해 엄격하게 보호됩니다. eBPF 프로그램이 바로 이곳에서 실행돼요!
- 🏠 사용자 공간 (User Space)
- 우리가 흔히 사용하는 브라우저, 에디터, 서버 애플리케이션 등이 실행되는 일반 영역입니다.
- 커널의 보호를 받으며, 하드웨어에 직접 접근할 수 없습니다.
이 두 공간은 절대 서로의 메모리를 직접 참조하거나 함수를 호출할 수 없도록 설계되어 있습니다. 마치 대통령 집무실과 우리 집처럼 엄격히 분리되어 있죠. 바로 이 "벽" 때문에 특별한 통신 방법이 필요합니다.
🌉 두 공간을 잇는 비밀 통로, eBPF Map!
eBPF Map은 이 견고한 벽을 넘어 커널 공간과 사용자 공간이 데이터를 주고받을 수 있도록 만들어진 '공유 데이터 저장소' 입니다.
쉽게 비유하자면, 커널과 사용자 공간 사이에 있는 특별한 공유 게시판 📬 이라고 생각할 수 있어요.
- 커널 공간의 eBPF 프로그램은 이벤트가 발생할 때마다 이 게시판에 데이터를 쓰거나(Write) 업데이트(Update)합니다.
- 사용자 공간의 애플리케이션(Agent, 모니터링 도구 등)은 언제든지 이 게시판의 데이터를 읽어(Read)가거나, 새로운 정책을 써서(Write) eBPF 프로그램의 행동을 제어할 수 있습니다.
이 eBPF Map은 해시 테이블, 배열, LRU 캐시 등 다양한 형태로 존재하며, 목적에 맞게 선택해서 사용할 수 있습니다.
🔧 실제로는 어떻게 동작할까? (feat. Code)
백문이 불여일견! 특정 IP 주소에서 들어오는 패킷의 수를 세는 간단한 시나리오를 통해 eBPF Map이 어떻게 작동하는지 코드로 살펴보겠습니다.
1. Map 정의하기 (설계도 그리기)
먼저 커널과 사용자 공간 양쪽에서 모두 이해할 수 있도록 Map의 구조를 정의해야 합니다.
// BPF_MAP_TYPE_HASH: Key-Value 형태의 해시 테이블
// key: 32비트 IP 주소 (u32)
// value: 64비트 패킷 카운트 (u64)
// max_entries: 최대 1024개의 IP를 추적
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024);
__type(key, u32);
__type(value, u64);
} ip_packet_counts SEC(".maps");
2. eBPF 프로그램 (커널 공간 👑)
네트워크 인터페이스에 패킷이 들어올 때마다 이 프로그램이 실행됩니다.
// 가상의 eBPF 프로그램 코드
SEC("xdp")
int count_packets(struct xdp_md *ctx) {
// 패킷에서 IP 헤더 정보 추출 (생략)
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct ethhdr *eth = data;
struct iphdr *ip = data + sizeof(*eth);
// IP 주소를 Key로 사용
u32 src_ip = ip->saddr;
u64 *count;
// 1. Map에서 현재 IP에 대한 카운터 조회
count = bpf_map_lookup_elem(&ip_packet_counts, &src_ip);
if (count) {
// 2. 카운터가 존재하면 1 증가
__sync_fetch_and_add(count, 1);
} else {
// 3. 카운터가 없으면 새로 생성하고 1로 초기화
u64 init_val = 1;
bpf_map_update_elem(&ip_packet_counts, &src_ip, &init_val, BPF_ANY);
}
return XDP_PASS;
}
이 코드는 커널에서 조용히, 그리고 아주 빠르게 돌면서 ip_packet_counts 라는 Map에 데이터를 차곡차곡 쌓고 있습니다.
3. 사용자 공간 애플리케이션 (사용자 공간 🏠)
이제 우리 차례입니다. Go 언어로 작성된 애플리케이션이 주기적으로 Map의 내용을 읽어와 출력합니다.
// 가상의 Go 애플리케이션 코드
func main() {
// eBPF Map 핸들 가져오기 (생략)
ipMap := getMapByName("ip_packet_counts")
// 2초마다 Map의 내용을 출력
for range time.Tick(2 * time.Second) {
var key uint32
var value uint64
iterator := ipMap.Iterate()
fmt.Println("--- Packet Counts per IP ---")
// Map의 모든 Key-Value 쌍을 순회하며 출력
for iterator.Next(&key, &value) {
// 192.168.1.10: 1520 packets
fmt.Printf("%s: %d packets\n", intToIP(key), value)
}
fmt.Println("--------------------------")
}
}
Raw Data 예시
위 Go 프로그램이 출력하는 데이터는 다음과 같은 모습이겠죠?
--- Packet Counts per IP ---
192.168.1.10: 1520 packets
10.0.0.5: 887 packets
172.17.0.1: 4312 packets
--------------------------
이렇게 커널에서 수집된 실시간 데이터가 사용자 공간으로 안전하게 넘어와 의미 있는 정보로 재탄생하는 것입니다.
✨ 이게 왜 중요할까? 전체 맥락 짚어보기
eBPF Map의 역할은 단순히 데이터를 주고받는 것 이상입니다. 이 메커니즘이 eBPF의 활용 가능성을 폭발적으로 증가시킵니다.
- 상태 정보 공유 및 저장 (State Sharing) 💾 eBPF 프로그램은 'stateless' 하게, 즉 이벤트가 발생할 때마다 독립적으로 실행됩니다. 하지만 Map을 이용하면 이전 실행의 결과를 저장하고 다음 실행에 참고할 수 있습니다. 예를 들어, 특정 연결의 세션 정보를 저장하거나, IP별 누적 트래픽을 기록하는 등 'stateful'한 작업이 가능해집니다.
- 동적 설정 및 제어 (Dynamic Configuration) ⚙️ 사용자 공간에서 Map에 데이터를 쓰는 것도 가능합니다. 예를 들어, 차단할 IP 목록을 Map에 써두면, 커널의 eBPF 프로그램은 이 목록을 실시간으로 참조하여 악성 트래픽을 필터링할 수 있습니다. Agent를 재시작하거나 커널 코드를 건드리지 않고도 정책을 유연하게 변경할 수 있는 것이죠.
- 고성능 데이터 추출 (High-Performance Data Export) 📊 커널의 데이터를 사용자 공간으로 가져오는 기존 방식(ex. /proc 파일 시스템, system call)은 복잡하거나 성능 저하를 유발할 수 있습니다. eBPF Map은 커널과 데이터를 공유하기 위해 최적화된 방법으로, 최소한의 오버헤드로 방대한 양의 데이터를 효율적으로 추출하여 실시간 모니터링을 가능하게 합니다.
결론: eBPF의 잠재력을 깨우는 열쇠
정리하자면, eBPF Map은 커널과 사용자 공간이라는 분리된 세계를 연결하는 핵심적인 다리입니다.
이 다리 덕분에 우리는 커널의 강력한 성능과 안전성을 활용하면서도, 수집된 데이터를 사용자 친화적인 형태로 보고, 또 우리의 의도대로 커널의 동작을 제어할 수 있게 됩니다. eBPF 기반의 수많은 Observability, 보안, 네트워킹 도구들이 바로 이 eBPF Map 위에서 탄생하고 있습니다.
다음에 eBPF 기반 도구가 실시간 대시보드를 보여준다면, 보이지 않는 곳에서 eBPF Map이 열심히 일하고 있다는 사실을 떠올려 보세요! 😉
'클라우드 > Cilium' 카테고리의 다른 글
| Cilium 설치 후 가장 먼저 만나는 IP 할당 방식, 대체 정체가 뭘까? 🤔 (0) | 2025.12.05 |
|---|---|
| [Cilium]내 쿠버네티스 클러스터를 지키는 숨은 경호원, 정체는? 🕵️♂️ (0) | 2025.12.05 |
| 내 파드(Pod) IP는 대체 누가 주는 걸까? 🤔 Cilium IPAM 완전 정복! (0) | 2025.12.05 |
| 쿠버네티스 통신 문제, 더 이상 헤매지 마세요! Hubble 아키텍처 완전 정복 🚀 (0) | 2025.12.04 |
| VPN, 아직도 IPsec 쓰세요? WireGuard가 '게임 체인저'인 진짜 이유 (0) | 2025.12.04 |