Infra
모니터링 통합 및 K8s Storage Class

모니터링 통합 및 K8s Storage Class

소유자: Rob

목차

  • 프로메테우스와 그라파나를 이용한 기존 모니터링 시스템의 중앙화
  • 온프레미스 환경에서의 쿠버네티스 PVC 사용량 확인을 위한 Storage Class 연구

시스템 모니터링을 어떻게 할까?

  • 각 시스템들이 돌아가고 있는 환경들에 대한 모니터링 필요
  • 리소스를 얼마나 사용하고 있는지, 장애는 없는지..

Prometheus

image.png

  • 메트릭 데이터를 수집하고 보여주는 오픈소스 모니터링 도구
  • 앱에서 특정 엔드포인트에 메트릭 데이터를 노출하고, 프로메테우스가 긁어가서 시계열 DB에 저장
    • 시스템 메트릭 데이터 제공 앱으로 Node Exporter, Kube State Metrics, cAdvisor 사용

Grafana

Screenshot from 2025-03-09 22-32-13.png

image.png

  • 프로메테우스로부터 지정한 쿼리를 이용하여 데이터를 가져와 대시보드에 시각화
  • 다양한 형태로 대시보드 구성 가능

Alertmanager

image.png

  • 프로메테우스에 alertmanager를 연결해놓을 수 있음
  • 특정 조건이 되면 지정한 방식으로 알람 발생

Prometheus Operator

image.png

  • 쿠버네티스 환경에서 프로메테우스를 이용하기 쉽게끔 설정, 권한 등에 대한 관리
  • 이 4가지 구성요소들을 kube-prometheus-stack으로 묶어서 helm으로 제공

기존 모니터링 방식

  • dev, release, onpremise 환경에 각각의 모니터링 환경 구축
    • 환경마다 kube-prometheus-stack을 설치
    • prometheus, grafana, alertmanager, operator가 환경 수만큼 설치..
    • 관리 포인트와 비용 모두 점점 증가

어떻게 해결해볼 수 있을까?

image.png

  • Prometheus Agent 모드를 통해 메트릭 데이터를 온프레미스로 집중

    • dev, release에서 메트릭 데이터를 라벨링 해서 온프레미스로 전송
    node_cpu_seconds_total{cpu="0", env="dev", instance="ip-10-0-103-83.ap-northeast-2.compute.internal", job="node-exporter", mode="idle"}
    • Grafana, Alertmanager는 온프레미스에만 설치

마주했던 문제

  • 온프레미스에서는 kube-prometheus-stack을 이용하여 프로메테우스 서버를 띄우려고 했으나, kube-prometheus-stack의 데이터 라벨링 및 메트릭 수집처 추가가 쉽지 않아 구성요소들(prometheus, grafana, alertmanager, node exporter, kube state metrics)을 직접 띄우는 방식으로 해결

효과

previous-release-prometheus-ram-usage.png

now-release-prometheus-ram-usage.png

  • 메모리 사용량 약 64.3% 감소
  • 관리 포인트 감소로 인한 효율성 증가
    • Grafana, Alertmanager 항목 추가 시 온프레미스에서만 작업
    • 모니터링 환경이 늘어나도 agent 연결만 설정해놓으면 모니터링 가능

온프레미스 환경에서 PVC 사용량 추적 불가

Screenshot from 2025-03-09 23-17-50.png

PVC?

image.png

  • pod에서 volume을 사용하기 위해 특정 용량을 쿠버네티스에 요청 (PVC)
  • 쿠버네티스에서는 요청에 알맞는 volume을 pod에 제공 (PV)
    • 정적 프로비저닝: 미리 PV들을 생성해놓음
    • 동적 프로비저닝: 요청이 들어올 때마다 맞춰서 PV 생성
  • PVC 사용량이란 요청한 전체 PVC 용량 중 실제로 사용한 양이 얼마인지

Grafana에서 PVC 사용량 추적이 불가한 이유

  • 프로메테우스에서 해당 메트릭을 수집하지 않기 때문 (너무 당연한 소리)
    • kubelet_volume_stats_used_bytes
    • kubelet_volume_stats_capacity_bytes
  • Microk8s에서 storage class를 따로 지정하지 않을 경우 hostpath로 설정되는데, 이건 cAdvisor에 PVC 관련 API를 제공하지 않음

Storage Class?

  • 스토리지에 대한 여러가지 관리 자동화
    • 볼륨의 타입(HDD, SSD, NFS 등)에 따른 리소스 관리
    • 프로비저닝, 삭제, 재사용 등의 작업
  • 쿠버네티스는 기본적으로 분산 클라우드 환경을 상정하기에 이런 매니징이 필수

왜 dev, release는 되고 온프레미스는 안되는가

  • dev, release는 AWS EKS를 통해 운영 중
  • EKS는 기본적으로 Storage Class로 ebs-sc, efs-sc를 사용하기에 cAdvisor에서 PVC 관련 메트릭 수집 가능
  • 온프레미스에서 사용 중인 Microk8s의 default storage class인 hostpath는 cAdvisor에 PVC 관련 API를 제공하지 않음

그럼 Microk8s에 다른 Storage Class를 적용해보자

  • OpenEBS
  • Longhorn
  • Ceph
  • SeaweedFS

OpenEBS 적용 시도

  • 많이 쓰이고 커뮤니티도 활발함
  • 다양한 엔진 제공
    • openebs-hostpath, jiva, cStor, mayastor, …
    • 일단 openebs-hostpath를 이용해서 진행
    설치 스크립트 (opens in a new tab)

OpenEBS hostpath 테스트 결과

Screenshot from 2025-03-09 15-17-50.png

Screenshot from 2025-03-09 15-18-43.png

  • MySQL과 Redis를 배포해서 PVC 사용량 확인
  • 약간의 차이는 있으나 사실상 동일한 수준의 사용량이 나타남 → ???

상세 확인

$ microk8s kubectl exec -it my-mysql-0 -n mysql -- df -h               
Defaulted container "mysql" out of: mysql, preserve-logs-symlinks (init)
Filesystem                         Size  Used Avail Use% Mounted on
overlay                            455G  127G  305G  30% /
tmpfs                               64M     0   64M   0% /dev
/dev/mapper/ubuntu--vg-ubuntu--lv  455G  127G  305G  30% /tmp
shm                                 64M     0   64M   0% /dev/shm
tmpfs                              768M  8.0K  768M   1% /opt/bitnami/mysql/secrets
tmpfs                              5.4G     0  5.4G   0% /proc/asound
tmpfs                              5.4G     0  5.4G   0% /proc/acpi
tmpfs                              5.4G     0  5.4G   0% /proc/scsi
tmpfs                              5.4G     0  5.4G   0% /sys/firmware
tmpfs                              5.4G     0  5.4G   0% /sys/devices/virtual/powercap
 
$ microk8s kubectl exec -it redis-master-0 -n redis -- df -h
Filesystem                         Size  Used Avail Use% Mounted on
overlay                            455G  127G  305G  30% /
tmpfs                               64M     0   64M   0% /dev
/dev/mapper/ubuntu--vg-ubuntu--lv  455G  127G  305G  30% /data
shm                                 64M     0   64M   0% /dev/shm
tmpfs                              192M  4.0K  192M   1% /opt/bitnami/redis/secrets
tmpfs                              5.4G     0  5.4G   0% /proc/asound
tmpfs                              5.4G     0  5.4G   0% /proc/acpi
tmpfs                              5.4G     0  5.4G   0% /proc/scsi
tmpfs                              5.4G     0  5.4G   0% /sys/firmware
tmpfs                              5.4G     0  5.4G   0% /sys/devices/virtual/powercap

image.png

[쿠버네티스] hostPath 볼륨 (opens in a new tab)

hostPath 볼륨파드가 동작하는 쿠버네티스 클러스터의 노드(host)의 로컬 파일시스템의 파일 및 디렉토리를 파드가 사용할 수 있는 볼륨으로 제공해줍니다.

Block Storage vs File Storage

image.png

  • 블록 스토리지는 데이터를 아주 작은 블록 단위로 나누어서 저장하고, 블록들을 합쳐서 데이터 제공
  • 파일 스토리지는 특정 경로에 데이터를 저장하는 전통적인 방식
  • hostpath와 같은 파일 스토리지 storageclass가 적용되면 k8s에서는 디스크 전체를 볼륨으로 마운트

📌 HostPath에서 PVC 크기가 전체 볼륨 크기와 동일하게 나오는 이유

hostPath를 사용하면 PVC에서 요청한 크기와 관계없이 실제 PV의 크기가 호스트 파일 시스템의 전체 공간을 나타내는 것은 정상적인 동작입니다. 이유는 hostPath는 단순히 호스트 노드의 특정 디렉토리를 마운트하는 방식이기 때문입니다.

  • hostPath실제 스토리지 프로비저너가 없으며, 단순히 호스트의 특정 경로를 마운트하는 역할만 수행합니다.
  • 따라서 PVC에서 요청한 크기와 상관없이 전체 볼륨 크기가 노출되는 현상이 발생합니다.
  • PVC에서 storage: 10Gi를 요청해도, df -h로 보면 전체 디스크 크기가 나타나는 이유입니다.
  • 블록 스토리지 storageclass 시도 필요

Longhorn 적용 시도

https://github.com/longhorn/longhorn (opens in a new tab)

Longhorn (opens in a new tab)

  • 쉬운 설치, 고가용성, 오픈소스
  • 자체 모니터링 환경 제공
  • 매우 활발한 커뮤니티

Longhorn 적용 결과

설치 스크립트 (opens in a new tab)

제대로 된 PVC 사용량 확인 가능

  • grafana

Screenshot from 2025-03-11 21-56-13.png

  • kubelet_volume_stats_used_bytes

스크린샷 2025-03-11 09.44.34.png

  • 백분율

스크린샷 2025-03-11 09.44.16.png

Longhorn 자체 제공 모니터링 UI

$ microk8s kubectl get svc -n longhorn-system
 
NAME                          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
longhorn-admission-webhook    ClusterIP   10.152.183.239   <none>        9502/TCP   20m
longhorn-backend              ClusterIP   10.152.183.158   <none>        9500/TCP   20m
longhorn-conversion-webhook   ClusterIP   10.152.183.18    <none>        9501/TCP   20m
**longhorn-frontend             ClusterIP   10.152.183.183   <none>        80/TCP     20m**
longhorn-recovery-backend     ClusterIP   10.152.183.33    <none>        9503/TCP   20m
 
$ microk8s kubectl port-forward svc/longhorn-frontend 8080:80 -n longhorn-system

스크린샷 2025-03-11 09.50.09.png

스크린샷 2025-03-11 10.07.22.png

결론

  • prometheus agent와 longhorn을 이용하여 k8s에서의 보다 효율적인 모니터링 구축 및 테스트
  • 온프레미스 싱글노드 microk8s라는 환경에 longhorn이 적합한지 추가적 확인 필요
  • 추후 실제 k8s 환경에 적용