Kubernetes Tools/Cilium

EP13. Hubble CLI & UI 고급 사용법 | 네트워크 분석 실무 활용

ygtoken 2025. 3. 23. 00:32
728x90

이 글에서는 Cilium의 강력한 네트워크 가시성 도구인 Hubble의 고급 사용법에 대해 알아봅니다. 기본적인 명령어부터 시작해 실제 현업에서 활용할 수 있는 복잡한 필터링, 실시간 모니터링, 그리고 네트워크 이슈 디버깅까지 다양한 시나리오를 다룰 예정입니다. 특히 Hubble CLI와 Hubble UI를 통해 쿠버네티스 네트워크 트래픽을 실시간으로 분석하고 시각화하는 방법을 실습 중심으로 살펴보겠습니다.


📌 Hubble 개요 및 기본 구성 확인

Hubble은 Cilium의 네트워크 관찰성(Observability) 계층으로, eBPF를 기반으로 한 강력한 네트워크 모니터링 및 보안 가시성 도구입니다. 이를 통해 우리는 쿠버네티스 클러스터 내의 네트워크 트래픽을 세밀하게 관찰하고 분석할 수 있습니다.

✅ Hubble 아키텍처 이해하기

Hubble은 크게 세 가지 주요 컴포넌트로 구성됩니다:

  1. Hubble - 각 노드의 Cilium Agent에 내장된 모듈로, eBPF를 통해 네트워크 플로우 데이터를 수집합니다.
  2. Hubble Relay - 클러스터 내 모든 Hubble 인스턴스에서 데이터를 수집하고 집계하는 컴포넌트입니다.
  3. 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의 실시간 모니터링 기능을 활용하여 클러스터 내 네트워크 이슈를 빠르게 감지할 수 있습니다.

▶️ 활용 시나리오:

  1. 롤아웃 모니터링: 새 버전 배포 시 네트워크 트래픽 변화 관찰
  2. 장애 감지: 갑작스러운 트래픽 패턴 변화 또는 에러 증가 감지
  3. 보안 모니터링: 비정상적인 통신 패턴 감지
# 간단한 테스트 애플리케이션 배포
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을 사용한 대응 워크플로우:

  1. 이상 징후 감지: Hubble UI 또는 자동화된 모니터링에서 비정상 패턴 발견
  2. 상세 트래픽 분석: Hubble CLI로 관련 트래픽 심층 분석
    # 의심스러운 IP의 모든 트래픽을 상세 모드로 분석# SUSPICIOUS_IP를 실제 의심되는 IP로 대체hubble observe --ip SUSPICIOUS_IP -o debug
    
  3. 격리 조치: 문제 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
    
  4. 증거 수집: 관련 트래픽 로그 보존
    # 의심스러운 IP의 모든 트래픽을 타임스탬프가 포함된 파일명으로 저장# SUSPICIOUS_IP를 실제 의심되는 IP로 대체hubble observe --ip SUSPICIOUS_IP -o json > evidence_$(date +%Y%m%d_%H%M%S).json
    
  5. 정상화 및 분석: 문제 해결 후 추가 보안 정책 적용

📌 Hubble의 성능과 한계

Hubble은 강력한 도구이지만 몇 가지 제한사항도 있습니다:

✅ 성능 고려사항

  1. 리소스 사용량
    • Hubble은 eBPF를 사용하여 트래픽을 캡처하므로 일반적인 DPI(Deep Packet Inspection) 도구보다 효율적이지만, 여전히 일정 수준의 리소스를 소비합니다.
    • 대규모 클러스터에서는 Hubble Relay가 모든 데이터를 집계할 때 메모리 사용량이 증가할 수 있습니다.
  2. 스토리지 제한
    • 기본적으로 Hubble은 인메모리 링 버퍼를 사용하여 최근 트래픽만 저장합니다.
    • 기본 설정에서는 약 4,000개의 이벤트만 저장되며, 오래된 이벤트는 자동으로 삭제됩니다.
  3. 설정 최적화
  4. # 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) # 더 많은 이벤트 저장 가능하지만 메모리 사용량 증가

✅ 한계 및 주의사항

  1. 완전한 패킷 캡처 아님
    • Hubble은 전체 패킷 데이터가 아닌 메타데이터와 일부 페이로드만 캡처합니다.
    • L7 프로토콜(HTTP, gRPC, Kafka 등)에 대한 상세 정보는 필터가 적용된 경우에만 확인 가능합니다.
  2. 보안 고려사항
    • Hubble UI 및 Relay 접근 권한 관리가 중요합니다. 민감한 트래픽 정보가 노출될 수 있습니다.
    • 프로덕션 환경에서는 TLS 및 RBAC 설정이 필수적입니다.
  3. 필터링 제한
    • 복잡한 필터링은 성능에 영향을 미칠 수 있습니다.
    • 일부 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

✅ 일상적인 모니터링 루틴

효과적인 네트워크 모니터링을 위한 일상적인 루틴을 수립하는 것이 중요합니다:

  1. 정기 점검 사항
    • 드롭된 패킷 비율 검토
    • 예상치 못한 통신 패턴 확인
    • HTTP 에러율 모니터링
    • 네트워크 정책 적용 상태 확인
  2. 자동화된 모니터링 스크립트
#!/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})'
  1. 주간 심층 분석
    • Hubble UI 서비스 맵에서 아키텍처 변화 확인
    • 정책 효과 검토 및 필요시 수정
    • 비정상 트래픽 패턴에 대한 심층 분석

✅ 문제 해결 가이드 

네트워크 문제 발생 시 Hubble을 활용한 체계적인 문제 해결 단계:

  1. 문제 현상 파악
  2. # 특정 서비스 간 통신 문제 확인 # service-a에서 service-b로의 통신 상태를 확인하여 문제 현상 파악 hubble observe --pod-from service-a --pod-to service-b
  3. 정책 검토
  4. # 관련 네트워크 정책 확인 # 모든 네임스페이스의 CiliumNetworkPolicy 목록 확인 kubectl get cnp -A # 특정 네임스페이스의 특정 정책 상세 정보 확인 kubectl describe cnp -n <namespace> <policy-name>
  5. 드롭된 트래픽 분석
  6. # 드롭 이유 확인 # service-a에서 service-b로 향하는 차단된 트래픽의 드롭 이유 분석 hubble observe --verdict DROPPED --pod-from service-a --pod-to service-b -o json | jq '.[] | .dropReason'
  7. L7 프로토콜 검사
  8. # HTTP 경우 # service-a에서 service-b로의 HTTP 트래픽을 디버그 모드로 상세 분석 hubble observe --protocol http --pod-from service-a --pod-to service-b -o debug
  9. 정책 수정 테스트
  10. # 테스트용 임시 정책 적용 # 문제 해결을 위한 테스트 정책 적용 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와의 통합
    • 알림 설정 및 자동화된 모니터링 스크립트
    • 정기적인 네트워크 스냅샷 생성
728x90