시작하며

쿠버네티스는 자체적으로 모니터링 기능을 제공하지 않지만 몇 가지 애드온 기능을 제공한다. CAdvisor와 같은 컨테이너 모니터링 에이전트들은 /metrics 경로를 외부에 노출시켜 메트릭 데이터를 오픈하고, 이 경로를 프로메테우스에게 미리 알려주면 자동으로 수집하는 형식이다.

모니터링 메트릭 계층

step 1) 인프라 수준의 메트릭 : 호스트 레벨에서의 메트릭.
                          파일 디스크립터 개수, 디스크 사용량, 호스트 NIC의 패킷 전송량
 
step 2) 컨테이너 수준의 메트릭 : 컨테이너 레벨에서의 메트릭.
                            컨테이너별 CPU와 메모리 사용량, 컨테이너 프로세스 상태,
                            컨테이너에 할당된 리소스 할당량, 포트 상태
 
step 3) 애플리케이션 수준의 메트릭 : 애플리케이션 레벨에서의 메트릭.
                              마이크로서비스에서 발생하는 트레이싱(tracing) 데이터,
                              애플리케이션 로직에 종속적인 데이터,
                              서버 프레임워크에서 제공하는 모니터링 데이터

모니터링 애드온

1. metrics-server

kubectl top과 같은 명령어를 사용하려면 클러스터 내부의 메트릭을 모아서 제공하는 별도의 컴포넌트가 필요하다. metrics-server가 바로 그 역할을 담당한다.

metrics-server의 동작 원리: APIService 리소스

쿠버네티스의 노드 에이전트인 kubelet은 CAdvisor를 자체적으로 내장하고 있으며, Pod와 노드 메트릭을 반환하는 /stats/summary 엔드포인트를 제공한다. 이 메트릭을 가져오기 위한 권한을 ClusterRole로 정의해서 서비스어카운트에 연결하고, 이 토큰을 기반으로 메트릭을 수집한다. 이 과정에서 metrics-server는 API 서버의 역할 일부를 담당하며, 쿠버네티스에 APIService로 등록되어 있다.

APIService 리소스는 “새로운 API를 확장해 사용하기 위해서는 어떤 서비스에 접근해야 하는가”를 정의한다. 이런 API 확장 방식을 쿠버네티스에서는 API Aggregation이라고 한다.

1) APIService 리소스를 통해 metrics-server를 확장한 API 서버로 등록
2) 쿠버네티스 API 서버에 metrics.k8s.io API 요청을 전송
3) API Aggregation Layer에 의해 metrics-server로부터 제공되므로
   k8s API 서버는 해당 요청을 metrics-server로 전달
4) 응답 반환

2. kube-state-metrics

쿠버네티스 리소스 상태에 관련된 메트릭을 제공하는 애드온이다. Pod의 상태, Deployment 레플리카 개수 등을 모니터링할 수 있다.

3. node-exporter

인프라 수준에서의 메트릭을 제공한다. 파일 시스템, 네트워크 패킷 등 호스트 측면의 메트릭을 수집한다.

Prometheus & Grafana

모니터링 메트릭을 제공하는 애드온을 설치하고 나면, 이를 수집하는 Prometheus를 설치할 차례이다. 설치 방법은 1) 프로메테우스 도커 이미지를 사용, 2) 프로메테우스 Operator와 커스텀 리소스를 사용, 3) 바이너리를 직접 실행 등 다양하게 존재한다.

Prometheus

프로메테우스 오퍼레이터는 깃헙 저장소에서 yaml 파일을 제공한다. CRD 역시 함께 생성된다. 이후 아래와 같이 prometheus라는 이름의 커스텀 리소스를 생성해서 프로메테우스를 배포한다. 이때 권한 문제를 위해 서비스 어카운트를 생성하고, 권한을 부여하고, 해당 서비스 어카운트를 프로메테우스 포드가 사용할 수 있도록 설정해야 한다.

apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  name: prometheus
  namespace: default
spec:
  replicas: 1
  serviceMonitorNamespaceSelector: {}
  serviceMonitorSelector: {}
  serviceAccountName: {생성해준 prometheus 서비스 어카운트 이름}

kubectl port-forward와 같은 명령어를 사용하면 외부로 노출되지 않는 서비스에 임시로 접근할 수 있는 포트 포워딩을 생성할 수 있다. 이를 통해 로컬에서 프로메테우스 web-ui를 확인할 수 있다.

프로메테우스로 메트릭을 수집하기 위해서는 메트릭을 가져올 수 있는 엔드포인트를 프로메테우스에게 알려주어야 한다. ServiceMonitor라는 커스텀 리소스를 사용하면 프로메테우스 프로세스를 리로드하지 않아도 자동으로 적용된다.

1. ServiceMonitor 커스텀 리소스 생성
   (matchLabels에 node-exporter가 설정되어 있는 yaml 파일 적용)
 
2. 프로메테우스 web-ui에서 상단 Status > Configuration > prometheus.yml 파일에서
   scrape_configs 확인

Grafana

별도의 설정 없이 도커 허브의 그라파나 이미지만 사용하면 손쉽게 설치할 수 있다.

# 예시
 
1) 프로메테우스를 데이터 소스로 등록
   Configuration > Datasource > Add datasource > Prometheus
 
2) 그라파나 대쉬보드 생성
   그라파나 사이트에서 대쉬보드 선택 > 그라파나 화면 왼쪽 Dashboards > Manage >
   대쉬보드 ID Import > Datasource는 1번 프로메테우스 데이터소스 선택

정리하며

쿠버네티스 모니터링은 metrics-server, kube-state-metrics, node-exporter로 메트릭을 수집하고, Prometheus로 이를 집계하며, Grafana로 시각화하는 구조로 이루어진다. 특히 metrics-server는 API Aggregation 방식으로 쿠버네티스 API에 통합되어 kubectl top 명령어 등을 지원하며, Prometheus Operator는 CRD 기반으로 모니터링 설정을 선언적으로 관리할 수 있게 해준다.