eBPF 기반 관측 완벽 가이드 — Cilium·Pixie·Parca로 커널 레벨 가시성 확보
이 글의 핵심
eBPF는 리눅스 커널에 안전한 샌드박스 프로그램을 주입해 네트워크·시스템콜·함수 호출을 재컴파일 없이 관측·제어하는 기술입니다. 이 글은 eBPF의 핵심 개념과 Cilium(CNI·서비스 메시·보안), Pixie(무-계측 관측), Parca(지속 프로파일링), Hubble(네트워크 가시성)을 실전 중심으로 정리하고 프로덕션 도입 체크리스트를 제공합니다.
이 글의 핵심
eBPF(extended Berkeley Packet Filter)는 “커널을 건드리지 않고 커널 안에서 안전한 코드를 실행”하는 리눅스 기술입니다. 네트워크 패킷 후킹에서 출발해 지금은 관측성·보안·네트워킹·트레이싱의 기반 기술로 확장되었고, 2026년 현재 클라우드 네이티브 인프라에서 없어서는 안 될 핵심입니다.
주요 활용:
- Cilium — eBPF 기반 CNI, 서비스 메시, 네트워크 정책, 로드밸런서 (CNCF Graduated)
- Hubble — Cilium의 네트워크 플로우 가시성 UI/CLI
- Pixie — 무-계측 자동 관측 플랫폼 (CNCF Incubating)
- Parca — 지속 프로파일링(Continuous Profiling) (CNCF Sandbox)
- Falco — eBPF 기반 런타임 보안 (CNCF Graduated)
- bpftrace / bcc — 운영자가 직접 쓰는 트레이싱 DSL
이 글은 eBPF의 개념을 최소한으로 정리한 뒤 위 도구들을 실제로 쓰는 방법과 프로덕션 고려사항을 다룹니다.
eBPF 30초 요약
사용자 공간 커널 공간
───────────── ─────────────
eBPF 프로그램 (C/Rust) ┌──────────────────┐
│ │ Verifier │
▼ │ (안전성 검증) │
컴파일 → BPF 바이트코드 ──► │ JIT → 네이티브 │
│ │
│ kprobe/tracepoint│
│ XDP/tc/socket │
│ perf_event │
│ │ │
│ BPF Map ◄───────┼──► 사용자 공간이 읽기
└────────────────────┘
- 프로그램 종류: XDP(초저지연 패킷), tc(트래픽 제어), kprobe/kretprobe(커널 함수), uprobe(유저 함수), tracepoint, perf_event, LSM(보안)
- Map: 커널 ↔ 사용자 공간 공유 자료구조 (hash, array, ring buffer, lru, percpu 등)
- CO-RE: BTF 메타데이터를 써서 “한 번 빌드한 바이너리를 여러 커널 버전에서” 사용 가능
- Verifier: 무한 루프·허용되지 않은 포인터 접근 차단 → 커널 panic 방지
Cilium: 네트워킹·보안·서비스 메시를 하나로
왜 Cilium인가
기존 쿠버네티스 네트워킹은 iptables 기반이어서 Pod가 많아지면 선형 탐색 비용이 커집니다. Cilium은 eBPF로 정책·로드밸런싱·NAT를 구현해 O(1) 수준으로 처리합니다.
제공 기능:
- CNI: Pod 네트워킹, IPAM
- NetworkPolicy + L7: HTTP path/method, gRPC, Kafka 레벨 정책
- kube-proxy 대체: eBPF로 Service/LB 구현, iptables 제거 가능
- Service Mesh: sidecar 없이 L7 라우팅·재시도·서킷브레이커
- Mutual TLS: SPIFFE/SPIRE 기반 또는 WireGuard 전송 암호화
- Hubble: 실시간 플로우 + UI
- Tetragon: 런타임 보안 (Cilium 팀이 스핀오프한 프로젝트)
설치 (EKS 예시)
CLUSTER_NAME=prod-eks
helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium --version 1.16.0 \
--namespace kube-system \
--set eni.enabled=true \
--set ipam.mode=eni \
--set routingMode=native \
--set endpointRoutes.enabled=true \
--set kubeProxyReplacement=true \
--set k8sServiceHost=<EKS API 엔드포인트> \
--set k8sServicePort=443 \
--set hubble.relay.enabled=true \
--set hubble.ui.enabled=true \
--set hubble.metrics.enabled="{dns,drop,tcp,flow,port-distribution,icmp,http}"
kube-proxy 제거 시 트래픽 지연 개선 효과가 크고, Hubble로 “어떤 Pod가 어디로 연결을 맺는지” 실시간 관찰 가능합니다.
L7 네트워크 정책 예시
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: payment-api
namespace: prod
spec:
endpointSelector:
matchLabels: {app: payment}
ingress:
- fromEndpoints:
- matchLabels: {app: order}
toPorts:
- ports:
- {port: "8080", protocol: TCP}
rules:
http:
- method: "POST"
path: "/api/v1/charge"
- method: "GET"
path: "/api/v1/status"
Order 서비스가 /charge(POST)와 /status(GET)만 Payment에 호출 가능하고 그 외는 차단됩니다. 기존 iptables 기반 NetworkPolicy로는 불가능한 L7 세밀함입니다.
Hubble로 네트워크 플로우 관찰
cilium hubble port-forward &
hubble observe --follow --pod prod/order-7d8c9f
실시간 스트림:
order-7d8c9f -> payment-3f2a1b:8080 (HTTP/1.1 POST /api/v1/charge) -> 200 OK in 12ms
order-7d8c9f -> db-0:5432 (TCP) forwarded
order-7d8c9f -> api.stripe.com:443 (TLS) forwarded
“계측 없이 모든 Pod 트래픽이 기록되는” 것이 eBPF의 위력입니다.
Pixie: 무-계측 자동 관측
어떤 문제를 푸는가
OpenTelemetry·Datadog 등은 코드에 SDK를 넣고 계측해야 합니다. Pixie는 eBPF uprobe + kprobe로 프로세스의 소켓 시스템콜을 후킹해 HTTP·gRPC·MySQL·Postgres·Redis·DNS 트래픽을 자동 캡처합니다.
설치
# CNCF 기반 Kubernetes에 DaemonSet으로 배포
bash -c "$(curl -fsSL https://withpixie.ai/install.sh)"
px deploy
설치 후 바로 모든 Pod의 요청이 보입니다. SDK 변경·재배포 없음.
PxL 쿼리 언어
import px
df = px.DataFrame('http_events', start_time='-5m')
df = df[df.ctx['namespace'] == 'prod']
df.latency_ms = df.latency / 1e6
px.display(df[['req_path', 'resp_status', 'latency_ms']])
Pandas 유사 DSL로 초대용량 스트림을 초 단위로 쿼리합니다. 내부적으로 Vizier라는 in-cluster 스토리지가 최근 수 시간 데이터를 로컬에서 처리합니다(데이터 유출 없음).
대표 사용 사례
- 새 배포 후 에러율 급증 →
Services뷰로 원인 Pod 즉시 파악 - 느린 요청 →
HTTP Data뷰에서 path별 p99 레이턴시 - DB 쿼리 튜닝 →
mysql_events/pgsql_events로 slow query 실시간 관찰 - DNS 문제 →
dns_events로 실패한 도메인 확인
SDK 대비 장점: 비프로덕션 한정이 아닌 프로덕션에 바로 켜놓을 수 있습니다. 오버헤드는 노드당 CPU 1-3%, 메모리 300-500MB 수준.
Parca: 지속 프로파일링
지속 프로파일링이란
기존 프로파일러(perf, pprof)는 “문제 발생 시 수동으로” 뜁니다. 지속 프로파일링은 항상 저부하(1% CPU 미만) 샘플링해 장기 플레임그래프를 쌓습니다.
Google·Netflix 등 대규모 조직에서는 이미 표준 관행이고, Parca·Pyroscope(Grafana)·Polar Signals가 오픈소스 구현입니다.
Parca Agent 배포
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: parca-agent
namespace: parca
spec:
selector:
matchLabels: {app: parca-agent}
template:
metadata:
labels: {app: parca-agent}
spec:
hostPID: true
containers:
- name: agent
image: ghcr.io/parca-dev/parca-agent:latest
args:
- --node=$(NODE_NAME)
- --remote-store-address=parca-server.parca:7070
- --remote-store-insecure
securityContext:
privileged: true
env:
- name: NODE_NAME
valueFrom: {fieldRef: {fieldPath: spec.nodeName}}
노드에 DaemonSet으로 떠서 모든 프로세스의 CPU·메모리 프로파일을 eBPF perf_event로 샘플링합니다. 애플리케이션 수정·재빌드 없음.
활용
Parca UI에서 서비스별 플레임그래프를 시각화:
- CPU 리그레션: 배포 전후 플레임그래프 diff로 새로 생긴 핫패스 발견
- 메모리 누수: Allocations 프로파일로 누수 함수 추적
- 언어별 심벌: Go/Rust/C/C++/Python/Node.js 모두 지원
Falco / Tetragon: 런타임 보안
eBPF는 보안 관측에도 쓰입니다.
- Falco: 시스템콜 기반 룰 엔진.
fd.name등의 조건으로 “컨테이너에서 /etc/shadow를 읽는 시도” 등을 실시간 탐지 - Tetragon: Cilium 팀의 KRSI/LSM 기반 탐지 + 실시간 차단(kill) 기능
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: block-curl-in-web
spec:
podSelector:
matchLabels: {app: web}
kprobes:
- call: "sys_execve"
syscall: true
args:
- index: 0
type: "string"
selectors:
- matchArgs:
- index: 0
operator: "Postfix"
values: ["/curl", "/wget"]
matchActions:
- action: Sigkill
웹 Pod에서 curl이 실행되면 커널에서 즉시 SIGKILL — 유저 공간 도달 전 차단. 전통적 도구로는 불가능한 수준의 응답성입니다.
직접 쓰는 eBPF: bpftrace
프로덕션 디버깅에서 “어떤 커널 함수가 얼마나 느린지” 즉석에서 측정하고 싶을 때:
# open(2) 시스템콜 호출자 집계
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_openat {
@[comm] = count();
}'
# 디스크 I/O 레이턴시 히스토그램
sudo bpftrace -e 'tracepoint:block:block_rq_issue { @start[args->sector] = nsecs; }
tracepoint:block:block_rq_complete { @latency = hist(nsecs - @start[args->sector]); delete(@start[args->sector]); }'
bpftrace는 운영자의 SSH 세션에서 바로 쓰는 트레이싱 DSL입니다. BCC tools 저장소에 100+ 즉시 사용 가능한 스크립트가 있습니다.
성능·안전성 고려
오버헤드
- eBPF 프로그램 자체는 JIT 컴파일되어 네이티브 속도
- Map 크기가 작으면 오버헤드가 미미. 큰 히스토그램/링버퍼 사용 시 노드당 0.5-5% CPU 가능
- XDP는 NIC 레벨 처리라 수백만 pps를 거의 공짜로 처리
보안
- 루트 권한이 필요하지만
CAP_BPF + CAP_PERFMON으로 최소화 가능 - 프로덕션에서는 신뢰된 컴포넌트만 eBPF 허용 (Cilium/Pixie/Parca/Falco처럼 검증된 프로젝트)
- AppArmor·SELinux와 충돌 가능 — 배포 전 충돌 확인
커널 버전
- Cilium 1.16+: 커널 5.4+ (일부 기능 5.10+)
- Pixie: 4.14+ 권장
- Parca Agent: 4.19+
- 프로덕션에는 6.x LTS(6.6, 6.12) 권장
프로덕션 도입 로드맵
- Cilium CNI부터: EKS/GKE/AKS에 공식 지원. 기존 CNI에서 마이그레이션도 지원
- Hubble UI 활성화: 네트워크 가시성 단번에 확보
- Pixie로 관측 보강: 기존 APM과 병행, 디버깅 전용으로 시작
- Parca로 프로파일링 상시화: CPU 리그레션 탐지에 탁월
- Falco 또는 Tetragon 보안: SOC/SIEM과 연동
- bpftrace 교육: 운영팀이 즉석 디버깅 도구로 익숙해지기
트러블슈팅
libbpf: kernel doesn't support BTF
커널에 CONFIG_DEBUG_INFO_BTF=y가 필요. 커널 5.8+ 주요 디스트로는 기본 활성화.
Cilium Pod가 init-container에서 실패
mount가 제한된 환경(세컨더리 네임스페이스). SecurityContext 조정 필요. 공식 Helm 차트의 --set securityContext.privileged=true 확인.
Pixie 데이터 누락
Vizier가 메모리 부족으로 샘플링 스킵 중. px.display 시 start_time 창을 줄이거나 Vizier 리소스 증설.
Parca 플레임그래프가 비어 있음
심벌 서버 미설정 또는 stripped 바이너리. Go는 기본 심벌 포함, Rust/C++는 -g 빌드 + debug symbol 서버 연결.
체크리스트
- 프로덕션 커널 5.10+ (가능하면 6.x LTS)
-
CONFIG_BPF,CONFIG_DEBUG_INFO_BTF활성 - Cilium CNI + Hubble로 네트워크 가시성 확보
- 네트워크 정책은 L7까지 Cilium으로 작성
- Pixie로 무-계측 관측 항상 켜두기
- Parca로 지속 프로파일링 수집
- Falco/Tetragon으로 런타임 보안 탐지
- 운영팀이 bpftrace·bcc tools 기본기 보유
- eBPF 컴포넌트 업그레이드 주기·커널 호환성 모니터링
마무리
eBPF는 더 이상 “커널 해커의 도구”가 아닙니다. Cilium·Pixie·Parca·Falco 덕분에 한 번의 DaemonSet 배포로 네트워크·관측·보안·프로파일링 전 영역에 커널 레벨 가시성이 열립니다. 기존 iptables·sidecar·APM 스택과 비교하면 오버헤드는 낮고 가시성은 훨씬 깊습니다. 2026년 현재 대규모 쿠버네티스를 운영한다면 eBPF 생태계는 선택이 아닌 필수입니다. Cilium CNI부터 시작해 Hubble·Pixie·Parca를 순차 도입하면 6개월 안에 인프라 관측 수준을 한 단계 끌어올릴 수 있습니다.
관련 글
- Kubernetes 완벽 가이드
- Linux 성능 튜닝 가이드
- Prometheus & Grafana 완벽 가이드
- Kubernetes NetworkPolicy 가이드