LabHub

CCA — 실리움 인증 어소시에이트 · Hubble 관측성 · 이론

플로우는 어디에 얼마나 남아 있나

LabHub 에서 이어서 보기

한 줄 요약

Hubble 은 eBPF 데이터패스가 만든 이벤트를 노드 로컬 링버퍼에 담고, relay 가 그것을 클러스터 단위로 합칩니다. 링버퍼는 회전하므로 장기 분석에는 export 가 필수입니다.

왜 이게 필요했나

정책을 강제하기 시작하면 질문이 쏟아집니다. "방금 결제 API 가 왜 끊겼지?", "이 드롭은 정책 때문인가 라우팅 때문인가?" 데이터패스가 커널 안으로 들어간 만큼 관측 수단도 같은 깊이에서 나와야 합니다.

기존 방식은 사이드카 프록시를 붙여 요청을 관측했습니다. 파드마다 프록시가 하나씩 붙으니 리소스가 두 배로 들고, 파드 스펙을 바꿔야 하니 재시작이 필요합니다. Hubble 은 이미 데이터패스에 붙어 있는 eBPF 프로그램이 만든 이벤트를 그대로 읽으므로 추가 프록시도 파드 변경도 없습니다.

어떻게 동작하나

구조는 세 층입니다.

[eBPF 데이터패스] --perf 링버퍼--> [cilium-agent 안의 Hubble 서버]                                      gRPC :4244                                          |                                   [hubble-relay] :4245                                          |                            +-------------+-------------+                            v                           v                      [hubble CLI]                [hubble-ui]

여기서 운영상 중요한 성질 세 가지가 나옵니다.

첫째, 플로우는 노드 로컬 메모리에만 잠시 존재합니다. 기본 버퍼는 노드당 4095 플로우이고, 확장해도 흔히 쓰는 값이 16383 입니다. 플로우 하나가 약 500바이트를 차지하므로 16383 이면 노드당 대략 8MiB 수준입니다. 트래픽이 많은 노드에서는 몇 초 만에 회전할 수 있으므로 감사 증적과 사후 분석에는 반드시 파일 export 를 붙여야 합니다.

둘째, relay 는 집계자일 뿐 저장소가 아닙니다. relay 가 죽어도 데이터패스와 노드 로컬 관측은 아무 영향을 받지 않습니다. 포트는 relay 가 4245, 노드의 Hubble 서버가 4244, 메트릭 엔드포인트가 9965 입니다.

셋째, 페이로드는 저장하지 않습니다. 플로우는 소스·목적지 아이덴티티와 라벨, 판정(verdict), 드롭 사유, HTTP/DNS 메타데이터를 담은 구조화 이벤트입니다. 패킷 내용이 필요하면 다른 도구를 써야 합니다.

판정 값을 읽는 법이 실전의 핵심입니다.

| verdict | 의미 |
| --- | --- |
| FORWARDED | 허용되어 전달됨 |
| DROPPED | 차단됨 (드롭 사유가 함께 붙음) |
| AUDIT | 감사 모드였고, 강제 상태였다면 차단됐을 트래픽 |
| ERROR | 처리 중 오류 |

드롭 사유별 첫 의심 지점도 정리해 두면 시간을 아낍니다. POLICY_DENIED 는 정책 미허용이니 아이덴티티와 포트를 다시 보고, CT_MAP_INSERT_FAILED 는 conntrack 맵이 가득 찬 것이니 맵 크기를 조정하고, UNSUPPORTED_L3_PROTOCOL 은 비IP 트래픽이며, STALE_OR_UNROUTABLE_IP 는 ipcache 불일치이므로 노드 간 동기화를 점검합니다.

마지막으로 반드시 구분해야 할 것. L7 거부는 L4 드롭과 로그 모양이 다릅니다. L4 에서 막히면 연결이 성립하지 않아 요청 한 줄로 끝나지만, L7 규칙 위반은 이미 확립된 연결 위에서 프록시가 403 을 만들어 돌려주므로 요청은 DROPPED, 응답은 FORWARDED 로 찍힙니다. 이 비대칭을 알면 로그 두 줄만 보고도 어느 계층의 문제인지 판정할 수 있습니다.

현장에서 만나는 모습

저자가 홈랩에 Hubble 을 올릴 때 hubble-relay 와 hubble-ui 가 Pending 에서 움직이지 않았습니다. 이벤트는 이랬습니다.

Warning  FailedScheduling  0/1 nodes are available: 1 node(s) had untolerated taint(s).

원인은 스케줄링이었습니다. 컨트롤 플레인 노드에는 node-role.kubernetes.io/control-plane:NoSchedule taint 가 걸려 있는데, hubble-relay 와 hubble-ui 는 DaemonSet 이 아니라 Deployment 라 toleration 이 없었습니다. CoreDNS 는 기본적으로 control-plane toleration 을 갖고 있어 정상 기동했던 것과 대비됩니다. 워커가 조인하자 바로 해소됐고, 이것은 오류가 아니라 정상 동작이었습니다.

여기서 얻을 감각이 있습니다. Cilium Agent 와 Hubble 서버는 노드마다 있어야 하므로 DaemonSet이고, relay 와 UI 는 클러스터에 하나면 되므로 Deployment 입니다. 배포 형태가 다르면 스케줄링 제약도 다릅니다. "에이전트는 다 떴는데 hubble CLI 만 붙지 않는다"면 relay 파드 상태부터 보는 것이 순서입니다.

같은 클러스터에서 L7 정책을 걸고 얻은 로그는 앞 모듈에서 본 그대로입니다. GET 요청은 FORWARDED, POST 요청은 DROPPED, 그리고 그 POST 에 대한 403 응답은 FORWARDED. 로그 세 줄이 정책이 의도대로 동작했다는 증거였습니다.

다음 실습에서 할 것

Hubble 활성화 값과 메트릭·export 설정을 작성하고, 실제 워크로드에 라벨을 붙여 아이덴티티에 들어가는 라벨과 제외되는 라벨을 컨피그맵으로 정리하고, 자주 쓰는 플로우 필터 질의와 드롭 사유 진단표, 그리고 드롭 급증 알림 규칙까지 만듭니다.