멀티클라우드 서비스 모니터링 이슈에 대한 해결
안녕하세요,
크라우드웍스 보안운영팀 마승우입니다.
오늘은 저희 팀이 최근 완료한 프로메테우스(Prometheus)와 그라파나(Grafana) 기반의 통합 모니터링 시스템 구축 경험을 여러분과 공유하고자 합니다.
우리의 도전 과제: 다중 클라우드 환경의 모니터링
최근 클라우드 서비스들이 각자의 특색을 가지고 발전함에 따라, 기업들은 점점 더 다중 클라우드 환경을 채택하고 있습니다. 예를 들어, 주요 서비스는 AWS에서 운영하고, 데이터 분석은 GCP의 BigQuery를 활용하는 등 각 클라우드의 강점을 살린 구성이 늘어나고 있습니다. 더욱이 엔터프라이즈 고객들의 경우, 기존의 레거시 시스템과의 호환성 때문에 AI 서비스는 Azure를, 데이터베이스는 Oracle Cloud Infrastructure(OCI)를 사용하는 등 더욱 복잡한 멀티클라우드 환경에 직면하고 있습니다.
크라우드웍스 역시 이러한 추세에 발맞춰 NCP, AWS, GCP, Azure 등 다양한 클라우드 서비스 제공업체(CSP)의 인프라를 활용하고 있습니다. 각 클라우드의 장점을 최대한 활용하기 위해 VM이나 PaaS(ECS, RDS 등) 서비스들이 여러 클라우드에 분산되어 있습니다.
이러한 다중 클라우드 환경은 유연성과 최적의 성능을 제공하는 반면, 모니터링과 관리 측면에서 큰 도전 과제를 안겨주었습니다. 각 클라우드 제공업체마다 고유한 모니터링 도구와 메트릭을 제공하기 때문에, 전체 시스템의 상태를 통합적으로 파악하고 문제 발생 시 신속하게 대응하는 것이 매우 어려웠습니다.
특히 다음과 같은 문제점들이 두드러졌습니다:
- 각 클라우드의 개별 대시보드를 번갈아 확인해야 하는 비효율성
- 서로 다른 메트릭 체계로 인한 일관된 성능 평가의 어려움
- 클라우드 간 연계된 서비스의 end-to-end 모니터링 부재
- 통합된 알림 시스템 구축의 복잡성
이러한 상황에서, 우리는 다중 클라우드 환경을 아우르는 통합 모니터링 솔루션의 필요성을 절감하게 되었습니다. 이는 단순히 여러 대시보드를 하나로 모으는 것을 넘어, 다양한 클라우드 서비스 간의 복잡한 상호작용을 이해하고, 전체 시스템의 건강 상태를 실시간으로 파악할 수 있는 솔루션이 필요했습니다.
왜 프로메테우스와 그라파나인가?
이러한 상황에서, 우리는 다중 클라우드 환경을 아우르는 통합 모니터링 솔루션의 필요성을 절감하게 되었습니다. 이는 단순히 여러 대시보드를 하나로 모으는 것을 넘어, 다양한 클라우드 서비스 간의 복잡한 상호작용을 이해하고, 전체 시스템의 건강 상태를 실시간으로 파악할 수 있는 솔루션이 필요했습니다.왜 프로메테우스와 그라파나인가?
이러한 복잡한 멀티 클라우드 환경에서 효과적인 모니터링은 선택이 아닌 필수입니다.
우리에게는 다음과 같은 요구사항이 있었습니다:
- 다양한 CSP에 걸쳐 있는 서버들을 통합 모니터링
- 실시간 메트릭 수집 및 분석
- 커스텀이 가능한 대시보드
- 임계값 기반의 유연한 알림 설정
- 솔루션 도입 비용
이러한 요구사항을 충족시킬 수 있는 솔루션으로 프로메테우스와 그라파나를 선택했습니다.
- 프로메테우스: 메트릭 수집과 저장에 특화된 오픈소스 모니터링 시스템으로, 동적인 클라우드 환경에서도 뛰어난 성능을 보여줍니다. 특히 다양한 엑스포터(exporter)를 통해 여러 CSP의 메트릭을 쉽게 수집할 수 있으며, 강력한 PromQL을 통해 복잡한 알림 규칙을 설정할 수 있습니다.
- 그라파나: 수집된 데이터를 시각화하는 도구로, 직관적이고 커스터마이즈 가능한 대시보드를 제공합니다. 다양한 데이터 소스를 지원하여 프로메테우스뿐만 아니라 CSP의 네이티브 모니터링 서비스와도 연동이 가능합니다. 또한, 알림 기능을 통해 다양한 채널로 신속하게 문제 상황을 전파할 수 있습니다.
1. Kubernetes 클러스터 준비
크라우드웍스는 기술 혁신과 서비스 품질 향상을 위해 다양한 오픈소스 기술을 적극적으로 도입하고 있습니다. 이러한 전략의 일환으로, 우리는 컨테이너 오케스트레이션 플랫폼인 Kubernetes를 핵심 인프라 기술로 선택하였습니다.
- 컨테이너의 배포, 확장, 업데이트를 자동화하여 운영 효율성을 높일 수 있습니다.
- 트래픽 변동에 따라 서비스를 자동으로 확장하거나 축소할 수 있어, 탄력적인 운영이 가능합니다.
- 하드웨어 자원을 효율적으로 활용하여 인프라 투자 대비 성능을 극대화할 수 있습니다.
- 시스템 장애 시 자동으로 복구하여 서비스의 안정성과 가용성을 높일 수 있습니다.
2. node_exporter 설치
github: https://github.com/prometheus/node_exporter
저희 팀은 호스트 시스템의 상세한 메트릭을 수집하기 위해 Node Exporter를 도입하기로 결정했습니다. Node Exporter는 CPU 사용률, 메모리 소비, 디스크 I/O, 네트워크 통계 등 시스템 수준의 중요한 정보를 제공합니다.
모니터링할 VM에 node_exporter를 설치합니다.
해당 agent는 기본적으로 TCP:9100 포트를 사용하고 있습니다.
# 설치위치
mkdir .prometheus
chmod 750 .prometheus
cd .prometheus
# node_exporter 설치
curl -OL https://github.com/prometheus/node_exporter/releases/download/v1.8.1/node_exporter-1.8.1.linux-amd64.tar.gz
tar xvfz node_exporter-1.8.1.linux-amd64.tar.gz
# systemctl service 등록
cat <<EOF | tee /etc/systemd/system/node_exporter.service
[Unit]
Description=Prometheus Node Exporter
Documentation=https://prometheus.io/docs/guides/node-exporter/
Wants=network-online.target
After=network-online.target
[Service]
User=root
Restart=on-failure
ExecStart=/home/user/.prometheus/node_exporter-1.8.1.linux-amd64/node_exporter
[Install]
WantedBy=multi-user.target
EOF
# 실행
systemctl daemon-reload
systemctl start node_exporter
systemctl enable node_exporter
systemctl status node_exporter
3. Prometheus 배포
Prometheus Docs: https://prometheus.io/
Helm Repo: https://artifacthub.io/packages/helm/prometheus-community/prometheus
Kubernetes 클러스터를 준비한 후, 우리의 다음 단계는 효과적인 모니터링 시스템을 구축하는 것이었습니다. 이를 위해 우리는 Prometheus를 선택했고, 설치 과정을 간소화하기 위해 Helm을 활용했습니다.
kubectl create namespace monitoring
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm -n monitoring upgrade --install grafana grafana/grafana -f values.yaml --version 8.2.2
values.yaml 을 통해 다음과 같은 설정을 하였습니다.
server:
# 데이터 scrape 주기, 타임아웃
global:
scrape_interval: 15s
scrape_timeout: 10s
# 데이터 보관기간
retention: "15d"
# ingress 노출을 위한 설정
service:
type: NodePort
# Ingress 설정
ingress:
enabled: true
annotations:
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80},{"HTTPS":443}]'
alb.ingress.kubernetes.io/network-type: private
alb.ingress.kubernetes.io/load-balancer-name: 'prometheus-alb'
alb.ingress.kubernetes.io/ssl-certificate-no: '{SSL_NUM}'
alb.ingress.kubernetes.io/healthcheck-path: '/-/healthy'
hosts:
- {Prometheus_URL}
path: /
pathType: Prefix
# Target 설정
extraScrapeConfigs: |
- job_name: 'dev'
static_configs:
- targets:
- 123.123.123.123:9100
labels:
node_name: 'dev1'
- targets:
- 234.234.234.234:9100
labels:
node_name: 'dev2'
Prometheus Target 카테고리에서 정상적으로 Agent와 통신되는지 알 수 있습니다.
4. Grafana 배포
Grafana Docs: https://grafana.com/docs/grafana/latest/
Helm Repo: https://artifacthub.io/packages/helm/grafana/grafana
Prometheus를 통해 메트릭 수집 기반을 마련한 후, 다음 단계로 우리는 이 데이터를 시각화하고 분석하기 위한 도구로 Grafana를 배포하도록 하겠습니다.
kubectl create namespace monitoring
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm -n monitoring upgrade --install grafana grafana/grafana -f values.yaml --version 8.2.2
values.yaml 을 통해 다음과 같은 설정을 하였습니다.
# 초기 Admin 계정
adminUser: admin
adminPassword: "P@assword"
# 재사용을 위해 Prometheus Datasource 지정
datasources:
datasources.yaml:
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
url: http://prometheus-server.monitoring.svc.cluster.local
access: proxy
isDefault: true
# Ingress 설정
ingress:
enabled: true
annotations:
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80},{"HTTPS":443}]'
alb.ingress.kubernetes.io/network-type: private
alb.ingress.kubernetes.io/load-balancer-name: 'grafana-alb'
alb.ingress.kubernetes.io/ssl-certificate-no: '{SSL_NUM}'
alb.ingress.kubernetes.io/healthcheck-path: '/api/health'
hosts:
- {Grafana_URL}
path: /
pathType: Prefix
5. Dashboard 구성
Prometheus와 Grafana를 설치한 후, 다음 중요한 단계는 효과적인 대시보드를 구성하는 것입니다. 잘 설계된 대시보드는 시스템의 상태를 한눈에 파악할 수 있게 해주며, 문제 발생 시 신속한 대응을 가능하게 합니다.
Grafana Labs 에서 Dashboard를 공유하는 공간(https://grafana.com/grafana/dashboards/)이 있으니 마음에 드는 Dashboard를 찾아 Import하는 방법도 있습니다.
아래 두 스크린샷은 Dashboard는 Import 하는 예시입니다.
저희 팀은 CPU, Memory, Disk, VM Status를 한눈에 확인하기 위해 직접 구축하였습니다.
각 항목에 대한 쿼리는 다음과 같으니 구축하실때 도움되시길 바랍니다.
# CPU
(1 - avg(rate(node_cpu_seconds_total{job=~"$job",mode="idle"}[$__rate_interval])) by (instance)) * 100
# Memory
(1 - (node_memory_MemAvailable_bytes{job=~"$job"} / (node_memory_MemTotal_bytes{job=~"$job"}))) * 100
# Root Disk
100 - (
sum(node_filesystem_avail_bytes{job=~"all|$job", mountpoint="/"}) by (instance) /
sum(node_filesystem_size_bytes{job=~"all|$job", mountpoint="/"}) by (instance) * 100
)
# Mount Disk
100 - (
sum(node_filesystem_avail_bytes{job=~"all|$job", mountpoint!="/"}) by (instance) /
sum(node_filesystem_size_bytes{job=~"all|$job", mountpoint!="/"}) by (instance) * 100
)
# VM Status
up{job=~"all|$job"}
6. Alert 설정
모니터링 시스템의 핵심 기능 중 하나는 문제 상황을 신속하게 감지하고 관련 팀에 알리는 것입니다. 이를 위해 Grafana의 Alert 기능을 이용하여 Rule을 설정하고 설정값 이상일 시 Google Chat으로 알람이 가도록 설정하였습니다.
먼저 Google Chat Space에서 웹훅을 생성 후 링크를 복사합니다.
이후 Grafana Alerting → Contact Points 에서 해당 웹훅을 설정합니다.
- URL에 복사한 웹훅URL 설정
Grafana Alerting → Alert rules 설정에서 Rule을 생성합니다.
A 단계에 쿼리를 넣어주시고 Run Queries 를 실행하여 정상적으로 수치를 보여지는지 확인합니다.
C 단계에서 내부정책에 맞게 수치를 설정합니다.
이렇게 구축을 하게 되면 CPU 가 85이상 증가할 시 GoogleChat으로 알람을 확인 할 수 있었습니다.
마치며
이렇게 구축한 모니터링 시스템을 통해 우리는 다음과 같은 이점을 얻을 수 있었습니다.
- 다중 클라우드 환경에 대한 통합적인 가시성 확보
- 실시간 성능 모니터링 및 이상 징후 조기 감지
- 자동화된 알람 시스템을 통한 신속한 대응
- 리소스 사용 최적화 및 비용 절감
앞으로도 이 시스템을 지속적으로 개선하고, 새로운 기술과 도구를 도입하여 더욱 효과적인 모니터링 체계를 구축해 나갈 예정입니다. 여러분의 조직에서도 이러한 접근 방식이 도움이 되기를 바랍니다.