eBPF는 운영체제 커널에서 발생하는 네트워크, 프로세스, 파일, 스케줄링 신호를 비교적 낮은 침투도로 수집할 수 있게 만들었습니다. 그래서 “애플리케이션에 SDK를 넣지 않아도 tracing이 된다"는 문장이 자주 나옵니다. 출발점으로는 맞지만 운영 결론으로 쓰기에는 부족합니다. 커널이 볼 수 있는 연결과 syscall은 강력한 증거이지만, 주문 번호가 왜 실패했는지, 어떤 business operation이 고객에게 영향을 주었는지, 특정 retry가 의도된 것인지는 애플리케이션 문맥 없이는 알기 어렵습니다.
지금 eBPF 관측성의 관심은 새 agent를 설치하는 문제에서, 플랫폼이 어떤 운영 데이터를 기본 제공하고 앱 팀은 어떤 의미를 추가하며 그 데이터의 비용·권한·보존을 누가 책임지는가로 이동하고 있습니다. 이 글은 eBPF production debugging 플레이북, OpenTelemetry instrumentation ecosystem, OpenTelemetry blueprint의 거버넌스를 연결해, 과장 없이 도입 결정을 내리는 기준을 정리합니다.
이 글에서 얻는 것
- eBPF가 잘 보는 신호와 애플리케이션 계측이 반드시 남겨야 하는 의미를 구분합니다.
- 커널 event를 무제한 수집하지 않고 sampling, cardinality, 보존 기간을 설계하는 기준을 배웁니다.
- Kubernetes node agent 도입 시 kernel·runtime 호환성, CPU·메모리 예산, 개인정보 경계를 검증할 수 있습니다.
- 한 팀의 데모를 공용 플랫폼으로 확장하기 전 필요한 pilot·rollout·rollback 기준을 세울 수 있습니다.
핵심 개념/이슈
1) 자동 계측의 범위와 business 문맥의 범위는 다르다
eBPF는 소켓 연결, DNS 질의, TCP 재전송, syscall 지연, 프로세스 수명처럼 공통 인프라 신호에 강합니다. 언어별 라이브러리를 고치기 어려운 legacy workload나 sidecar가 많은 환경에서는 특히 빠른 coverage를 제공합니다. 반면 HTTP route template, tenant, 주문 상태, feature flag variant, 결제 결과 같은 business 속성은 암호화 경계와 애플리케이션 의미 때문에 추론만으로 안전하게 만들기 어렵습니다.
| 질문 | eBPF가 주는 강점 | 앱 계측 또는 별도 데이터가 필요한 이유 |
|---|---|---|
| 어느 서비스가 누구에게 연결했는가 | process·socket·DNS로 의존성 그래프를 빠르게 생성 | logical service name과 배포 버전은 별도 정규화 필요 |
| 어디서 지연됐는가 | connect, retransmit, scheduler wait의 하부 원인 단서 | 고객 과업·route·retry intent는 코드 문맥 필요 |
| 어떤 요청이 실패했는가 | protocol error, reset, timeout 경향 확인 | authorization denial과 business validation 실패를 구분해야 함 |
| 무엇이 유출 위험인가 | node 단위에서 넓은 관찰 가능 | request body·query·command line의 수집 금지 정책 필요 |
원칙은 “eBPF로 자동 coverage를 확보하고, 앱 계측으로 의미를 보강한다"입니다. eBPF가 trace ID나 protocol metadata를 얻더라도 SDK span을 모두 제거하기 전에 오류 분류, 배포 버전, 사용자 영향 분석이 유지되는지 검증해야 합니다. 결제·인증·권한 경로에서는 business event가 없는 네트워크 trace만으로 정상과 위험을 판정하지 마세요.
2) coverage는 수집량이 아니라 비교 가능한 데이터 품질이다
node마다 수백만 event를 수집하면 대시보드는 풍부해 보일 수 있습니다. 그러나 service name이 pod name으로 쪼개지고 ephemeral port가 label로 들어가며 retry가 매 request마다 새 span으로 보이면 비용만 증가하고 인시던트 판단은 더 어려워집니다. 관측성 품질은 얼마나 많이 받았는가가 아니라 release 전후와 서비스 간 같은 질문을 비교할 수 있는가로 평가해야 합니다.
처음부터 다음 최소 공통 차원을 합의하는 편이 좋습니다.
service.name, service.namespace, deployment.environment,
service.version, k8s.cluster.name, peer.service,
network.protocol.name, error.type, trace_id(있을 때만)
pod.uid, 전체 URL query, client IP, 동적 user ID, process command line을 기본 metric label로 넣는 선택은 피해야 합니다. trace나 log에 제한적으로 보관할 필요가 있어도 접근 권한과 TTL을 분리해야 합니다. metric cardinality budget과 metric overflow·data completeness의 원칙처럼, event를 얻기 쉬워질수록 label 정책은 더 엄격해야 합니다.
3) node agent는 application library보다 넓은 신뢰 경계를 가진다
애플리케이션 SDK는 한 서비스 process 안에서만 실행되는 경우가 많지만 eBPF agent는 node의 여러 workload와 kernel event에 접근할 수 있습니다. 따라서 배포 권한, privileged capability, host mount, collector egress를 엄격히 검토해야 합니다. telemetry에는 connection metadata, DNS name, process argument, 인증 header 조각이 섞일 수 있으므로 “read-only"라는 설명만으로 위험이 사라지지 않습니다.
node kernel event → eBPF program → node agent buffer → collector → storage/query
↓ ↓ ↓
kernel/runtime sampling·filter tenant·retention·RBAC
각 화살표마다 누가 configuration을 바꾸는지, raw event가 어디까지 갈 수 있는지, collector 장애가 앱 traffic에 영향을 주는지 정해야 합니다. buffer가 가득 차면 observability event를 drop하고 drop rate를 관찰하는 편이 일반적으로 안전합니다. 다만 security audit처럼 유실 자체가 사건인 데이터는 best-effort telemetry와 같은 pipeline에 섞지 말고 별도 보존·전송 계약을 둬야 합니다.
실무 적용
1) 한 가지 운영 질문으로 pilot을 제한한다
“전체 tracing을 자동화한다"는 pilot 목표는 검증할 수 없습니다. 대신 서비스 맵에서 알 수 없던 egress dependency를 찾기, legacy service의 TCP reset과 p99 지연 상관관계 확인, node별 DNS 실패와 application timeout 비교 중 하나를 고르세요. 서로 다른 traffic profile의 2~3개 서비스와 1개 node pool에서 정상 피크를 포함한 최소 7일을 관찰하는 방식이 적절합니다.
rollout 전에는 node CPU, agent memory, network egress, collector queue lag, 기존 APM trace completeness를 기준선으로 기록합니다. 예를 들어 agent 추가 후 node CPU가 기준선보다 1%p 이상 지속 상승하거나 collector drop rate가 0.5%를 넘으면 feature를 늘리기 전에 filter와 sampling을 조정합니다. 이 수치는 환경마다 바꾸되, 예산과 중단 기준을 사전에 적는 원칙은 지켜야 합니다.
pilot 성공도 “새 그래프가 생겼다"가 아닙니다. 실제 사건 조사에서 기존보다 빠르게 upstream 또는 network 원인을 좁혔는지, dependency inventory의 미등록 endpoint가 몇 건 발견됐는지, 앱 팀이 새 service identity를 신뢰하는지를 함께 확인하세요.
2) sampling은 비용 절감 기능이면서 데이터 계약이다
모든 event를 같은 비율로 sample하면 드문 오류와 저빈도 고객 흐름이 사라질 수 있습니다. 시작 정책은 성공 event는 낮은 비율, 오류·reset·timeout은 높은 비율 또는 전량, 새 배포 version은 일시적으로 상향하는 식으로 구성할 수 있습니다. 그러나 sampling decision과 rate를 event에 남기지 않으면 성공률과 latency percentile을 재계산할 때 편향을 해석할 수 없습니다.
| 신호 종류 | 시작 수집 정책 예시 | 조정 조건 | 주의점 |
|---|---|---|---|
| connection/service graph | 집계 우선, raw flow 1~10% sample | 새 dependency 또는 route 변경 | IP·ephemeral port를 metric label로 승격하지 않음 |
| error/reset/timeout | 100% 또는 높은 tail sample | burst 시 rate cap·queue 관찰 | business error와 혼동하지 않음 |
| latency profile | histogram·exemplar 중심 | p99 drift 시 trace sample 상향 | sample rate와 population을 저장 |
| process/syscall debug | incident 기간·승인 node만 | 종료 시 자동 해제 | command line·file path의 민감정보 점검 |
service별 event drop, cardinality rejection, sampling rate, collector queue lag를 platform SLO의 일부로 대시보드에 올리세요. 데이터 파이프라인이 정상이어야 애플리케이션 SLO도 해석할 수 있습니다.
3) rollout은 kernel 호환성과 rollback을 포함한 변경 관리다
eBPF 프로그램은 kernel version, container runtime, CNI, security policy의 영향을 받습니다. attach가 실패했다고 agent를 privileged mode로 넓히는 식의 즉흥 대응은 위험합니다. 지원 matrix를 먼저 정하고 build·signing provenance, verifier failure, agent version, node OS/kernel version을 telemetry로 남기세요.
권장 순서는 compatibility check → disabled install → limited capture → canary node pool → fleet rollout입니다. disabled install에서는 event export 없이 config·RBAC·kernel verifier 문제를 먼저 찾습니다. canary는 node pool의 5% 이내에서 시작하고 다음 조건 중 하나라도 충족되면 이전 config로 되돌립니다.
- node CPU 또는 memory pressure가 합의한 예산 이상으로 지속 증가한다.
- application p99 또는 connection error가 canary 집단에서 대조군보다 악화한다.
- collector drop, attach failure, unknown service identity가 기준선보다 증가한다.
- 수집 금지 속성 또는 tenant 간 접근 오류가 한 건이라도 확인된다.
기술적인 rollback은 daemonset version을 되돌리는 것으로 끝나지 않습니다. sampling rule, collector route, storage retention, dashboard query도 같이 되돌릴 수 있어야 합니다. 배포 drain과 rollback처럼 변경 단위와 관찰 창을 정하고, agent 제거 후 의존하던 alert가 허위 정상으로 바뀌지 않는지 확인하세요.
트레이드오프/주의점
첫째, eBPF는 “코드 변경 없음"을 약속할 수 있어도 “운영 의미 없음"을 약속하지는 않습니다. business transaction, feature flag, 사용자 권한 문맥을 포기하면 오히려 MTTR이 늘 수 있습니다. SDK를 전부 대체할지보다 자동 계측의 빈틈과 명시적 span·event가 필요한 위치를 service catalog에 적는 편이 현실적입니다.
둘째, 모든 node에서 high-cardinality flow를 장기간 보관하면 비용과 프라이버시가 함께 커집니다. debug 신호는 incident 기간에만 켜고 default는 집계와 제한된 exemplar로 두세요. raw flow를 30일 보관해야 한다는 요구가 나오면 실제 조사 사례와 접근 역할을 확인한 뒤 24시간 또는 7일 tier로 시작하는 편이 안전합니다.
마지막으로 kernel-level visibility는 security tool과 관측성 tool의 경계를 흐릴 수 있습니다. 성능 진단을 위해 수집한 process·network 정보가 인사 평가나 사용자 행위 감시에 쓰이지 않도록 목적 제한, 접근 로그, export 승인 정책을 분리해야 합니다. agent CVE, kernel patch, CNI upgrade, vendor lock-in도 application dependency처럼 관리해야 합니다.
체크리스트 또는 연습
플랫폼 도입 체크리스트
- eBPF로 답할 운영 질문 하나와 앱 계측이 계속 제공할 business 문맥을 분리했다.
- pilot 대상 2~3개 서비스와 1개 node pool의 CPU, memory, egress, queue lag, 기존 trace 품질 기준선을 기록했다.
- service identity, environment, version, peer service 공통 차원을 정하고 pod UID·raw URL·user ID를 기본 metric label에서 제외했다.
- node agent의 권한, host 접근, collector egress, raw event 보존 위치, RBAC와 audit log를 검토했다.
- sampling rate, drop reason, cardinality rejection을 event와 platform dashboard에서 해석할 수 있다.
- kernel/runtime/CNI 지원 matrix와 canary attach failure의 rollback 절차를 문서화했다.
- CPU·p99·drop·privacy violation 중단 기준을 합의하고 config·collector·dashboard를 함께 되돌릴 수 있다.
연습: DNS timeout 조사용 pilot 설계하기
특정 서비스에서 간헐적인 timeout이 보고되지만 application trace에는 downstream 이름이 비어 있다고 가정해 봅시다. eBPF pilot으로 DNS query 실패, connect latency, TCP retransmit 중 무엇을 수집할지 먼저 고르세요. 그 다음 앱 팀이 남길 route template·tenant tier·retry attempt와 결합해 어떤 경우를 같은 사건으로 볼지 정의합니다. 마지막으로 raw DNS name의 보존 기간, sample rate, 7일 pilot의 CPU와 drop 중단 기준을 적어 보세요. 답이 “모두 수집"이라면 아직 플랫폼 계약이 아닙니다. 필요한 신호와 불필요한 데이터를 함께 줄이는 것이 운영 가능한 관측성의 시작입니다.
💬 댓글