Observability/Prometheus

EP09 [Part 3: 클러스터 모니터링 깊게 들여다보기] 네트워크 및 시스템 메트릭 분석

ygtoken 2025. 3. 24. 09:37
728x90

이번 글에서는 쿠버네티스 클러스터의 네트워크와 시스템 메트릭을 분석하는 방법에 대해 심층적으로 알아보겠습니다. 지금까지 노드와 파드, 네임스페이스 수준의 리소스 모니터링에 대해 살펴보았다면, 이제는 클러스터 구성 요소 간의 통신과 시스템 상태를 모니터링하는 방법을 탐구할 차례입니다. 네트워크 트래픽, 지연 시간, 오류율과 같은 네트워크 지표와 함께 커널 파라미터, 파일 시스템 상태, 프로세스 메트릭과 같은 시스템 수준의 지표를 모니터링하는 방법을 배웁니다. 이를 통해 클러스터 내 통신 문제를 조기에 발견하고, 시스템 레벨의 병목 현상을 식별하여 전반적인 클러스터 성능과 안정성을 향상시킬 수 있는 종합적인 방법론을 제시하겠습니다.


📌 네트워크 모니터링의 중요성

쿠버네티스 클러스터에서 네트워크는 모든 구성 요소를 연결하는 핵심 인프라입니다. 효과적인 네트워크 모니터링은 다음과 같은 이점을 제공합니다:

서비스 가용성 보장

  • 서비스 간 통신 문제 조기 감지
  • 네트워크 병목 현상 식별
  • DNS 해결 지연 또는 실패 감지

성능 최적화

  • 네트워크 지연 시간 추적 및 최적화
  • 대역폭 사용량 모니터링
  • 패킷 손실 및 재전송 식별

보안 강화

  • 비정상적인 네트워크 트래픽 패턴 감지
  • 잠재적인 보안 위협 조기 식별
  • 네트워크 정책 효과 검증

▶️ 실제 사례: 한 기업은 네트워크 모니터링을 통해 특정 서비스의 간헐적인 지연 문제를 감지했습니다. 조사 결과, DNS 캐싱 문제로 인한 것으로 밝혀졌고, DNS 설정 최적화 후 서비스 응답 시간이 50% 개선되었습니다.


📌 네트워크 메트릭 모니터링

쿠버네티스 클러스터의 네트워크 메트릭을 모니터링하는 방법을 살펴보겠습니다.

✅ 노드 수준 네트워크 메트릭

노드 수준에서 네트워크 인터페이스의 성능을 모니터링하는 것은 기본적이면서도 중요합니다:

# 노드별 네트워크 수신 트래픽 속도
# node_network_receive_bytes_total: 각 네트워크 인터페이스가 수신한 총 바이트 수
# rate(): 지정된 시간 범위에서 초당 평균 변화율 계산
# [5m]: 5분 간격의 데이터 사용
# device!~"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*": 실제 물리 인터페이스만 선택
#   - lo: 루프백 인터페이스 (로컬 통신용)
#   - veth.*: 가상 이더넷 인터페이스 (컨테이너 연결용)
#   - docker.*, flannel.*, cali.*, cbr.*: CNI 플러그인 관련 가상 인터페이스
# 결과: 초당 바이트 수 (예: 1.2e+6 = 약 1.2MB/s)
# 정상적인 패턴을 파악하여 비정상적인 트래픽 증가/감소 탐지 가능

rate(node_network_receive_bytes_total{device!~"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*"}[5m])
# 노드별 네트워크 송신 트래픽 속도
# node_network_transmit_bytes_total: 각 네트워크 인터페이스가 전송한 총 바이트 수
# device: 네트워크 인터페이스 식별자
# instance: 노드 식별자
# 가상 인터페이스(lo, veth 등) 제외하고 실제 물리 인터페이스만 모니터링
# 결과는 초당 바이트 수로 표시되며, 대역폭 사용률 계산에 사용 가능
# 갑작스런 트래픽 감소는 네트워크 문제 징후일 수 있음

rate(node_network_transmit_bytes_total{device!~"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*"}[5m])

✅ 네트워크 오류 및 패킷 손실 모니터링

패킷 손실과 네트워크 오류는 애플리케이션 성능에 직접적인 영향을 미칩니다:

# 네트워크 인터페이스별 수신 오류 비율
# node_network_receive_errs_total: 수신 중 발생한 오류 총 수
# rate(): 오류 발생 속도 계산
# / rate(node_network_receive_packets_total): 총 수신 패킷 대비 비율
# * 100: 백분율로 변환
# 결과: 수신 패킷 중 오류 비율(%)
# 1% 이상이면 심각한 네트워크 문제 가능성 높음
# 지속적인 오류는 하드웨어 또는 드라이버 문제 의심 필요

rate(node_network_receive_errs_total[5m]) / rate(node_network_receive_packets_total[5m]) * 100
# 네트워크 인터페이스별 송신 패킷 손실 비율
# node_network_transmit_drop_total: 송신 중 드롭된 패킷 총 수
# 결과: 전송 패킷 중 손실된 패킷 비율(%)
# 일시적인 스파이크는 네트워크 혼잡 의미할 수 있음
# 지속적인 패킷 손실은 대역폭 문제 또는 하드웨어 이슈 가능성

rate(node_network_transmit_drop_total[5m]) / rate(node_network_transmit_packets_total[5m]) * 100

✅ 서비스 수준 네트워크 지표

쿠버네티스 서비스 간 통신을 모니터링하는 것은 애플리케이션 성능 이해에 중요합니다:

# kube-proxy 연결 동기화 지연 시간
# kubeproxy_sync_proxy_rules_duration_seconds: kube-proxy가 프록시 규칙을 동기화하는 데 걸린 시간
# quantile: 지연 시간 분포의 특정 백분위수 (0.5 = 중앙값, 0.9 = 90번째 백분위수)
# 결과: 초 단위 지연 시간
# 중앙값/90번째 백분위수의 급격한 증가는 네트워크 정책 변경 또는 kube-proxy 문제 의미
# 대규모 클러스터에서 높은 값은 서비스 검색 지연으로 이어질 수 있음

histogram_quantile(0.5, sum(rate(kubeproxy_sync_proxy_rules_duration_seconds_bucket[5m])) by (instance, le))
histogram_quantile(0.9, sum(rate(kubeproxy_sync_proxy_rules_duration_seconds_bucket[5m])) by (instance, le))

✅ DNS 성능 모니터링

쿠버네티스 클러스터에서 DNS는 서비스 검색의 핵심 구성 요소입니다. DNS 성능 문제는 전체 애플리케이션 지연으로 이어질 수 있습니다:

# CoreDNS 응답 지연 시간 (백분위수별)
# coredns_dns_request_duration_seconds: DNS 요청 처리 시간
# histogram_quantile(): 특정 백분위수 계산
# 0.5: 중앙값 (50번째 백분위수)
# 0.9: 90번째 백분위수
# 0.99: 99번째 백분위수
# le: less than or equal (버킷 경계)
# server, zone, type: DNS 요청 특성 (서버, 영역, 요청 유형)
# 결과: 각 백분위수의 응답 시간 (초)
# 중앙값은 일반적인 성능, 99번째 백분위수는 최악의 경우 성능 나타냄
# 응답 시간 증가는 DNS 서버 과부하 또는 구성 문제 의미 가능

# 중앙값 응답 시간
histogram_quantile(0.5, sum(rate(coredns_dns_request_duration_seconds_bucket[5m])) by (server, zone, type, le))

# 90번째 백분위수 응답 시간
histogram_quantile(0.9, sum(rate(coredns_dns_request_duration_seconds_bucket[5m])) by (server, zone, type, le))

# 99번째 백분위수 응답 시간
histogram_quantile(0.99, sum(rate(coredns_dns_request_duration_seconds_bucket[5m])) by (server, zone, type, le))
# CoreDNS 응답 코드별 요청 수
# coredns_dns_responses_total: DNS 응답 총 수
# rcode: 응답 코드
#   - NOERROR (0): 오류 없음, 성공적인 응답
#   - NXDOMAIN (3): 도메인 이름이 존재하지 않음
#   - SERVFAIL (2): 서버 실패
#   - REFUSED (5): 요청 거부
# sum by (rcode): 응답 코드별로 합산
# 결과: 각 응답 코드별 초당 요청 수
# NXDOMAIN 증가: 잘못된 서비스 이름 사용 가능성
# SERVFAIL 증가: CoreDNS 구성 문제 또는 리소스 부족 의심

sum by (rcode) (rate(coredns_dns_responses_total[5m]))

✅ 네트워크 정책 효과 모니터링

쿠버네티스 네트워크 정책(NetworkPolicy)은 파드 간 트래픽을 제어합니다. 네트워크 정책의 효과를 모니터링하는 것은 보안 상태를 이해하는 데 중요합니다:

# Calico 네트워크 정책 거부된 패킷 (Calico CNI 사용 시)
# calico_denied_packets: Calico 네트워크 정책에 의해 거부된 패킷 수
# rate(): 시간당 거부된 패킷 비율 계산
# namespace, pod: 트래픽 출발지 정보
# dest_namespace, dest_pod: 트래픽 목적지 정보
# 결과: 특정 파드/네임스페이스 간 거부된 초당 패킷 수
# 예상치 못한 거부 패킷 증가는 정책 구성 오류 또는 잠재적 침입 시도 의미 가능
# 정기적으로 모니터링하여 네트워크 정책 효과 검증

rate(calico_denied_packets{namespace="app-namespace", pod=~"frontend-.*", dest_namespace="db-namespace"}[5m])

📌 시스템 메트릭 모니터링

네트워크 외에도, 커널 파라미터, 프로세스 상태, 시스템 리소스와 같은 저수준 시스템 메트릭을 모니터링하는 것이 중요합니다.

✅ 커널 파라미터 모니터링

리눅스 커널 파라미터는 시스템 성능과 안정성에 큰 영향을 미칩니다:

# inode 사용률 모니터링
# node_filesystem_files: 파일시스템의 총 inode 수
# node_filesystem_files_free: 사용 가능한 inode 수
# mountpoint="/": 루트 파일시스템만 선택
# fstype!="tmpfs": 임시 파일시스템 제외
# (node_filesystem_files - node_filesystem_files_free): 사용 중인 inode 수
# / node_filesystem_files: 총 inode 수로 나누어 비율 계산
# * 100: 백분율로 변환
# 결과: 파일시스템별 inode 사용률(%)
# 90% 이상 사용률은 많은 작은 파일 생성 가능성, 로그 파일 증가 등의 문제 의심
# inode 고갈 시 디스크 공간이 남아있어도 파일 생성 불가능

(node_filesystem_files{mountpoint="/", fstype!="tmpfs"} - node_filesystem_files_free{mountpoint="/", fstype!="tmpfs"}) / node_filesystem_files{mountpoint="/", fstype!="tmpfs"} * 100
# 파일 핸들 사용률
# node_filefd_allocated: 할당된 파일 디스크립터 수
# node_filefd_maximum: 최대 파일 디스크립터 수
# 결과: 전체 파일 핸들 중 사용 중인 비율(%)
# 지속적으로 높은 비율(>80%)은 "too many open files" 오류 발생 가능성 높음
# 특히 데이터베이스, 프록시 서버 등 많은 연결을 다루는 워크로드 모니터링 중요

node_filefd_allocated / node_filefd_maximum * 100

✅ 프로세스 및 스레드 모니터링

프로세스와 스레드 수를 모니터링하면 리소스 누수와 과부하를 식별하는 데 도움이 됩니다:

# 노드별 프로세스 수
# node_processes_state: 각 상태별 프로세스 수
# state="running": 실행 중인 프로세스만 선택
# sum by (instance): 노드(인스턴스)별로 합산
# 결과: 각 노드의 실행 중인 프로세스 총 수
# 시간에 따른 급격한 증가는 포크 폭탄 또는 리소스 누수 가능성 시사
# 노드별 정상 패턴 대비 이상치 탐지에 유용

sum by (instance) (node_processes_state{state="running"})
# 시스템 전체 스레드 수
# node_processes_threads: 모든 프로세스의 총 스레드 수
# sum by (instance): 노드별로 합산
# 결과: 각 노드의 총 스레드 수
# 지속적인 증가는 메모리 누수 또는 스레드 생성 문제 의심 필요
# 특히 Java 애플리케이션에서 스레드 폭발 문제 모니터링에 유용

sum by (instance) (node_processes_threads)

✅ 시스템 로드 및 컨텍스트 스위치

시스템 로드와 컨텍스트 스위치 비율은 CPU 경합 상태를 이해하는 데 중요합니다:

# 노드 로드 대비 CPU 코어 수 비율
# node_load1, node_load5, node_load15: 1분, 5분, 15분 평균 로드
# / count without(cpu, mode) (node_cpu_seconds_total{mode="idle"}): CPU 코어 수로 나눔
# by (instance): 노드별로 계산
# 결과: CPU 코어 수 대비 시스템 로드 비율
# 1.0 = 정확히 CPU 코어 수만큼의 로드
# >1.0 = CPU 코어보다 더 많은 프로세스가 대기 중 (과부하)
# 컨테이너화된 환경에서도 여전히 유용한 시스템 부하 지표

# 1분 평균 로드 대비 코어 수 비율
node_load1 / count without(cpu, mode) (node_cpu_seconds_total{mode="idle"}) by (instance)

# 5분 평균 로드 대비 코어 수 비율
node_load5 / count without(cpu, mode) (node_cpu_seconds_total{mode="idle"}) by (instance)

# 15분 평균 로드 대비 코어 수 비율
node_load15 / count without(cpu, mode) (node_cpu_seconds_total{mode="idle"}) by (instance)
# 초당 컨텍스트 스위치 수
# node_context_switches_total: 시스템 전체 컨텍스트 스위치 총 수
# rate(): 초당 컨텍스트 스위치 수 계산
# 결과: 초당 컨텍스트 스위치 횟수
# 매우 높은 값은 CPU 경합 또는 I/O 대기 시간 증가 의미 가능
# 일반적으로 코어당 초당 ~5000-10000 컨텍스트 스위치는 정상
# 갑작스러운 증가는 스케줄링 문제 또는 많은 인터럽트 의심

rate(node_context_switches_total[1m])

✅ 가상 메모리 통계

가상 메모리 시스템 성능은 메모리 압력 상황에서 중요합니다:

# 페이지 폴트 비율 (메이저 vs 마이너)
# node_vmstat_pgfault: 마이너 페이지 폴트 총 수 (메모리에서 페이지 재배치)
# node_vmstat_pgmajfault: 메이저 페이지 폴트 총 수 (디스크에서 페이지 로드)
# rate(): 초당 페이지 폴트 발생 비율
# 마이너 페이지 폴트: 일반적으로 성능에 큰 영향 없음
# 메이저 페이지 폴트: 디스크 I/O 발생, 성능 저하 유발
# 메이저 페이지 폴트 비율이 높으면 메모리 부족 또는 메모리 단편화 의심

# 초당 마이너 페이지 폴트
rate(node_vmstat_pgfault[1m])

# 초당 메이저 페이지 폴트
rate(node_vmstat_pgmajfault[1m])
# 스왑 사용량 변화율
# node_vmstat_pswpin: 디스크에서 메모리로 스왑인된 페이지 수
# node_vmstat_pswpout: 메모리에서 디스크로 스왑아웃된 페이지 수
# rate(): 초당 스왑 페이지 수 계산
# 결과: 초당 스왑 인/아웃 페이지 수
# 0이 아닌 값이 지속되면 메모리 압박 상태로 성능 저하 발생 가능
# 쿠버네티스에서는 일반적으로 스왑을 비활성화하므로 0이어야 함
# 값이 관찰되면 노드 구성 확인 필요

# 초당 스왑인 페이지 수
rate(node_vmstat_pswpin[1m])

# 초당 스왑아웃 페이지 수
rate(node_vmstat_pswpout[1m])

📌 네트워크 및 시스템 대시보드 구성

수집한 네트워크 및 시스템 메트릭을 시각화하기 위한 Grafana 대시보드를 구성해 보겠습니다.

✅ 네트워크 대시보드 구성 요소

효과적인 네트워크 모니터링 대시보드에는 다음 요소가 포함되어야 합니다:

[네트워크 모니터링 대시보드 레이아웃:
- 상단: 클러스터 네트워크 개요 (전체 트래픽, 오류율, CoreDNS 상태)
- 중앙: 노드별 네트워크 트래픽 및 패킷 통계
- 하단: 서비스 지연 시간, 연결 상태, 네트워크 정책 효과 지표]

네트워크 인터페이스 트래픽 패널:

# 노드별 네트워크 인터페이스 수신/송신 트래픽 시계열
# Grafana 패널 설정:
# - 패널 유형: Time series
# - 단위: bytes/sec (Grafana에서 단위 변환)
# - 범례: {{instance}} - {{device}}
# - 시각화: 영역 그래프 또는 선 그래프

# 수신 트래픽 (음수값으로 표시하여 상하 대칭 구성)
-rate(node_network_receive_bytes_total{device!~"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*"}[5m])

# 송신 트래픽 (양수값)
rate(node_network_transmit_bytes_total{device!~"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*"}[5m])

DNS 성능 패널:

# CoreDNS 응답 시간 히스토그램
# Grafana 패널 설정:
# - 패널 유형: Heatmap
# - 데이터 포맷: Time series buckets
# - 색상 스키마: 파란색(낮음) → 빨간색(높음)
# - 단위: seconds
# - 그룹: zone 레이블

# 히스토그램 데이터
sum(increase(coredns_dns_request_duration_seconds_bucket[5m])) by (le, zone)

✅ 시스템 메트릭 대시보드 구성 요소

시스템 메트릭 대시보드에는 다음과 같은 핵심 요소가 포함되어야 합니다:

[시스템 메트릭 대시보드 레이아웃:
- 상단: 시스템 로드, CPU 사용률, 메모리 사용률 개요
- 중앙: 프로세스/스레드 통계, 컨텍스트 스위치, 인터럽트
- 하단: 파일 시스템 메트릭, 커널 파라미터, 가상 메모리 통계]

시스템 로드 패널:

# 노드별 시스템 로드 추이 (코어 수 대비)
# Grafana 패널 설정:
# - 패널 유형: Time series
# - 임계값: 0.7 (경고), 1.0 (위험)
# - 범례: {{instance}} - {{load}}
# - Y축 최소값: 0

# 1분, 5분, 15분 로드
# alias() 함수는 Grafana에서 범례 이름 지정
node_load1 / count without(cpu, mode) (node_cpu_seconds_total{mode="idle"}) by (instance)

node_load5 / count without(cpu, mode) (node_cpu_seconds_total{mode="idle"}) by (instance)

node_load15 / count without(cpu, mode) (node_cpu_seconds_total{mode="idle"}) by (instance)

파일 핸들 사용률 패널:

# 노드별 파일 핸들 사용률 게이지
# Grafana 패널 설정:
# - 패널 유형: Gauge
# - 임계값: 50% (경고), 80% (위험)
# - 단위: 백분율

# 파일 핸들 사용률
node_filefd_allocated / node_filefd_maximum * 100

📌 네트워크 및 시스템 모니터링 알림 설정

효과적인 네트워크 및 시스템 모니터링을 위한 알림 규칙을 설정해 보겠습니다.

✅ 네트워크 관련 알림 규칙

# 네트워크 모니터링 알림 규칙
# 파일명: network-alerts.yaml
# 적용 방법: kubectl apply -f network-alerts.yaml
# 주요 알림:
# 1. 높은 네트워크 오류율
# 2. DNS 응답 지연
# 3. 네트워크 인터페이스 포화

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: network-monitoring-rules
  namespace: monitoring
  labels:
    app: kube-prometheus-stack         # kube-prometheus-stack과 통합하기 위한 레이블
    release: prometheus                # Helm 릴리스 이름에 맞게 조정
spec:
  groups:
  - name: network.rules                # 규칙 그룹 이름
    rules:
    # 네트워크 인터페이스 오류율 알림
    # 수신 패킷 중 오류 비율이 1% 이상일 경우 경고
    # 물리적 네트워크 문제 또는 드라이버 이슈 의심 필요
    # for: 5m - 5분 이상 지속될 경우 알림 발생 (일시적 스파이크 필터링)
    - alert: HighNetworkErrorRate
      expr: rate(node_network_receive_errs_total[5m]) / rate(node_network_receive_packets_total[5m]) * 100 > 1
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "높은 네트워크 오류율 (인스턴스 {{ $labels.instance }})"
        description: "네트워크 인터페이스 {{ $labels.device }}의 오류율이 1%를 초과했습니다.\n  현재 오류율: {{ $value | humanizePercentage }}"
    
# DNS 응답 지연 알림
   # CoreDNS의 90번째 백분위수 응답 시간이 100ms를 초과할 경우 경고
   # DNS 지연은 서비스 검색과 전체 애플리케이션 성능에 영향을 미침
   # for: 15m - 15분 이상 지속될 경우 알림 발생 (일시적 지연은 무시)
   - alert: CoreDNSLatencyHigh
     expr: histogram_quantile(0.9, sum(rate(coredns_dns_request_duration_seconds_bucket[5m])) by (server, zone, le)) * 1000 > 100
     for: 15m
     labels:
       severity: warning
     annotations:
       summary: "CoreDNS 응답 지연 (서버 {{ $labels.server }})"
       description: "CoreDNS 영역 {{ $labels.zone }}의 90번째 백분위수 응답 시간이 100ms를 초과했습니다.\n  현재 응답 시간: {{ $value | humanize }}ms"
   
   # 네트워크 인터페이스 포화 알림
   # 네트워크 인터페이스 대역폭의 80% 이상 사용 시 경고
   # 네트워크 인터페이스 속도 정보가 익스포트되는 경우 사용
   # 패킷 드롭이나 지연 발생 가능성 높음
   - alert: NetworkInterfaceSaturation
     expr: (rate(node_network_transmit_bytes_total[5m]) + rate(node_network_receive_bytes_total[5m])) / node_network_speed_bytes * 100 > 80
     for: 10m
     labels:
       severity: warning
     annotations:
       summary: "네트워크 인터페이스 포화 (인스턴스 {{ $labels.instance }})"
       description: "네트워크 인터페이스 {{ $labels.device }}의 사용률이 80%를 초과했습니다.\n  현재 사용률: {{ $value | humanizePercentage }}"

 

✅ 시스템 관련 알림 규칙

# 시스템 모니터링 알림 규칙
# 파일명: system-alerts.yaml
# 적용 방법: kubectl apply -f system-alerts.yaml
# 주요 알림:
# 1. 높은 시스템 로드
# 2. 파일 핸들 고갈
# 3. 높은 메이저 페이지 폴트 비율

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: system-monitoring-rules
  namespace: monitoring
  labels:
    app: kube-prometheus-stack
    release: prometheus
spec:
  groups:
  - name: system.rules                 # 규칙 그룹 이름
    rules:
    # 높은 시스템 로드 알림
    # 코어 수 대비 시스템 로드가 1.5배 이상인 경우 경고
    # 시스템 과부하 상태로 응답성 저하 가능성
    # node_load1: 1분 평균 로드
    # for: 15m - 15분 이상 지속될 경우 알림 발생
    - alert: SystemLoadHigh
      expr: node_load1 / count without(cpu, mode) (node_cpu_seconds_total{mode="idle"}) by (instance) > 1.5
      for: 15m
      labels:
        severity: warning
      annotations:
        summary: "높은 시스템 로드 (인스턴스 {{ $labels.instance }})"
        description: "시스템 로드가 CPU 코어 수의 1.5배를 초과했습니다.\n  현재 로드: {{ $value | humanize }} (코어당)"
    
    # 파일 핸들 고갈 위험 알림
    # 할당된 파일 핸들이 최대 가능 수의 90% 이상인 경우 경고
    # "Too many open files" 오류 발생 가능성 높음
    # for: 10m - 10분 이상 지속될 경우 알림 발생
    - alert: FileDescriptorsExhausting
      expr: node_filefd_allocated / node_filefd_maximum * 100 > 90
      for: 10m
      labels:
        severity: warning
      annotations:
        summary: "파일 핸들 고갈 위험 (인스턴스 {{ $labels.instance }})"
        description: "할당된 파일 핸들이 최대 값의 90%를 초과했습니다.\n  현재 사용률: {{ $value | humanizePercentage }}"
    
    # 높은 메이저 페이지 폴트 비율 알림
    # 초당 메이저 페이지 폴트가 비정상적으로 높은 경우 (임계값은 환경에 따라 조정 필요)
    # 메모리 압박 상태로 I/O 증가 및 성능 저하 발생 가능
    # for: 5m - 5분 이상 지속될 경우 알림 발생
    - alert: HighMajorPageFaults
      expr: rate(node_vmstat_pgmajfault[1m]) > 50
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "높은 메이저 페이지 폴트 (인스턴스 {{ $labels.instance }})"
        description: "메이저 페이지 폴트 비율이 비정상적으로 높습니다.\n  현재 초당 페이지 폴트: {{ $value | humanize }}"

📌 고급 네트워크 및 시스템 모니터링 기술

좀 더 심화된 네트워크 및 시스템 모니터링 기술을 살펴보겠습니다.

✅ 서비스 메시 모니터링 (Istio, Linkerd)

서비스 메시는 마이크로서비스 간 통신을 관리하고 관찰성을 향상시킵니다:

# Istio 서비스 간 요청 지연 시간 (P95)
# histogram_quantile: 백분위수 계산
# 0.95: 95번째 백분위수
# istio_request_duration_milliseconds_bucket: Istio에서 측정한 요청 처리 시간
# reporter="destination": 대상 서비스에서 보고한 메트릭
# 결과: 각 서비스별 95% 요청의 지연 시간 (밀리초)
# 갑작스러운 증가는 서비스 성능 저하 의미

histogram_quantile(0.95, sum(rate(istio_request_duration_milliseconds_bucket{reporter="destination"}[5m])) by (destination_service, source_workload, le))
# Istio 서비스별 오류율
# istio_requests_total: 총 요청 수
# response_code=~"5.*": 5xx 오류 응답만 선택
# sum(rate(...)) by (...): 서비스별로 초당 오류 수 계산
# / : 총 요청 대비 오류 비율 계산
# * 100: 백분율로 변환
# 결과: 서비스별 오류율(%)
# 오류율 증가는 서비스 안정성 문제 의미

sum(rate(istio_requests_total{response_code=~"5.*"}[5m])) by (destination_service, source_workload) / 
sum(rate(istio_requests_total[5m])) by (destination_service, source_workload) * 100

✅ 확장된 BPF (eBPF) 기반 모니터링

eBPF 기술을 활용하면 커널 수준의 상세한 모니터링이 가능합니다. Prometheus와 통합된 eBPF 익스포터를 사용할 수 있습니다:

# TCP 연결 재전송 비율 (eBPF 익스포터 사용 시)
# ebpf_tcp_retransmits_total: TCP 재전송 총 수
# ebpf_tcp_segments_sent_total: 전송된 총 TCP 세그먼트 수
# 결과: 전체 전송 세그먼트 대비 재전송 비율(%)
# 1% 이상은 네트워크 품질 또는 혼잡 문제 의심 필요

rate(ebpf_tcp_retransmits_total[5m]) / rate(ebpf_tcp_segments_sent_total[5m]) * 100
# eBPF를 통한 시스템 호출 지연 시간
# histogram_quantile: 백분위수 계산
# 0.95: 95번째 백분위수
# ebpf_syscall_latency_seconds_bucket: 시스템 호출 지연 시간 분포
# syscall: 시스템 호출 유형
# 결과: 각 시스템 호출별 95% 실행 시간 (초)
# 높은 지연 시간은 I/O 병목 또는 리소스 경합 의미 가능

histogram_quantile(0.95, sum(rate(ebpf_syscall_latency_seconds_bucket[5m])) by (syscall, le))

✅ 커스텀 익스포터 및 메트릭

특정 요구사항에 맞는 커스텀 익스포터를 개발하거나 기존 애플리케이션에서 메트릭을 노출할 수 있습니다:

# 커스텀 메트릭 스크래핑 설정
# apiVersion: monitoring.coreos.com/v1: Prometheus Operator API 버전
# kind: ServiceMonitor: 서비스를 통해 메트릭 스크래핑 설정
# spec.selector: 대상 서비스 선택 기준 (레이블 기반)
# spec.endpoints: 메트릭 엔드포인트 설정
# 이 설정을 통해 Prometheus Operator가 커스텀 메트릭 엔드포인트를 스크래핑

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: custom-network-metrics
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: network-monitor     # 이 레이블을 가진 서비스 선택
  endpoints:
  - port: metrics              # 'metrics'라는 이름의 포트 사용
    interval: 30s              # 30초마다 스크래핑
    path: /metrics             # 메트릭을 노출하는 경로

📌 실제 트러블슈팅 시나리오

네트워크 및 시스템 메트릭을 활용한 실제 트러블슈팅 시나리오를 살펴보겠습니다.

✅ 시나리오 1: 네트워크 지연 문제 해결

문제: 특정 서비스의 응답 시간이 간헐적으로 증가하는 현상 발생

진단 쿼리:

# 서비스 간 통신 지연 시간 분석
# histogram_quantile(): 백분위수 계산
# 0.95: 95번째 백분위수 (tail latency 확인)
# istio_request_duration_milliseconds_bucket: 요청 처리 시간 히스토그램
# reporter="destination": 대상 서비스 관점에서 측정
# destination_service="problematic-service": 문제가 발생한 서비스만 필터링
# by (source_workload, le): 출발지 서비스별로 그룹화
# 결과: 각 클라이언트 서비스에서 문제 서비스로의 95% 지연 시간 (ms)
# 모든 클라이언트에서 지연 발생 시 서비스 자체 문제 의심
# 특정 클라이언트에서만 지연 발생 시 네트워크 경로 문제 의심

histogram_quantile(0.95, sum(rate(istio_request_duration_milliseconds_bucket{reporter="destination", destination_service="problematic-service"}[5m])) by (source_workload, le))

진단 결과:

  • 모든 클라이언트에서 문제 서비스로의 지연 시간이 증가함
  • DNS 응답 시간도 함께 증가하는 패턴 발견
# CoreDNS 응답 시간 확인
# histogram_quantile(): 백분위수 계산
# 0.95: 95번째 백분위수
# coredns_dns_request_duration_seconds_bucket: CoreDNS 요청 처리 시간 히스토그램
# by (server, zone, type, le): 서버, 영역, 요청 유형별로 그룹화
# 결과: CoreDNS의 95% 응답 시간 (초)
# 서비스 지연 시간과 DNS 응답 시간 간의 상관관계 확인 가능

histogram_quantile(0.95, sum(rate(coredns_dns_request_duration_seconds_bucket[5m])) by (server, zone, type, le))

해결 단계:

  1. CoreDNS 리소스 할당 증가 (CPU/메모리)
  2. CoreDNS 복제본 수 증가
  3. DNS 캐싱 설정 최적화
  4. 서비스 디스커버리 패턴 개선

✅ 시나리오 2: 시스템 리소스 고갈 문제

문제: 노드가 간헐적으로 응답하지 않고 파드 배치 실패 발생

진단 쿼리:

# 파일 핸들 사용량 추적
# node_filefd_allocated: 할당된 파일 핸들 수
# node_filefd_maximum: 최대 파일 핸들 수 제한
# 결과: 파일 핸들 사용률 (%)
# 90% 이상이면 "too many open files" 오류 발생 가능성 높음
# 시간에 따른 사용량 증가 패턴 확인

node_filefd_allocated / node_filefd_maximum * 100
# 시스템 로드 및 프로세스 수 확인
# node_load5: 5분 평균 시스템 로드
# <노드의 CPU 코어 수>: 해당 노드의 코어 수 (예: 4)
# 결과: 코어 수 대비 시스템 로드 비율
# 1.0 이상이면 시스템 과부하 의미
# 프로세스 수와 비교하여 상관관계 파악

# 시스템 로드
node_load5{instance="problem-node:9100"} / 4  # 4코어 노드 예시

# 프로세스 수
sum(node_processes_state{instance="problem-node:9100"})

진단 결과:

  • 파일 핸들 사용량이 95% 이상으로 매우 높음
  • 특정 애플리케이션이 연결을 제대로 닫지 않고 리소스 누수 발생

해결 단계:

  1. 문제가 되는 애플리케이션 식별 및 코드 수정
  2. 시스템 수준 파일 핸들 제한 증가
  3. 리소스 사용량 모니터링 알림 설정
  4. 애플리케이션 수준 연결 풀 최적화

✅ 시나리오 3: 네트워크 패킷 손실 문제

문제: 특정 노드에서 실행 중인 서비스가 간헐적으로 타임아웃 발생

진단 쿼리:

# 네트워크 인터페이스 패킷 손실 비율
# node_network_transmit_drop_total: 송신 중 드롭된 패킷 수
# node_network_transmit_packets_total: 송신된 총 패킷 수
# 결과: 송신 패킷 중 손실된 비율 (%)
# 0.1% 이상이면 네트워크 문제 의심 필요
# 노드 간 비교하여 특정 노드 문제인지 확인

rate(node_network_transmit_drop_total{instance="problem-node:9100"}[5m]) / 
rate(node_network_transmit_packets_total{instance="problem-node:9100"}[5m]) * 100
# TCP 재전송 비율 (eBPF 익스포터 사용 시)
# ebpf_tcp_retransmits_total: TCP 재전송 총 수
# ebpf_tcp_segments_sent_total: 전송된 총 TCP 세그먼트 수
# instance: 노드 식별자
# 결과: TCP 재전송 비율 (%)
# 높은 재전송률은 네트워크 혼잡 또는 패킷 손실 의미

rate(ebpf_tcp_retransmits_total{instance="problem-node:9100"}[5m]) / 
rate(ebpf_tcp_segments_sent_total{instance="problem-node:9100"}[5m]) * 100

진단 결과:

  • 문제 노드에서 패킷 드롭 비율이 다른 노드보다 5배 높음
  • TCP 재전송 비율도 비정상적으로 높음

해결 단계:

  1. 물리 네트워크 인터페이스 및 케이블 점검
  2. 네트워크 드라이버 업데이트 또는 설정 조정
  3. 네트워크 장비(스위치, 라우터) 점검
  4. MTU 설정 최적화

📌 네트워크 및 시스템 모니터링 모범 사례

효과적인 네트워크 및 시스템 모니터링을 위한 모범 사례를 살펴보겠습니다.

✅ 다계층 모니터링 접근법

네트워크 및 시스템 모니터링은 여러 계층에서 수행해야 합니다:

  1. 물리 계층:
    • 네트워크 인터페이스 상태
    • 패킷 오류 및 손실
    • 하드웨어 장애
  2. 네트워크 프로토콜 계층:
    • TCP 연결 상태
    • DNS 성능
    • 라우팅 상태
  3. 애플리케이션 계층:
    • 서비스 간 통신 지연 시간
    • API 응답 시간
    • 클라이언트 경험

✅ 신호 대 잡음 최적화

효과적인 모니터링은 중요한 신호에 집중하고 잡음을 줄이는 것이 중요합니다:

  1. 기준선 설정:
    • 정상 상태의 메트릭 패턴 파악
    • 일별/주별/월별 패턴 이해
    • 환경별 특성 고려
  2. 알림 임계값 조정:
    • 과도한 알림 방지를 위한 적절한 임계값 설정
    • 시간 기반 필터링 (일시적 스파이크 무시)
    • 동적 임계값 고려 (시간에 따른 기준선 변화 반영)
  3. 상관 관계 분석:
    • 관련 메트릭 그룹화
    • 근본 원인 식별을 위한 메트릭 간 상관 관계 파악
    • 증상이 아닌 원인에 알림 집중

✅ 복원력 테스트와 모니터링 통합

시스템의 복원력을 테스트하고 모니터링 체계를 지속적으로 개선하는 것이 중요합니다:

  1. 카오스 엔지니어링:
    • 의도적인 장애 주입
    • 복구 메커니즘 검증
    • 모니터링 시스템 자체의 복원력 확인
  2. 포스트모템 분석:
    • 실제 장애 이후 모니터링 개선점 식별
    • 누락된 메트릭 추가
    • 알림 임계값 및 조건 재평가
  3. 지속적인 개선:
    • 새로운 서비스 추가 시 모니터링 확장
    • 기술 스택 변화에 따른 모니터링 업데이트
    • 모니터링 도구 및 기술 트렌드 주시

📌 Summary

이번 포스트에서는 쿠버네티스 클러스터의 네트워크 및 시스템 메트릭을 깊이 있게 분석하는 방법에 대해 알아보았습니다. 다음과 같은 내용을 다루었습니다:

  • 네트워크 메트릭 모니터링: 노드, 파드, 서비스 간 네트워크 트래픽, 패킷 손실, 지연 시간, DNS 성능 등 다양한 네트워크 측면을 모니터링하는 방법을 살펴보았습니다. 특히 CoreDNS와 같은 핵심 네트워크 서비스의 성능 모니터링이 클러스터 안정성에 중요함을 확인했습니다.
  • 시스템 메트릭 모니터링: 커널 파라미터, 파일 핸들, 프로세스 및 스레드, 컨텍스트 스위치, 가상 메모리 통계 등 심층적인 시스템 메트릭을 추적하는 방법을 배웠습니다. 이러한 저수준 메트릭은 애플리케이션 성능 문제의 근본 원인을 파악하는 데 필수적입니다.
  • 효과적인 대시보드 구성: 네트워크 및 시스템 메트릭을 가시화하는 직관적인 대시보드를 구성하는 방법과 PromQL을 활용한 고급 쿼리 기법을 살펴보았습니다. 잘 설계된 대시보드는 복잡한 상관관계를 빠르게 파악하는 데 도움이 됩니다.
  • 알림 규칙 설정: 네트워크 오류율, DNS 지연, 시스템 로드, 파일 핸들 고갈 등 중요한 문제를 조기에 감지하는 알림 규칙을 설정하는 방법을 배웠습니다. 적절한 임계값과 지속 시간 설정으로 알림 피로를 줄이면서도 중요한 이슈를 놓치지 않는 균형이 중요합니다.
  • 고급 모니터링 기술: 서비스 메시, eBPF, 커스텀 익스포터를 활용한 고급 모니터링 기법을 탐색했습니다. 이러한 기술은 더 깊은 수준의 관찰성을 제공하여 복잡한 문제 해결에 도움이 됩니다.
  • 실제 트러블슈팅 시나리오: 네트워크 지연, 시스템 리소스 고갈, 패킷 손실과 같은 실제 문제 상황을 진단하고 해결하는 방법을 구체적인 예시와 함께 살펴보았습니다. 메트릭을 통한 체계적인 문제 접근법이 신속한 해결에 핵심임을 확인했습니다.
  • 모니터링 모범 사례: 다계층 모니터링 접근법, 신호 대 잡음 최적화, 복원력 테스트와 모니터링 통합 등 효과적인 모니터링 체계를 구축하기 위한 모범 사례를 정리했습니다. 지속적인 개선과 학습이 성공적인 모니터링의 핵심 요소입니다.

네트워크 및 시스템 수준의 모니터링은 쿠버네티스 클러스터 관찰성의 중요한 구성 요소입니다. 이러한 깊이 있는 메트릭을 통해 애플리케이션 성능 문제의 근본 원인을 파악하고, 클러스터 안정성을 높이며, 사용자 경험을 개선할 수 있습니다.

728x90