eBPF와 NetFlow로 보는 네트워크 트래픽 모니터링: 베어메탈에서 쿠버네티스까지
eBPF/XDP와 NetFlow 기반 시스템은 물리 서버부터 쿠버네티스 클러스터까지 모든 계층에서 세밀한 네트워크 텔레메트리 데이터를 제공합니다. 전통적인 sFlow/NetFlow의 한계인 높은 하드웨어 부담, 샘플링, 사용자 정의 필드 부재 문제를 극복합니다. 트래픽은 유일한 '라우터 온 어 스틱' 인터페이스를 통해 처리되며, 커널 수정 없이도 XDP가 수신 패킷을 캡처할 수 있습니다.
eBPF는 운영체제 커널 내에서 안전하고 낮은 지연으로 프로그램을 실행할 수 있어 실시간 모니터링에 최적입니다. 5튜플(소스/대상 IP, 포트, 프로토콜), 바이트, 패킷 수 등 통계 정보를 수집해 NetFlow 형식으로 수집기로 내보냅니다.
고성능을 위한 BPF 맵 선택
BPF 맵은 키-값 형태의 통계 저장소로, 키는 5튜플, 값은 카운터입니다. 테스트 결과 BPF_MAP_TYPE_HASH는 다음과 같은 문제를 겪었습니다:
- 다중 코어에서의 멀티스레드 접근 시 락 경합 발생.
- 경쟁 조건으로 인한 정확하지 않은 카운터 값.
원자적 연산(__sync_fetch_and_add)은 오류를 제거하지만, 동기화 오버헤드로 성능이 저하됩니다.
BPF_MAP_TYPE_PERCPU_HASH로 전환하면 각 CPU 코어마다 별도의 맵을 생성해 락을 완전히 제거합니다. 집계는 사용자 공간에서 수행됩니다. 100코어 환경에서 다양한 부하를 적용한 벤치마크 결과, PERCPU 맵이 다른 타입보다 우수함이 입증되었습니다.
600K개의 5튜플(60K 엔트리 맵 기준)이 꽉 찬 상태에서는 BPF_MAP_TYPE_LRU_PERCPU_HASH가 오래된 항목을 자동으로 제거하지만, 비용이 따릅니다. 단순한 한 번 읽기 작업에는 표준 PERCPU_HASH가 여전히 선호됩니다.
// 어디에 쓸지 결정
#define SHARD_COUNT 25 // 슬롯 수
map_hash_idx = ctx->rx_queue_index % SHARD_COUNT + shard_offset;
맵 분할과 멀티스레드 내보내기
1000만 개의 레코드를 저장하는 단일 맵은 단일 스레드 내보내기로 인해 성능 저하를 겪었습니다. rx_queue_index를 기반으로 RSS 기반으로 25개의 맵으로 분할함으로써 병렬 읽기가 가능해져 처리 속도가 3배 가량 향상되었습니다.
분할의 장점:
- 확장성: 재시작 없이 맵 추가 가능.
- 병렬 처리: 센서가 여러 맵을 동시에 읽음.
- 캐시 효율: 작은 맵은 L1/L2 캐시에 적합.
Go 기반 센서(실제로 Cilium 라이브러리를 사용)는 매 분마다 BPF_MAP_LOOKUP_AND_DELETE_BATCH를 활용해 맵을 읽고 삭제하며, 오버플로우 시 데이터 손실을 최소화합니다.
샘플링과 동적 로드 적응
패킷 전달 성능과 텔레메트리 요구 사이의 균형을 위해 샘플링 기능을 도입했습니다. 보조 stats_map(BPF_MAP_TYPE_HASH, max_entries=128)은 각 슬롯별 패킷 수를 추적합니다:
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 128); // 최대 슬롯 수
__type(key, __u32); // 슬롯 ID
__type(value, __u64); // 패킷/바이트 카운터
__uint(pinning, LIBBPF_PIN_BY_NAME);
} stats_map SEC(".maps");
eBPF 타이머는 주기적으로 대역폭(패킷/초)을 계산하고, 각 슬롯별 임계치를 초과하면 샘플링을 트리거합니다. 타이머는 패킷 처리 컨텍스트 외부에서 백그라운드 작업을 수행해 데이터를 집계하고 카운터를 리셋합니다.
이 방식은 DDoS와 같은 트래픽 폭주 상황에서도 안정성을 유지하면서도 세션 수준의 텔레메트리 정보를 유지합니다.
가상화 및 쿠버네티스 환경에의 적응
베어메탈 아키텍처는 가상화 환경과 쿠버네티스 클러스터로 자연스럽게 확장됩니다. 쿠버네티스에서는 eBPF/XDP가 DaemonSet 형태로 실행되어 CNI를 통해 파드 트래픽을 캡처합니다. 분할 전략은 노드 애피니티에 맞춰 조정되며, PERCPU_HASH는 vCPU와 잘 일치합니다.
NetFlow 내보내기는 네임스페이스, 파드 IP 등의 메타데이터를 집계해 마이크로서비스 관찰성을 강화합니다.
핵심 요약:
- PERCPU_HASH는 락 경합을 제거해 HASH 대비 2~3배 성능 향상.
- 분할은 병렬 처리로 내보내기 속도를 3배 가속화.
- eBPF 타이머 + 샘플링은 전달 성능 희생 없이 부하를 적절히 조절.
- LRU 변종은 오버플로우가 자주 발생하는 동적 환경에 적합.
- Cilium 라이브러리를 활용한 Go 센서는 고처리량 파싱에서 뛰어난 성능.
— Editorial Team
아직 댓글이 없습니다.