이 글에서는 Cilium의 강력한 네트워크 가시성 도구인 Hubble의 고급 사용법에 대해 알아봅니다. 기본적인 명령어부터 시작해 실제 현업에서 활용할 수 있는 복잡한 필터링, 실시간 모니터링, 그리고 네트워크 이슈 디버깅까지 다양한 시나리오를 다룰 예정입니다. 특히 Hubble CLI와 Hubble UI를 통해 쿠버네티스 네트워크 트래픽을 실시간으로 분석하고 시각화하는 방법을 실습 중심으로 살펴보겠습니다.
📌 Hubble 개요 및 기본 구성 확인
Hubble은 Cilium의 네트워크 관찰성(Observability) 계층으로, eBPF를 기반으로 한 강력한 네트워크 모니터링 및 보안 가시성 도구입니다. 이를 통해 우리는 쿠버네티스 클러스터 내의 네트워크 트래픽을 세밀하게 관찰하고 분석할 수 있습니다.
✅ Hubble 아키텍처 이해하기
Hubble은 크게 세 가지 주요 컴포넌트로 구성됩니다:
- Hubble - 각 노드의 Cilium Agent에 내장된 모듈로, eBPF를 통해 네트워크 플로우 데이터를 수집합니다.
- Hubble Relay - 클러스터 내 모든 Hubble 인스턴스에서 데이터를 수집하고 집계하는 컴포넌트입니다.
- Hubble UI - 네트워크 트래픽을 시각적으로 표현하는 웹 인터페이스입니다.
▶️ 설치 확인하기:
# Hubble 컴포넌트 확인
# 이 명령어는 kube-system 네임스페이스에서 Hubble 관련 Pod를 찾습니다
kubectl get pods -n kube-system -l k8s-app=hubble
# Hubble Relay 상태 확인
# Hubble Relay는 노드별 Hubble 데이터를 집계하는 중앙 컴포넌트입니다
kubectl get pods -n kube-system -l k8s-app=hubble-relay
# Hubble UI 상태 확인
# Hubble UI는 웹 인터페이스를 제공하는 Pod입니다
kubectl get pods -n kube-system -l k8s-app=hubble-ui
✅ Hubble CLI 설정 확인
먼저 Hubble CLI가 제대로 설정되어 있는지 확인해 봅시다:
# Hubble CLI 버전 확인
# 클라이언트와 서버 버전이 표시됩니다
hubble version
# Hubble 상태 확인
# 현재 연결 상태, 플로우 데이터 수집 정보 등이 표시됩니다
hubble status
▶️ 상태 확인 결과 예시:
Healthcheck (via localhost:4245): Ok # Hubble 서비스 상태 - 정상
Current/Max Flows: 2,339/4,095 (57.12%) # 현재 저장된 플로우 수 / 최대 저장 가능 플로우 수
Flows/s: 13.75 # 초당 수집되는 플로우 수
Connected Nodes: 4/4 # 연결된 노드 수 / 전체 노드 수
📌 Hubble CLI 고급 명령어 활용
이제 Hubble CLI를 사용하여 네트워크 트래픽을 자세히 분석해 보겠습니다.
✅ 기본 흐름 관찰하기
# 기본 네트워크 흐름 관찰
# 이 명령어는 실시간으로 모든 네트워크 트래픽을 표시합니다
hubble observe
이 명령어는 실시간으로 발생하는 모든 네트워크 트래픽을 보여줍니다. 하지만 대규모 클러스터에서는 정보가 너무 많아 유용하지 않을 수 있습니다. 좀 더 정밀한 필터링이 필요합니다.
✅ 고급 필터링 적용하기
# 특정 네임스페이스 필터링
# default 네임스페이스 내의 트래픽만 표시합니다
hubble observe --namespace default
# 특정 Pod 간 통신 필터링
# app-frontend와 app-backend Pod 간의 통신만 표시합니다
hubble observe --pod app-frontend --pod app-backend
# HTTP 메소드별 필터링
# HTTP GET 요청만 표시합니다
hubble observe --protocol http --http-method GET
# 특정 DNS 쿼리 필터링
# example.com 도메인에 대한 DNS 쿼리만 표시합니다
hubble observe --protocol dns --dns-query example.com
# 특정 IP 주소에 대한 트래픽 필터링
# 10.0.0.1 IP와 관련된 트래픽만 표시합니다
hubble observe --ip 10.0.0.1
# 특정 포트로의 트래픽 필터링
# 80번 포트와 관련된 트래픽만 표시합니다
hubble observe --port 80
# 에러 트래픽만 필터링
# 차단된(DROPPED) 트래픽만 표시합니다
hubble observe --verdict DROPPED
# 여러 필터 조합하기
# app 네임스페이스의 80번 포트로 향하는, 전달된(FORWARDED) HTTP 트래픽 중
# 상태코드가 200인 요청만 표시합니다
hubble observe --namespace app --port 80 --verdict FORWARDED --protocol http --http-status 200
▶️ 필터 표현식 사용 예시:
# 복합 필터 표현식 (AND 조건)
# HTTP 트래픽이면서, 소스가 default 네임스페이스이고, 목적지가 kube-system 네임스페이스인 트래픽만 표시합니다
hubble observe -f "http && source.namespace=default && destination.namespace=kube-system"
# 복합 필터 표현식 (OR 조건)
# HTTP 상태코드가 404이거나 500인 트래픽만 표시합니다
hubble observe -f "http-status=404 || http-status=500"
✅ 출력 형식 사용자 정의하기
Hubble CLI는 다양한 출력 형식을 지원합니다:
# JSON 형식으로 출력 (자동화 및 추가 처리에 유용)
# 모든 데이터를, 프로그래밍 방식으로 처리하기 쉬운 JSON 형식으로 출력합니다
hubble observe -o json
# YAML 형식으로 출력
# 모든 데이터를 YAML 형식으로 출력합니다
hubble observe -o yaml
# 컴팩트 형식으로 출력 (기본값)
# 주요 정보만 간결하게 표시합니다
hubble observe -o compact
# 디버그 형식으로 출력 (상세 정보)
# 모든 상세 정보를 텍스트 형식으로 표시합니다
hubble observe -o debug
# 표시할 필드 지정하기
# 출력 형식을 직접 정의합니다. 여기서는 소스 네임스페이스:Pod -> 목적지 네임스페이스:Pod verdict 형식으로 표시합니다
hubble observe --output "{source.namespace}:{source.pod} -> {destination.namespace}:{destination.pod} {verdict}"
✅ 트래픽 데이터 저장 및 분석
# 트래픽 로그를 파일로 저장
# 현재 관찰된 트래픽 데이터를 JSON 형식으로 traffic_log.json 파일에 저장합니다
hubble observe -o json > traffic_log.json
# 저장된 로그 분석 (Unix 도구 활용)
# 저장된 JSON 파일에서 차단된(DROPPED) 트래픽만 필터링하여 dropped_traffic.json 파일에 저장합니다
cat traffic_log.json | jq '.[] | select(.verdict == "DROPPED")' > dropped_traffic.json
📌 실제 시나리오별 Hubble CLI 활용
이제 실제 운영 환경에서 자주 마주치는 시나리오별로 Hubble CLI 활용법을 알아보겠습니다.
✅ 시나리오 1: 네트워크 정책 디버깅
네트워크 정책을 적용했지만 의도한 대로 작동하지 않는 경우, 트래픽이 어디서 차단되고 있는지 확인할 수 있습니다.
# 먼저 테스트용 네트워크 정책을 적용합니다
cat <<EOF | kubectl apply -f -
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "test-policy" # 정책의 이름
spec:
endpointSelector: # 이 정책이 적용될 대상 Pod
matchLabels:
app: backend # app=backend 레이블이 있는 Pod에 적용
ingress: # 수신 트래픽 규칙
- fromEndpoints: # 어떤 출발지에서 오는 트래픽을 허용할지
- matchLabels:
app: frontend # app=frontend 레이블이 있는 Pod에서 오는 트래픽만 허용
toPorts: # 어떤 포트로의 트래픽을 허용할지
- ports:
- port: "8080" # 8080 포트로의 트래픽만 허용
protocol: TCP # TCP 프로토콜만 허용
EOF
# 이제 차단된 트래픽을 확인합니다
# backend Pod로 향하는 트래픽 중 차단된 것만 표시합니다
hubble observe --verdict DROPPED --pod-to backend
▶️ 결과 분석:
# 실제 출력 예시
TIMESTAMP SOURCE DESTINATION TYPE VERDICT SUMMARY
2023-03-15T10:15:32.0 default/middleware-54fd85cd-p8nxc default/backend-67fd9c765-7k2vm TCP DROPPED (1) policy denied
# -------- -------------------------- ----------------------------- ---- --------- -------------
# 발생 시간 출발지 Pod 목적지 Pod 프로토콜 판정 요약(차단 이유)
✅ 시나리오 2: HTTP 에러 트래픽 모니터링
특정 애플리케이션에서 HTTP 에러가 발생하는 경우, 해당 에러를 모니터링하고 원인을 파악할 수 있습니다.
# HTTP 5xx 에러만 필터링
# HTTP 상태 코드가 5로 시작하는(500대) 모든 요청을 표시합니다
hubble observe --protocol http --http-status 5
# HTTP 5xx 에러와 함께 헤더 정보도 확인 (디버그 모드)
# 더 상세한 정보를 포함한 디버그 모드로, HTTP 상태코드가 500대인 요청을 표시합니다
hubble observe -o debug --protocol http --http-status 5
# 특정 애플리케이션의 HTTP 에러 모니터링
# app-frontend Pod의 HTTP 상태코드가 500대인 요청만 표시합니다
hubble observe --protocol http --http-status 5 --pod app-frontend
✅ 시나리오 3: DNS 트래픽 분석
애플리케이션의 DNS 쿼리를 분석하여 외부 서비스 의존성을 파악할 수 있습니다.
# 모든 DNS 쿼리 모니터링
# 모든 DNS 프로토콜 트래픽을 표시합니다
hubble observe --protocol dns
# 특정 Pod의 DNS 쿼리 모니터링
# app-frontend Pod에서 발생하는 모든 DNS 쿼리를 표시합니다
hubble observe --protocol dns --pod app-frontend
# 특정 도메인에 대한 DNS 쿼리 모니터링
# example.com 도메인에 대한 DNS 쿼리만 표시합니다
hubble observe --protocol dns --dns-query "example.com"
# 실패한 DNS 쿼리 모니터링
# DNS 응답 코드가 NXDomain(존재하지 않는 도메인)인 쿼리만 표시합니다
hubble observe --protocol dns --dns-rcode "NXDomain"
▶️ 결과 예시:
TIMESTAMP SOURCE DESTINATION TYPE VERDICT SUMMARY
2023-03-15T11:25:00.0 default/crawler-76f5bc5857-gk8n9:34246 kube-system/coredns:53 L7 FORWARDED (1) DNS Query: api.example.com. A
# -------- -------------------------- -------------- --- ---------- ---------------------------
# 발생 시간 DNS 쿼리를 보낸 Pod와 소스 포트 DNS 서버와 포트 계층 판정 DNS 쿼리 내용과 유형(A 레코드)
✅ 시나리오 4: 특정 서비스 간 통신 패턴 분석
마이크로서비스 아키텍처에서 서비스 간 통신 패턴을 분석하여 의존성을 파악할 수 있습니다.
# 두 서비스 간 양방향 통신 확인
# app-frontend Pod로 향하는 app-backend 발 트래픽을 표시합니다
hubble observe --pod-to app-frontend --pod-from app-backend
# app-backend Pod로 향하는 app-frontend 발 트래픽을 표시합니다
hubble observe --pod-to app-backend --pod-from app-frontend
# 통신량 및 패턴 분석
# app-backend Pod로 향하는 트래픽 중 HTTP GET 요청의 개수를 계산합니다
hubble observe --pod-to app-backend --follow | grep -c "HTTP/1.1 GET"
# 지난 시간 동안의 통신 분석 (최근 100개 로그)
# app-backend Pod로 향하는 최근 100개의 트래픽 로그를 표시합니다
hubble observe --pod-to app-backend -n 100
📌 Hubble UI 고급 활용법
Hubble UI는 네트워크 트래픽을 시각적으로 표현하는 강력한 도구입니다. 이제 Hubble UI의 고급 기능을 살펴보겠습니다.
✅ Hubble UI 접속하기
# Hubble UI에 포트 포워딩 설정
# kube-system 네임스페이스의 hubble-ui 서비스의 80번 포트를 로컬 12000번 포트로 포워딩합니다
kubectl port-forward -n kube-system svc/hubble-ui 12000:80
# 이제 브라우저에서 http://localhost:12000으로 접속할 수 있습니다
✅ 서비스 맵(Service Map) 활용하기
Hubble UI의 서비스 맵은 클러스터 내 통신 관계를 시각적으로 보여줍니다.
▶️ 서비스 맵 인터페이스 주요 기능:
- 노드: 각 서비스(Deployment, StatefulSet 등)를 나타냅니다.
- 엣지(Edge): 서비스 간 통신을 나타냅니다.
- 색상: 트래픽의 상태를 나타냅니다 (녹색: 정상, 빨간색: 에러/차단됨).
- 두께: 트래픽의 양을 나타냅니다.
- 필터: 네임스페이스, 서비스 등으로 필터링할 수 있습니다.
[서비스 맵을 보여주는 다이어그램: 클러스터 내 다양한 네임스페이스와 서비스 간의 통신을 시각화하는 그래프 형태 UI]
✅ 네트워크 흐름(Flow) 분석
Hubble UI의 Flow 탭에서는 네트워크 흐름을 세부적으로 분석할 수 있습니다.
▶️ 주요 필터링 옵션:
- Namespace Filter: 특정 네임스페이스 선택
- Verdict Filter: FORWARDED, DROPPED 등 상태 선택
- HTTP Status Filter: HTTP 상태 코드 필터링
- Protocol Filter: TCP, UDP, HTTP, ICMP 등 프로토콜 선택
- IP Filter: 특정 IP 주소 필터링
[Flow 분석 화면을 보여주는 다이어그램: 다양한 필터 옵션과 상세 네트워크 흐름 정보가 표시된 UI]
✅ 실시간 모니터링 활용
Hubble UI의 실시간 모니터링 기능을 활용하여 클러스터 내 네트워크 이슈를 빠르게 감지할 수 있습니다.
▶️ 활용 시나리오:
- 롤아웃 모니터링: 새 버전 배포 시 네트워크 트래픽 변화 관찰
- 장애 감지: 갑작스러운 트래픽 패턴 변화 또는 에러 증가 감지
- 보안 모니터링: 비정상적인 통신 패턴 감지
# 간단한 테스트 애플리케이션 배포
apiVersion: apps/v1
kind: Deployment
metadata:
name: traffic-generator # 트래픽 생성기 이름
namespace: default # 배포할 네임스페이스
spec:
replicas: 1 # 단일 복제본 생성
selector:
matchLabels:
app: traffic-generator # 어떤 Pod가 이 Deployment에 속하는지 선택하는 레이블
template:
metadata:
labels:
app: traffic-generator # Pod에 부여할 레이블
spec:
containers:
- name: traffic-generator # 컨테이너 이름
image: busybox # 사용할 이미지
command: ["/bin/sh", "-c"] # 실행할 명령어
args:
- |
# 이 스크립트는 지속적인 HTTP 트래픽을 생성합니다
while true; do # 무한 루프 시작
# 여러 타겟 서비스에 요청 보내기
wget -q -O- http://app-frontend 2>/dev/null || true # app-frontend 서비스로 HTTP 요청
wget -q -O- http://app-backend 2>/dev/null || true # app-backend 서비스로 HTTP 요청
wget -q -O- http://app-database 2>/dev/null || true # app-database 서비스로 HTTP 요청
# 에러 트래픽도 일부 생성 (존재하지 않는 서비스)
wget -q -O- http://non-existent-service 2>/dev/null || true # 존재하지 않는 서비스로 요청 (에러 발생)
# 10초 대기
sleep 10 # 요청 간 10초 대기
done # 무한 루프 종료
📌 네트워크 정책 디버깅 실습
이제 실제 네트워크 정책을 적용하고 Hubble을 사용하여 디버깅하는 실습을 진행해보겠습니다.
✅ 테스트 애플리케이션 배포
먼저 세 가지 마이크로서비스로 구성된 테스트 애플리케이션을 배포합니다:
# frontend.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend # 프론트엔드 배포 이름
namespace: test-app # 네임스페이스
spec:
replicas: 2 # 2개의 복제본 생성
selector:
matchLabels:
app: frontend # 이 배포에 속하는 Pod 선택 레이블
template:
metadata:
labels:
app: frontend # Pod에 부여할 레이블
spec:
containers:
- name: nginx # 컨테이너 이름
image: nginx:latest # 사용할 이미지
ports:
- containerPort: 80 # 컨테이너가 노출하는 포트
---
apiVersion: v1
kind: Service
metadata:
name: frontend # 서비스 이름
namespace: test-app # 네임스페이스
spec:
selector:
app: frontend # 이 서비스로 트래픽을 라우팅할 Pod 선택
ports:
- port: 80 # 서비스가 노출하는 포트
targetPort: 80 # Pod의 대상 포트
# api.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api # API 배포 이름
namespace: test-app # 네임스페이스
spec:
replicas: 2 # 2개의 복제본 생성
selector:
matchLabels:
app: api # 이 배포에 속하는 Pod 선택 레이블
template:
metadata:
labels:
app: api # Pod에 부여할 레이블
spec:
containers:
- name: nginx # 컨테이너 이름
image: nginx:latest # 사용할 이미지
ports:
- containerPort: 80 # 컨테이너가 노출하는 포트
---
apiVersion: v1
kind: Service
metadata:
name: api # 서비스 이름
namespace: test-app # 네임스페이스
spec:
selector:
app: api # 이 서비스로 트래픽을 라우팅할 Pod 선택
ports:
- port: 80 # 서비스가 노출하는 포트
targetPort: 80 # Pod의 대상 포트
# database.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: database # 데이터베이스 배포 이름
namespace: test-app # 네임스페이스
spec:
replicas: 1 # 단일 복제본 생성 (일반적인 데이터베이스 구성)
selector:
matchLabels:
app: database # 이 배포에 속하는 Pod 선택 레이블
template:
metadata:
labels:
app: database # Pod에 부여할 레이블
spec:
containers:
- name: redis # 컨테이너 이름
image: redis:latest # Redis 이미지 사용
ports:
- containerPort: 6379 # Redis 기본 포트
---
apiVersion: v1
kind: Service
metadata:
name: database # 서비스 이름
namespace: test-app # 네임스페이스
spec:
selector:
app: database # 이 서비스로 트래픽을 라우팅할 Pod 선택
ports:
- port: 6379 # 서비스가 노출하는 포트
targetPort: 6379 # Pod의 대상 포트 (Redis 기본 포트)
# 네임스페이스 및 애플리케이션 생성
# 먼저 test-app 네임스페이스를 생성합니다
kubectl create namespace test-app
# 그 다음 세 가지 서비스를 배포합니다
kubectl apply -f frontend.yaml -f api.yaml -f database.yaml
✅ 네트워크 정책 적용
이제 다음과 같은 네트워크 정책을 적용합니다:
# network-policy.yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "secure-app" # 정책 이름
namespace: test-app # 네임스페이스
spec:
description: "Restrict communication between microservices" # 정책 설명
endpointSelector: # 이 정책이 적용될 대상 Pod
matchLabels:
app: database # database 레이블이 있는 Pod에 적용
ingress: # 수신 트래픽 규칙
- fromEndpoints: # 어떤 출발지에서 오는 트래픽을 허용할지
- matchLabels:
app: api # api 레이블이 있는 Pod에서 오는 트래픽만 허용
toPorts: # 어떤 포트로의 트래픽을 허용할지
- ports:
- port: "6379" # Redis 기본 포트로의 트래픽만 허용
protocol: TCP # TCP 프로토콜만 허용
---
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "api-access" # 정책 이름
namespace: test-app # 네임스페이스
spec:
description: "Allow frontend to access API" # 정책 설명
endpointSelector: # 이 정책이 적용될 대상 Pod
matchLabels:
app: api # api 레이블이 있는 Pod에 적용
ingress: # 수신 트래픽 규칙
- fromEndpoints: # 어떤 출발지에서 오는 트래픽을 허용할지
- matchLabels:
app: frontend # frontend 레이블이 있는 Pod에서 오는 트래픽만 허용
toPorts: # 어떤 포트로의 트래픽을 허용할지
- ports:
- port: "80" # HTTP 포트로의 트래픽만 허용
protocol: TCP # TCP 프로토콜만 허용
# 네트워크 정책 적용
# 위에서 정의한 네트워크 정책을 클러스터에 적용합니다
kubectl apply -f network-policy.yaml
📌 네트워크 정책 디버깅 실습
✅ Hubble을 활용한 정책 디버깅
# 네임스페이스 내 모든 통신 관찰
# test-app 네임스페이스의 모든 네트워크 트래픽을 관찰합니다
hubble observe --namespace test-app
# 허용된 트래픽 확인
# test-app 네임스페이스에서 허용된(FORWARDED) 트래픽만 표시합니다
hubble observe --namespace test-app --verdict FORWARDED
# 차단된 트래픽 확인
# test-app 네임스페이스에서 차단된(DROPPED) 트래픽만 표시합니다
hubble observe --namespace test-app --verdict DROPPED
# frontend -> api 통신 확인
# frontend Pod에서 api Pod로 향하는 트래픽을 표시합니다 (허용되어야 함)
hubble observe --namespace test-app --pod-from frontend --pod-to api
# api -> database 통신 확인
# api Pod에서 database Pod로 향하는 트래픽을 표시합니다 (허용되어야 함)
hubble observe --namespace test-app --pod-from api --pod-to database
# frontend -> database 통신 확인 (차단되어야 함)
# frontend Pod에서 database Pod로 향하는 트래픽을 표시합니다 (정책에 의해 차단되어야 함)
hubble observe --namespace test-app --pod-from frontend --pod-to database
▶️ 예상 결과:
- frontend -> api: FORWARDED
- api -> database: FORWARDED
- frontend -> database: DROPPED (정책에 의해 차단됨)
✅ 정책 문제 해결
만약 정책이 예상대로 작동하지 않는다면:
# 정책 상태 확인
# test-app 네임스페이스의 모든 CiliumNetworkPolicy 리소스 상태를 확인합니다
kubectl get cnp -n test-app
# 정책 세부 정보 확인
# secure-app 정책의 상세 정보를 확인합니다 (상태, 적용 대상 등)
kubectl describe cnp -n test-app secure-app
# api-access 정책의 상세 정보를 확인합니다
kubectl describe cnp -n test-app api-access
# Cilium 에이전트 로그 확인
# Cilium 에이전트 Pod의 로그를 확인하여 정책 적용 관련 오류나 경고를 찾습니다
kubectl logs -n kube-system -l k8s-app=cilium
# Cilium 엔드포인트 상태 확인
# test-app 네임스페이스의 Cilium 엔드포인트 상태를 확인합니다
# 이 명령은 각 Pod가 어떤 정책의 영향을 받는지 보여줍니다
cilium endpoint list -n test-app
📌 고급 분석 기법: 트래픽 패턴 인사이트
Hubble에서 수집한 데이터를 바탕으로 더 깊은 인사이트를 도출하는 방법을 알아보겠습니다.
✅ 트래픽 통계 추출하기
# 서비스별 트래픽 통계 (기본 100개 로그 분석)
# 최근 100개 로그를 JSON 형식으로 추출하여, 목적지별로 그룹화하고 카운트하여 정렬합니다
# 이 명령어는 어떤 서비스가 가장 많은 트래픽을 받는지 보여줍니다
hubble observe -n 100 -o json | jq 'group_by(.destination.namespace + "/" + .destination.podName) | map({service: .[0].destination.namespace + "/" + .[0].destination.podName, count: length}) | sort_by(.count) | reverse'
# 시간별 트래픽 추이 확인
# 최근 1000개 로그의 시간 정보를 추출하여, 시간별로 그룹화하고 카운트합니다
# 이 명령어는 시간별 트래픽 볼륨 추이를 보여줍니다
hubble observe -n 1000 -o json | jq '.[] | .time' | cut -d'T' -f2 | cut -d'.' -f1 | sort | uniq -c
✅ Shell 스크립트를 활용한 고급 분석
다음은 Hubble 데이터를 활용한 간단한 분석 스크립트입니다:
#!/bin/bash
# traffic_analysis.sh - Hubble 트래픽 분석 스크립트
# 네임스페이스 인자 확인 (인자가 없으면 default 사용)
NAMESPACE=${1:-default}
echo "Analyzing traffic in namespace: $NAMESPACE"
# 최근 500개 트래픽 로그 수집
echo "Collecting traffic logs..."
# 지정된 네임스페이스의 최근 500개 트래픽 로그를 JSON 형식으로 저장
hubble observe --namespace $NAMESPACE -n 500 -o json > traffic.json
# 1. HTTP 상태 코드별 분포
echo -e "\n=== HTTP Status Code Distribution ==="
# HTTP 상태 코드별로 카운트하여 내림차순 정렬 (200, 404, 500 등의 분포 확인)
cat traffic.json | jq -r '.[] | select(.l7?.http?.code) | .l7.http.code' | sort | uniq -c | sort -nr
# 2. 가장 많은 요청을 받는 Pod
echo -e "\n=== Top 5 Requested Pods ==="
# 목적지 Pod별로 카운트하여 상위 5개 추출 (가장 트래픽이 많은 Pod 확인)
cat traffic.json | jq -r '.destination.podName' | sort | uniq -c | sort -nr | head -5
# 3. 드롭된 트래픽 분석
echo -e "\n=== Dropped Traffic Analysis ==="
# 드롭된 트래픽만 추출하여 출발지->목적지(드롭 이유) 형식으로 정리
cat traffic.json | jq -r 'select(.verdict == "DROPPED") | .source.podName + " -> " + .destination.podName + " (" + .dropReason + ")"' | sort | uniq -c
# 4. 프로토콜별 트래픽 분포
echo -e "\n=== Protocol Distribution ==="
# L7 프로토콜(HTTP, DNS 등) 또는 L3/L4 분류하여 분포 확인
cat traffic.json | jq -r '.l7.type // "L3/L4"' | sort | uniq -c
# 5. 에러 요청 분석
echo -e "\n=== HTTP Error Requests ==="
# HTTP 상태 코드가 400 이상인 에러 요청만 추출하여 출발지->목적지[상태코드] URL 형식으로 정리
cat traffic.json | jq -r 'select(.l7?.http?.code and (.l7.http.code >= 400)) | .source.podName + " -> " + .destination.podName + " [" + .l7.http.code + "] " + .l7.http.url' | sort | uniq -c
# 정리
rm traffic.json
echo -e "\nAnalysis complete!"
▶️ 스크립트 실행 예시:
chmod +x traffic_analysis.sh # 스크립트에 실행 권한 부여
./traffic_analysis.sh test-app # test-app 네임스페이스에 대해 분석 실행
✅ 정기적인 모니터링 자동화
다음은 매 시간마다 실행되어 네트워크 상태를 모니터링하는 크론잡 예시입니다:
# network-monitor-cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: network-monitor # 크론잡 이름
namespace: monitoring # 모니터링 네임스페이스에 배포
spec:
schedule: "0 * * * *" # cron 표현식: 매시 정각에 실행
jobTemplate:
spec:
template:
spec:
serviceAccountName: hubble-monitor # 적절한 권한을 가진 서비스 계정
containers:
- name: hubble-monitor
image: cilium/hubble:latest # Hubble CLI가 포함된 이미지
command:
- /bin/sh
- -c
- |
# 모든 드롭된 트래픽 기록
# 차단된 모든 트래픽을 JSON 형식으로 저장 (파일명에 타임스탬프 포함)
hubble observe --verdict DROPPED -o json > /tmp/dropped_$(date +%Y%m%d%H%M).json
# HTTP 에러 기록
# HTTP 상태 코드가 5xx인 요청을 JSON 형식으로 저장
hubble observe --protocol http --http-status 5 -o json > /tmp/http_errors_$(date +%Y%m%d%H%M).json
# 결과를 Slack 또는 다른 알림 시스템으로 전송
# (여기에 알림 로직 추가)
echo "Monitoring completed!"
restartPolicy: OnFailure # 작업 실패 시 재시작 정책
📌 실무 보안 모니터링 시나리오
Hubble을 사용한 실질적인 보안 모니터링 시나리오를 살펴보겠습니다.
✅ 비정상 패턴 감지하기
# 1. 짧은 시간 내 많은 연결 시도 감지 (DDoS 의심)
# 동일한 IP에서 100회 이상 연결을 시도한 경우 추출 (DDoS 공격 의심)
hubble observe -o json | jq 'group_by(.source.ip) | map({ip: .[0].source.ip, count: length}) | select(.count > 100)'
# 2. 비정상적인 포트 스캔 감지
# DROPPED 결과 중 같은 출발지->목적지 쌍에서 5개 이상의 서로 다른 TCP 포트로 접근한 경우 탐지 (포트 스캔 의심)
hubble observe --verdict DROPPED -o json | jq 'select(.l4.TCP) | group_by(.source.podName + .destination.podName) | map({source: .[0].source.podName, dest: .[0].destination.podName, ports: map(.l4.TCP.destinationPort) | unique | length}) | select(.ports > 5)'
# 3. 중요 서비스로의 비인가 접근 시도 감지
# database Pod로 향하는 모든 차단된 트래픽 확인 (비인가 접근 시도)
hubble observe --verdict DROPPED --pod-to database -o json
✅ 인프라 서비스 트래픽 분석
클러스터 내 기본 서비스 간 통신을 모니터링하여 이상 징후를 감지할 수 있습니다:
# 코어 DNS 트래픽 분석
# CoreDNS 서비스로 향하는 모든 DNS 프로토콜 트래픽 확인
# 비정상적인 DNS 쿼리 패턴 감지에 유용
hubble observe --pod-to coredns --protocol dns
# 쿠버네티스 API 서버 트래픽 분석
# API 서버로 향하는 모든 트래픽을 관찰하여 비인가 접근 시도 감지
hubble observe --pod-to kube-apiserver
# 외부 CIDR로의 트래픽 분석
# 내부 네트워크(10.x.x.x)가 아닌 외부 IP로 향하는 모든 트래픽 탐지
# 데이터 유출이나 허용되지 않은 외부 통신 감지에 유용
hubble observe -o json | jq 'select(.destination.ip | test("^10\\.") | not)'
✅ 보안 사고 대응 워크플로우
보안 이슈 발생 시 Hubble을 사용한 대응 워크플로우:
- 이상 징후 감지: Hubble UI 또는 자동화된 모니터링에서 비정상 패턴 발견
- 상세 트래픽 분석: Hubble CLI로 관련 트래픽 심층 분석
# 의심스러운 IP의 모든 트래픽을 상세 모드로 분석# SUSPICIOUS_IP를 실제 의심되는 IP로 대체hubble observe --ip SUSPICIOUS_IP -o debug
- 격리 조치: 문제 Pod 또는 서비스 격리를 위한 임시 네트워크 정책 적용
apiVersion: "cilium.io/v2"kind: CiliumNetworkPolicymetadata: name: "quarantine-policy" # 격리 정책 이름 namespace: affected-namespace # 영향받은 네임스페이스spec: endpointSelector: # 이 정책이 적용될 대상 matchLabels: app: compromised-app # 침해된 애플리케이션 레이블 ingress: # 수신 규칙 (매우 제한적) - fromEntities: # 클러스터 내부에서만 접근 허용 - cluster toPorts: # SSH 포트만 허용 (디버깅용) - ports: - port: "22" protocol: TCP egress: # 송신 규칙 (완전 차단) - toEntities: # 모든 외부 통신 차단 - none
- 증거 수집: 관련 트래픽 로그 보존
# 의심스러운 IP의 모든 트래픽을 타임스탬프가 포함된 파일명으로 저장# SUSPICIOUS_IP를 실제 의심되는 IP로 대체hubble observe --ip SUSPICIOUS_IP -o json > evidence_$(date +%Y%m%d_%H%M%S).json
- 정상화 및 분석: 문제 해결 후 추가 보안 정책 적용
📌 Hubble의 성능과 한계
Hubble은 강력한 도구이지만 몇 가지 제한사항도 있습니다:
✅ 성능 고려사항
- 리소스 사용량
- Hubble은 eBPF를 사용하여 트래픽을 캡처하므로 일반적인 DPI(Deep Packet Inspection) 도구보다 효율적이지만, 여전히 일정 수준의 리소스를 소비합니다.
- 대규모 클러스터에서는 Hubble Relay가 모든 데이터를 집계할 때 메모리 사용량이 증가할 수 있습니다.
- 스토리지 제한
- 기본적으로 Hubble은 인메모리 링 버퍼를 사용하여 최근 트래픽만 저장합니다.
- 기본 설정에서는 약 4,000개의 이벤트만 저장되며, 오래된 이벤트는 자동으로 삭제됩니다.
- 설정 최적화
- # cilium-config ConfigMap의 관련 설정 hubble-disable-tls: "true" # 개발 환경에서만 사용 (프로덕션에서는 보안상 사용하지 말 것) hubble-socket-path: /var/run/cilium/hubble.sock # Hubble 서버 소켓 경로 hubble-metrics-server: ":9091" # Prometheus 메트릭 서버 포트 hubble-flow-buffer-size: "65536" # 버퍼 크기 확장 (기본값: 4096) # 더 많은 이벤트 저장 가능하지만 메모리 사용량 증가
✅ 한계 및 주의사항
- 완전한 패킷 캡처 아님
- Hubble은 전체 패킷 데이터가 아닌 메타데이터와 일부 페이로드만 캡처합니다.
- L7 프로토콜(HTTP, gRPC, Kafka 등)에 대한 상세 정보는 필터가 적용된 경우에만 확인 가능합니다.
- 보안 고려사항
- Hubble UI 및 Relay 접근 권한 관리가 중요합니다. 민감한 트래픽 정보가 노출될 수 있습니다.
- 프로덕션 환경에서는 TLS 및 RBAC 설정이 필수적입니다.
- 필터링 제한
- 복잡한 필터링은 성능에 영향을 미칠 수 있습니다.
- 일부 L7 프로토콜 필터는 추가 리소스를 소비할 수 있습니다.
✅ 성능 최적화 팁
# 최소한의 필터로 시작하여 점진적으로 확장
# 특정 네임스페이스와 Pod로 범위를 제한하여 부하 감소
hubble observe --namespace specific-namespace --pod app-frontend
# 관찰 기간 제한
# 최근 1000개 이벤트만 관찰하여 메모리 사용량 제한
hubble observe -n 1000 # 최근 1000개 이벤트만 관찰
# 필요한 필드만 출력하여 성능 향상
# 출력 형식을 최소화하여 처리 속도 개선
hubble observe --output "{source.pod} -> {destination.pod} {verdict}"
# 특정 문제 해결 시에만 디버그 모드 사용
# 디버그 모드는 리소스를 많이 사용하므로 필요한 경우만 사용
hubble observe -o debug --verdict DROPPED
📌 Hubble을 활용한 실무 대시보드 구성 전략
Hubble의 데이터를 Prometheus 및 Grafana와 통합하여 종합적인 모니터링 대시보드를 구성하는 방법을 알아보겠습니다.
✅ Hubble 메트릭스 수집 활성화
Hubble은 Prometheus 메트릭을 제공하여 장기적인 트렌드 분석과 알림 설정이 가능합니다.
# values.yaml (Helm 설치 시)
hubble:
enabled: true # Hubble 기능 활성화
metrics:
enabled: # 활성화할 메트릭 유형 지정
- dns # DNS 관련 메트릭 (쿼리 수, 응답 코드 등)
- drop # 드롭된 패킷 관련 메트릭 (이유별 분류)
- tcp # TCP 연결 관련 메트릭 (SYN, FIN, RST 등)
- flow # 전체 플로우 관련 메트릭 (처리된 총 플로우 수 등)
- icmp # ICMP 관련 메트릭 (타입별 분류)
- http # HTTP 관련 메트릭 (상태 코드, 메소드별 분류)
serviceMonitor:
enabled: true # Prometheus Operator용 ServiceMonitor 리소스 생성
▶️ 주요 메트릭:
- hubble_flows_processed_total: 처리된 총 플로우 수
- hubble_drop_total: 드롭된 패킷 수 (이유별 분류)
- hubble_tcp_flags_total: TCP 플래그별 통계
- hubble_http_requests_total: HTTP 요청 수 (상태 코드별 분류)
- hubble_dns_queries_total: DNS 쿼리 수 (응답 코드별 분류)
✅ Grafana 대시보드 구성
Grafana 대시보드를 구성하여 네트워크 트래픽을 시각화할 수 있습니다:
[Grafana 대시보드 화면: 네트워크 트래픽 시각화, HTTP 상태 코드, DNS 쿼리, 드롭된 패킷 등의 차트가 표시된 대시보드]
▶️ 유용한 대시보드 패널:
- 네트워크 트래픽 추이: 시간별 트래픽 양 시각화
- 상태 코드 분포: HTTP 응답 코드 비율 파이 차트
- 에러율 트렌드: 5xx 에러 비율의 시계열 그래프
- 드롭된 패킷 분석: 드롭 이유별 통계
- 네임스페이스 간 트래픽: 히트맵으로 표현된 네임스페이스 간 통신량
✅ 알림 설정
비정상 패턴을 감지하여 자동으로 알림을 전송하는 규칙을 설정할 수 있습니다:
# prometheus-rule.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: hubble-alerts # 알림 규칙 이름
namespace: monitoring # 모니터링 네임스페이스
spec:
groups:
- name: hubble.rules # 알림 규칙 그룹 이름
rules:
- alert: HighPacketDropRate # 패킷 드롭 비율이 높은 경우 알림
expr: sum(rate(hubble_drop_total[5m])) / sum(rate(hubble_flows_processed_total[5m])) > 0.05
# 표현식: 5분 동안의 드롭 비율이 5% 초과인 경우
for: 10m # 10분 동안 지속되면 알림 발생
labels:
severity: warning # 경고 수준
annotations:
summary: "High packet drop rate detected" # 알림 요약
description: "More than 5% of packets are being dropped in the cluster" # 상세 설명
- alert: HTTPErrorRateHigh # HTTP 에러 비율이 높은 경우 알림
expr: sum(rate(hubble_http_requests_total{code=~"5.."}[5m])) / sum(rate(hubble_http_requests_total[5m])) > 0.1
# 표현식: 5분 동안의 5xx 에러 비율이 10% 초과인 경우
for: 5m # 5분 동안 지속되면 알림 발생
labels:
severity: critical # 심각 수준
annotations:
summary: "High HTTP error rate detected" # 알림 요약
description: "More than 10% of HTTP requests are resulting in 5xx errors" # 상세 설명
- alert: UnusualDNSQueries # 비정상적인 DNS 쿼리 패턴 감지 알림
expr: sum(rate(hubble_dns_queries_total{rcode="NXDomain"}[5m])) > 10
# 표현식: 5분 동안 NXDomain(존재하지 않는 도메인) 응답이 초당 10개 초과인 경우
for: 15m # 15분 동안 지속되면 알림 발생
labels:
severity: warning # 경고 수준
annotations:
summary: "Unusual number of NXDomain DNS responses" # 알림 요약
description: "There are more than 10 NXDomain DNS responses per second, which may indicate DNS exfiltration or misconfiguration" # 상세 설명
📌 Best Practice
✅ 일상적인 모니터링 루틴
효과적인 네트워크 모니터링을 위한 일상적인 루틴을 수립하는 것이 중요합니다:
- 정기 점검 사항
- 드롭된 패킷 비율 검토
- 예상치 못한 통신 패턴 확인
- HTTP 에러율 모니터링
- 네트워크 정책 적용 상태 확인
- 자동화된 모니터링 스크립트
#!/bin/bash
# daily-network-check.sh
# 지난 24시간 동안 가장 많이 드롭된 트래픽 상위 10개
echo "=== Top 10 Dropped Traffic Patterns ==="
# 최근 1000개의 차단된 트래픽 로그를 수집하여 출발지->목적지 패턴별로 그룹화
# 가장 빈번하게 차단되는 패턴 상위 10개를 추출하여 파일로 저장
hubble observe --verdict DROPPED -n 1000 -o json | \
jq 'group_by(.source.namespace + "/" + .source.podName + " -> " + .destination.namespace + "/" + .destination.podName) | \
map({pattern: .[0].source.namespace + "/" + .[0].source.podName + " -> " + .[0].destination.namespace + "/" + .[0].destination.podName, count: length}) | \
sort_by(.count) | reverse | .[0:10]' | \
tee daily-drops-$(date +%Y%m%d).json
# 에러 상태 코드 비율 계산
echo -e "\n=== HTTP Error Rate ==="
# 최근 1000개의 HTTP 트래픽 로그를 수집하여 상태 코드 첫 자리별로 그룹화
# 2xx(성공), 3xx(리다이렉트), 4xx(클라이언트 에러), 5xx(서버 에러) 비율 계산
hubble observe --protocol http -n 1000 -o json | \
jq 'group_by(.l7.http.code | tostring | .[0:1]) | \
map({code_prefix: .[0].l7.http.code | tostring | .[0:1], count: length}) | \
map({code_type: (if .code_prefix == "2" then "Success" elif .code_prefix == "3" then "Redirect" \
elif .code_prefix == "4" then "Client Error" elif .code_prefix == "5" then "Server Error" \
else "Unknown" end), count: .count})'
- 주간 심층 분석
- Hubble UI 서비스 맵에서 아키텍처 변화 확인
- 정책 효과 검토 및 필요시 수정
- 비정상 트래픽 패턴에 대한 심층 분석
✅ 문제 해결 가이드
네트워크 문제 발생 시 Hubble을 활용한 체계적인 문제 해결 단계:
- 문제 현상 파악
- # 특정 서비스 간 통신 문제 확인 # service-a에서 service-b로의 통신 상태를 확인하여 문제 현상 파악 hubble observe --pod-from service-a --pod-to service-b
- 정책 검토
- # 관련 네트워크 정책 확인 # 모든 네임스페이스의 CiliumNetworkPolicy 목록 확인 kubectl get cnp -A # 특정 네임스페이스의 특정 정책 상세 정보 확인 kubectl describe cnp -n <namespace> <policy-name>
- 드롭된 트래픽 분석
- # 드롭 이유 확인 # service-a에서 service-b로 향하는 차단된 트래픽의 드롭 이유 분석 hubble observe --verdict DROPPED --pod-from service-a --pod-to service-b -o json | jq '.[] | .dropReason'
- L7 프로토콜 검사
- # HTTP 경우 # service-a에서 service-b로의 HTTP 트래픽을 디버그 모드로 상세 분석 hubble observe --protocol http --pod-from service-a --pod-to service-b -o debug
- 정책 수정 테스트
- # 테스트용 임시 정책 적용 # 문제 해결을 위한 테스트 정책 적용 kubectl apply -f test-policy.yaml # 효과 확인 # 정책 적용 후 실시간으로 트래픽 변화 관찰 hubble observe --pod-from service-a --pod-to service-b --follow
✅ 전체 클러스터 네트워크 스냅샷 생성
주기적으로 전체 네트워크 상태를 기록하여 문제 발생 시 비교 분석에 활용할 수 있습니다:
#!/bin/bash
# network-snapshot.sh
# 현재 날짜와 시간 기반으로 스냅샷 디렉토리 생성
SNAPSHOT_DIR="network-snapshots/$(date +%Y%m%d-%H%M)"
mkdir -p $SNAPSHOT_DIR
# 1. 네트워크 정책 스냅샷
echo "Capturing network policies..."
# 모든 네임스페이스의 Cilium 네트워크 정책 저장
kubectl get cnp -A -o yaml > $SNAPSHOT_DIR/cilium-network-policies.yaml
# 모든 네임스페이스의 Kubernetes 기본 네트워크 정책 저장
kubectl get networkpolicies -A -o yaml > $SNAPSHOT_DIR/k8s-network-policies.yaml
# 2. Cilium 상태 스냅샷
echo "Capturing Cilium status..."
# Cilium 전체 상태 정보 저장
cilium status --verbose > $SNAPSHOT_DIR/cilium-status.txt
# 모든 Cilium 엔드포인트 정보 저장 (Pod별 네트워크 구성)
cilium endpoint list -o json > $SNAPSHOT_DIR/cilium-endpoints.json
# 3. 트래픽 패턴 스냅샷
echo "Capturing traffic patterns..."
# 최근 1000개 네트워크 흐름 저장
hubble observe -n 1000 -o json > $SNAPSHOT_DIR/recent-flows.json
# 4. 서비스 맵 스냅샷
echo "Creating service map summary..."
# 최근 5000개 로그를 수집하여 출발지->목적지 패턴별로 그룹화
# 트래픽 양이 많은 통신 경로 순으로 정렬
hubble observe -n 5000 -o json | \
jq 'group_by(.source.namespace + "/" + .source.podName + " -> " + .destination.namespace + "/" + .destination.podName) | \
map({route: .[0].source.namespace + "/" + .[0].source.podName + " -> " + .[0].destination.namespace + "/" + .[0].destination.podName, count: length}) | \
sort_by(.count) | reverse' \
> $SNAPSHOT_DIR/service-map.json
# 5. 메트릭 스냅샷
echo "Capturing metrics..."
# Hubble 메트릭 서버에서 Prometheus 메트릭 수집
curl -s http://localhost:9091/metrics > $SNAPSHOT_DIR/hubble-metrics.txt
echo "Network snapshot created in $SNAPSHOT_DIR"
📌 Summary
Hubble은 Cilium의 강력한 가시성 도구로, 쿠버네티스 네트워크 트래픽을 심층적으로 분석할 수 있게 해줍니다. 이 글에서 다룬 주요 내용은 다음과 같습니다:
- Hubble CLI 고급 사용법:
- 다양한 필터 옵션(네임스페이스, Pod, IP, HTTP 메소드 등)
- 복합 필터 표현식을 활용한 정밀한 트래픽 분석
- 출력 형식 사용자 정의 및 데이터 가공
- Hubble UI 활용:
- 서비스 맵을 통한 클러스터 내 통신 시각화
- 실시간 트래픽 모니터링 및 디버깅
- 네트워크 흐름 분석
- 실무 네트워크 정책 디버깅:
- 정책 적용 전후 트래픽 변화 관찰
- 차단된 트래픽 원인 분석
- 정책 최적화 및 테스트
- 보안 모니터링 및 인사이트 도출:
- 비정상 패턴 감지 (DDoS, 포트 스캔 등)
- 인프라 서비스 트래픽 분석
- 보안 사고 대응 워크플로우
- 성능 고려사항 및 최적화:
- Hubble의 리소스 사용량 및 한계
- 성능 최적화 설정 및 전략
- 대규모 클러스터에서의 운영 팁
- 통합 모니터링 및 자동화:
- Prometheus 및 Grafana와의 통합
- 알림 설정 및 자동화된 모니터링 스크립트
- 정기적인 네트워크 스냅샷 생성
'Kubernetes Tools > Cilium' 카테고리의 다른 글
EP15. Cilium 성능 최적화와 한계점 | 실무 팁과 리스크 관리 (0) | 2025.03.23 |
---|---|
EP14. Cilium 운영 환경 구성 전략 | 롤아웃, 업데이트, 장애 복구 (0) | 2025.03.23 |
EP12. ID 기반 정책과 보안 강화 | Identity 기반 접근 제어 이해 (0) | 2025.03.23 |
EP11. CiliumClusterwideNetworkPolicy 실습 | 클러스터 전체 범위 제어 (0) | 2025.03.23 |
EP10. CIDR, Entity 기반 정책 구성 | 외부 접근 정밀 제어 (0) | 2025.03.22 |