🐛

Keploy — eBPF로 트래픽을 가로채 API 테스트를 자동 생성하는 구조

eBPF가 커널에서 connect() 목적지를 몰래 바꿔치기하는 투명 프록시 패턴

Go製のCNCFプロジェクト. 17k+ 스타. 코드 수정 제로로 API 테스트를 자동 생성한다.

핵심 원리: eBPF 목적지 리다이렉트

모든 앱은 외부와 통신할 때 커널 syscall을 쓴다. connect(postgres:5432)를 호출하면 커널이 TCP 연결을 만든다. Keploy는 여기에 eBPF를 붙인다.

eBPF 프로그램이 SockOps(cgroup 부착)와 connect4/6 훅으로 아웃바운드 연결을 감시한다. 앱이 postgres:5432로 connect하려 하면, eBPF가 목적지를 127.0.0.1:proxyPort로 덮어쓴다. 원래 목적지는 redirectProxyMap 공유 맵에 저장.

앱은 postgres에 연결한 줄 안다. 실제로는 Keploy 프록시에 연결된 거다. 프록시가 원래 목적지를 조회해서 실제 postgres에 포워딩하면서, 오가는 트래픽을 전부 녹화한다.

투명 프록시의 프로토콜 파싱

프록시는 연결의 첫 바이트를 보고 프로토콜을 판별한다. HTTP, MySQL, PostgreSQL, MongoDB, Redis, Kafka, gRPC — 각각 전용 파서가 요청/응답 쌍을 캡처.

녹화 결과:

  • 인바운드 HTTP → TestCase (YAML)

  • 아웃바운드 DB/외부 API → Mock (YAML)

  • 매핑 → 어떤 Mock이 어떤 TestCase에 속하는지

재생(Test) 모드

keploy test로 실행하면 녹화된 HTTP 요청을 앱에 다시 보낸다. 앱의 DB 호출은 프록시가 Mock으로 응답. 실제 DB 없이 테스트가 돌아간다.

한계

Linux 전용 — eBPF는 커널 5.15+ 필요. macOS/Windows는 Docker 안에서만 가능.

SQLite 캡처 불가 — 네트워크 소켓을 안 쓰는 통신은 eBPF에 안 걸린다. PostgreSQL/MySQL만 지원.

통합 테스트만 — 비즈니스 로직 단위 테스트는 만들어주지 않는다.

스키마 변경에 취약 — DB 컬럼 추가/삭제하면 Mock이 깨진다. 재녹화 필요.

트래픽 의존 — 안 친 API는 테스트도 없다. 에러 케이스, 엣지 케이스는 직접 만들어야 한다.

동작 흐름

1

eBPF가 connect() syscall을 가로채서 목적지를 프록시로 리다이렉트 (앱은 모름)

2

투명 프록시가 첫 바이트로 프로토콜 판별 → 전용 파서로 요청/응답 캡처

3

인바운드(TestCase) + 아웃바운드(Mock)를 goroutine 채널로 동시 수집 → YAML 저장

4

재생 시 Mock이 DB/외부 API를 대체 — 실제 인프라 없이 오프라인 테스트

장점

  • 코드 수정 제로 — eBPF가 커널에서 동작하므로 SDK 불필요, 언어 무관
  • HTTP/gRPC/MySQL/Postgres/MongoDB/Redis/Kafka + TLS 투명 처리

단점

  • Linux 전용 (커널 5.15+). macOS/Windows는 Docker 필수
  • SQLite 등 네트워크 안 쓰는 DB는 캡처 불가. 통합 테스트만 생성 (단위 테스트 X)

사용 사례

기존 앱에 테스트가 없는 상태에서 실제 트래픽 기반 회귀 테스트를 빠르게 확보 CI/CD에서 외부 의존성 없이 통합 테스트 실행 (DB, Redis, 외부 API 전부 Mock)