K8S Monitoring 교육 자료

목차

참고 자료

Prometheus

주요개념

Metrics: Prometheus에서 데이터를 수집하는 기본 단위입니다. 각 메트릭은 특정한 이름과 레이블 세트를 가지며, 시간에 따른 값의 변화를 기록합니다.

Labels: 메트릭을 구분하고 쿼리할 때 사용하는 키-값 쌍입니다. 예를 들어, 서버의 메트릭을 수집할 때 ‘서버의 위치’, ‘서버의 이름’ 등을 레이블로 사용할 수 있습니다.

Time Series: 동일한 메트릭 이름과 레이블 세트를 가진 데이터 포인트의 시퀀스입니다. Prometheus는 이 타임 시리즈 데이터를 사용하여 시간 경과에 따른 메트릭의 변화를 추적합니다.

Query: Prometheus는 자체 쿼리 언어인 PromQL을 사용하여 저장된 데이터를 검색하고 계산할 수 있습니다. 이를 통해 사용자는 복잡한 쿼리를 작성하여 메트릭 데이터에서 유용한 정보를 추출할 수 있습니다.

Alerts: Prometheus는 정의된 조건에 따라 알림을 발생시킬 수 있습니다. 사용자는 규칙을 설정하여 특정 메트릭이 주어진 임계값을 초과하거나 특정 상태에 도달했을 때 알림을 받을 수 있습니다.

Exporters: Prometheus는 다양한 시스템과 서비스로부터 메트릭을 수집하기 위해 Exporter라는 에이전트를 사용합니다. 각 Exporter는 특정 서비스나 시스템에 대한 메트릭을 수집하여 Prometheus가 이해할 수 있는 형식으로 변환합니다.

Scraping: Prometheus 서버는 설정된 간격으로 Exporter나 수집 대상 시스템에 HTTP 요청을 보내어 메트릭을 “스크레이핑”합니다. 이 과정을 통해 Prometheus는 정기적으로 메트릭 데이터를 수집하고 저장합니다.

Storage: Prometheus는 수집된 데이터를 로컬 스토리지에 시계열 데이터베이스 형식으로 저장합니다. 이 데이터는 후에 쿼리, 시각화 및 알림 생성을 위해 사용됩니다.

Metric의 종류

Prometheus에서 사용하는 메트릭 종류는 주로 네 가지로 분류됩니다. 각각의 메트릭 유형은 서로 다른 유형의 정보를 모니터링하고 측정하는 데 사용됩니다:

Counter:

  • 카운터는 단순히 증가만 하는 메트릭으로, 주로 요청 수, 완료된 작업 수, 에러 발생 수 등을 측정하는 데 사용됩니다.

  • 카운터 값은 절대 감소하지 않으며 (재시작 등의 경우를 제외하고), 주로 누적 값을 관찰하는 데 사용됩니다.

Gauge:

  • 게이지는 특정 시점에서의 값을 측정하는 메트릭으로, 값이 증가하거나 감소할 수 있습니다.

  • 메모리 사용량, 현재 활성 세션 수, 온도 등 현재 상태를 나타내는 값을 모니터링하는 데 주로 사용됩니다.

Histogram:

  • 히스토그램은 샘플을 관찰하고 이를 구성된 버킷에 분류하여, 샘플들의 분포를 관찰할 수 있게 해줍니다.

  • 주로 응답 시간, 요청 크기 등을 측정하는 데 사용되며, 각 버킷은 특정 범위의 값을 나타냅니다.

  • 히스토그램은 측정 값의 총합과 버킷 별 누적 카운트를 제공합니다.

Summary:

  • 서머리도 샘플의 분포를 측정하는 데 사용되지만, 히스토그램과는 다르게 특정 분위수(quantiles)의 관찰 값을 제공합니다.

  • 응답 시간의 90번째 백분위수 같은 지표를 계산할 때 유용합니다.

  • 서머리는 관측된 값의 총합과 카운트, 그리고 설정된 분위수에 따른 값을 제공합니다.

이러한 메트릭 유형들은 각기 다른 모니터링 목적에 따라 선택하여 사용될 수 있으며, Prometheus의 유연성과 강력한 데이터 수집 및 쿼리 능력의 기반이 됩니다.

Exporter의 종류

  • Node Exporter

  • Client Library

  • DCGM

Jobs and Instances

Jobs:

  • Job은 Prometheus가 수집하는 메트릭들의 한 그룹을 의미합니다. 일반적으로 job은 동일한 유형의 여러 인스턴스에서 메트릭을 수집할 때 사용되는 레이블입니다.

  • 예를 들어, 여러 서버에서 실행 중인 동일한 애플리케이션의 메트릭을 수집하는 경우, 이러한 서버 그룹 전체를 나타내기 위해 “job” 레이블을 사용할 수 있습니다. 모든 서버가 “api-server”라는 job에 속할 수 있으며, Prometheus는 이 job으로부터 메트릭을 수집합니다.

  • Job은 Prometheus 설정에서 정의됩니다. 이를 통해 Prometheus는 어떤 엔드포인트에서 메트릭을 수집해야 하는지, 그리고 해당 메트릭을 어떤 job 이름으로 그룹화할지를 알게 됩니다.

Instances:

  • Instance는 job 내에서 개별적으로 메트릭을 수집하는 대상을 의미합니다. 보통은 하나의 애플리케이션 인스턴스나 하나의 서버를 가리킵니다.

  • 예를 들어, “api-server” job이 여러 서버에서 실행 중이라면, 각 서버는 “api-server” job의 별도 인스턴스로 간주됩니다. - Prometheus는 각 인스턴스에서 메트릭을 독립적으로 수집하고, 이 메트릭들을 인스턴스 레이블로 구분합니다. Instance는 일반적으로 호스트명과 포트 번호를 포함하는데, 이는 Prometheus가 메트릭을 수집할 정확한 위치를 나타냅니다

PromQL

https://prometheus.io/docs/prometheus/latest/querying/basics/

Prometheus Operator

정의

Prometheus Operator는 Kubernetes 클러스터 내에서 Prometheus를 보다 쉽게 배포하고 관리할 수 있도록 설계된 도구입니다. Kubernetes 리소스와 밀접하게 통합되어 있으며, Kubernetes API를 확장하여 Prometheus 설정을 자동화하고 간소화합니다. 다음은 Prometheus Operator의 주요 개념들입니다:

Custom Resource Definitions (CRDs):

  • Prometheus Operator는 Custom Resource Definitions (CRDs)를 사용하여 Prometheus 관련 설정을 Kubernetes 네이티브 리소스처럼 관리할 수 있게 합니다. 이를 통해 사용자는 Kubernetes 리소스를 정의하고 조작하는 방식으로 Prometheus 인스턴스, Alertmanager, 서비스 모니터링 등을 구성할 수 있습니다.

Prometheus Custom Resource:

  • Prometheus 리소스는 클러스터 내에서 실행할 Prometheus 인스턴스를 정의합니다. 사용자는 이 리소스를 통해 Prometheus 서버의 버전, 설정, 스토리지 요구사항 등을 지정할 수 있습니다.

ServiceMonitor:

  • ServiceMonitor 리소스는 Prometheus가 모니터링할 서비스를 발견하고 설정하는 방법을 정의합니다. 이는 서비스의 레이블을 기반으로 하며, Prometheus가 어떤 서비스를 스크래핑할지, 어떤 엔드포인트와 포트를 사용할지 등을 지정합니다.

Alertmanager Custom Resource:

  • Alertmanager 리소스를 통해 클러스터 내에서 실행되는 Alertmanager 인스턴스를 구성할 수 있습니다. 이를 통해 Prometheus로부터의 알림을 관리하고, 알림의 라우팅, 그룹화, 중복 제거, 발송 방법 등을 설정할 수 있습니다.

PrometheusRule:

  • PrometheusRule 리소스는 알림 규칙과 레코딩 규칙을 정의합니다. 이 리소스를 통해 사용자는 Prometheus 쿼리 언어(PromQL)를 사용하여 메트릭에 기반한 알림 규칙과 새로운 타임 시리즈 데이터를 생성하는 규칙을 설정할 수 있습니다.

Operator Pattern:

  • Prometheus Operator는 Kubernetes의 Operator 패턴을 따릅니다. 이는 복잡한 애플리케이션을 Kubernetes 상에서 운영하는 논리를 코드로 구현한 것으로, 사용자가 애플리케이션을 보다 쉽게 배포하고 관리할 수 있게 해줍니다.

Grafana

Grafana는 강력한 시각화 및 분석 플랫폼으로, 다양한 데이터 소스에서 데이터를 수집하여 인터랙티브한 대시보드 형태로 시각화합니다. 사용자는 Grafana를 사용하여 데이터를 쉽게 조회, 모니터링 및 분석할 수 있습니다. 다음은 Grafana의 주요 개념들입니다:

Dashboards:

  • 대시보드는 여러 위젯 또는 패널을 통해 시각화된 데이터의 모음입니다. 사용자는 대시보드를 통해 다양한 데이터 소스로부터의 정보를 한눈에 볼 수 있습니다.

  • 각 대시보드는 특정 목적이나 관점을 반영하여 구성될 수 있으며, 사용자는 필요에 따라 여러 대시보드를 생성하고 관리할 수 있습니다.

Panels:

  • 패널은 대시보드 내에서 개별적인 차트, 그래프, 테이블 등의 시각화를 보여주는 컴포넌트입니다. 각 패널은 특정 쿼리에 기반하여 데이터를 시각화하며, 다양한 시각화 유형(예: 그래프, 히트맵, 가이지 등)을 지원합니다.

Data Sources:

  • Grafana는 다양한 데이터 소스와 연동될 수 있습니다. Prometheus, InfluxDB, Elasticsearch, MySQL, PostgreSQL 등 다양한 데이터베이스 및 모니터링 툴과의 연동이 지원됩니다.

  • 사용자는 Grafana에 데이터 소스를 추가하고, 해당 데이터 소스에서 데이터를 조회하여 대시보드를 생성할 수 있습니다.

Query:

  • 패널 내에서 데이터를 시각화하기 위해, Grafana는 데이터 소스에 쿼리를 실행합니다. 이 쿼리는 사용자가 정의하며, 대시보드에 표시할 데이터를 결정합니다.

Alerts:

  • Grafana는 데이터 포인트가 사전 정의된 임계값을 초과할 때 알림을 발송하는 기능을 제공합니다. 이를 통해 사용자는 시스템의 문제점을 신속하게 인지하고 대응할 수 있습니다.

Plugins:

  • Grafana는 다양한 플러그인을 지원하여 기능을 확장할 수 있습니다. 데이터 소스 플러그인, 패널 플러그인, 앱 플러그인 등을 설치하여 Grafana의 기능을 확장하고 사용자 정의화할 수 있습니다.

사용자 및 권한 관리:

  • Grafana는 사용자 계정 관리, 사용자 그룹 및 역할 기반의 액세스 컨트롤을 지원합니다. 이를 통해 대시보드, 패널 및 데이터 소스에 대한 세밀한 접근 제어가 가능합니다.

  • Grafana는 이러한 개념들을 통해 복잡한 데이터를 쉽게 시각화하고, 효율적인 데이터 분석 및 모니터링을 가능하게 합니다.

k8s 클러스터 요약 Dashboard 설명

클러스터 요약

Panel 이름 설명
정상 노드 수 상태가 Ready인 노드 수
비정상 노드 수 상태가 Ready가 아닌 노드 수
생성가능한 파드 대비 배포수 생성가능한 파드 대비 현재배포된 파드 수
클러스터 파드 Capacity 생성가능한 파드수
CPU 토탈 코어 대비 요청량 requested/total
클러스터 CPU Capacity 클러스터 총 CPU 코어
메모리 토탈 코어 대비 요청량 requested/total
클러스터 메모리 Capacity 클러스터 총 메모리 용량
GPU 토탈 코어 대비 요청량 requested/total
클러스터 GPU Capacity 클러스터 총 GPU 갯수

노드 요약 정보 테이블

Column 이름 설명
ip 노드 아이피 주소
hostname 노드 호스트 이름
uptime 마지막 부팅 이후 경과 시간
memory 노드 총 메모리
CPU Cores 최근 5분간 CPU 시스템에서 쓴 사용량
5m load 최근 5분간 CPU 전체 사용량
Memory used 메모리 사용량
Partition used 디스크 사용량
Disk read 초당 평균 디스크에서 읽은 데이터 용량
Disk write 초당 평균 디스크에 쓴 데이터 용량
CurrEstab 연결되어 있는 TCP connection 수
TCP-tw 종료된 TCP connection 수
Download* 초당 평균 다운로드 트래픽
Upload* 초당 평균 업로드 트래픽

노드별 상세 정보

Panel 이름 설명
Uptime 마지막 부팅 이후 경과 시간
CPU Cores 총 CPU 코어 개수
Total RAM 총 메모리 용량
CPU Busy CPU 사용량
Usage RAM 메모리 사용량
Used Max Mount 가장 큰 파티션 기준 디스크 사용량
Used SWAP 스왑 메모리 사용량

Disk Space Used Basic

Column 이름

설명

Device

디바이스 이름

Filesystem

파일시스템 형식

Mounted on

파일 시스템상 마운트된 위치

Size

디스크 크기

Avail

남은 용량

Used

사용량

Panel 이름 설명
Internet traffic per hour All nic별 네트워크 트래픽/시간
CPU% Basic 모드(user,system,io, total)별 CPU 사용량
Memory Basic 메모리 사용량(free, used, total)
Network bandwidth usage per second All nic별 네트워크 bandwidth
System Load 1m, 5m, 15m 단위 시스템 로드(cpu 사용량)
Disk R/W Data 디스크에 읽고/쓴 데이터 bytes
Disk Space Used% Basic 디스크 사용량
Disk IOps Completed 디스크 io 횟수/초
Time Spent Doing I/Os 디스크의 io에 소요한 시간
Disk R/W Time io별 소요 시간

Network Sockstat

항목 이름

설명

TCP-tw

종료된 TCP connection 수

CurrEstab

연결되어 있는 TCP connection 수

TCP_inuse

사용중인 TCP socket 수

UDP_inuse

사용중인 UDP socket 수

TCP_alloc

alloc 상태인 TCP socket 수

TCP_passive_opens

해당 노드에서 listen 중인 포트에 연결하여 열린 TCP socket

TCP_active_opens

해당 노드로 부터 시작되어 열린 TCP socket

TCP_inSegs

수신한 TCP segment 수

TCP_retransSegs

재전송한 TCP segment 수

TCP_outSegs

송신한 TCP segment 수

Open FIle Descriptor/Context switches

항목 이름

설명

file descriptor

할당된 file descriptor 수

context switches

이뤄진 context switch 수

Custom Metric을 이용한 Application 모니토링(예제)

Server.go

package main

import (
	"fmt"
	"net/http"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
)

var pingCounter = prometheus.NewCounter(
	prometheus.CounterOpts{
		Name: "ping_request_count",
		Help: "No of request handled by Ping handler",
	},
)

func ping(w http.ResponseWriter, req *http.Request) {
	pingCounter.Inc()
	fmt.Fprintf(w, "pong")
}

func main() {
	prometheus.MustRegister(pingCounter)

	http.HandleFunc("/ping", ping)
	http.Handle("/metrics", promhttp.Handler())
	http.ListenAndServe(":8090", nil)
}

Dockerfile

FROM golang:1.22.1-alpine AS build
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN GOARCH=amd64 go build -o server .

FROM alpine:latest
WORKDIR /app
COPY --from=build /app/server .
EXPOSE 8090
CMD ["./server"]

Deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prom-example
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prom-example
      release: qks-monitoring
  template:
    metadata:
      labels:
        app: prom-example
        release: qks-monitoring
    spec:
      containers:
      - name: mymetric
        image: registry.smg.quantumcns.io/qms/prom_example:v0.2
        ports:
        - name: metrics
          containerPort: 8090

Service.yaml

apiVersion: v1
kind: Service
metadata:
  name: prom-example
  labels:
    app: prom-example
    release: qks-monitoring
spec:
  selector:
    app: prom-example  
    release: qks-monitoring
  ports:
    - name: metrics
      protocol: TCP
      port: 8090   
      targetPort: metrics
  type: ClusterIP

ServiceMonitor.yaml

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  annotations:
  labels:
    app: prom-example
    release: qks-monitoring
  name: prom-example
spec:
  endpoints:
  - path: /metrics
    port: metrics
    interval: 15s
  namespaceSelector:
    matchNames:
    - qks-monitoring
  selector:
    matchLabels:
      app: prom-example
      release: qks-monitoring

alertmanagerconfig.yaml

apiVersion: monitoring.coreos.com/v1alpha1
kind: AlertmanagerConfig
metadata:
  name: config-example
  labels:
    alertmanagerConfig: example
spec:
  route:
    groupBy: ['job']
    groupWait: 30s
    groupInterval: 5m
    repeatInterval: 12h
    receiver: 'webhook'
  receivers:
  - name: 'webhook'
    webhookConfigs:
    - url: https://webhook.site/6016d666-7cc1-4f81-bb8f-442ef2a9a400
      send_resolved: false

prometheusrule.yaml

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  creationTimestamp: null
  labels:
    release: qks-monitoring
    prometheus: example
    role: alert-rules
  name: prometheus-example-rules
spec:
  groups:
  - name: Count greater than 5
    rules:
    - alert: CountGreaterThan5
      expr: ping_request_count > 5
      for: 10s