쿠버네티스에서 Application을 모니터링하기
이 글의 목차
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 BusyCPU 사용량Usage RAM메모리 사용량Used Max Mount가장 큰 파티션 기준 디스크 사용량Used SWAP스왑 메모리 사용량
Disk Space Used Basic
Column 이름설명Device디바이스 이름Filesystem파일시스템 형식Mounted on파일 시스템상 마운트된 위치Size디스크 크기Avail남은 용량Used사용량
Panel 이름설명Internet traffic per hour Allnic별 네트워크 트래픽/시간CPU% Basic모드(user,system,io, total)별 CPU 사용량Memory Basic메모리 사용량(free, used, total)Network bandwidth usage per second Allnic별 네트워크 bandwidthSystem Load1m, 5m, 15m 단위 시스템 로드(cpu 사용량)Disk R/W Data디스크에 읽고/쓴 데이터 bytesDisk Space Used% Basic디스크 사용량Disk IOps Completed디스크 io 횟수/초Time Spent Doing I/Os디스크의 io에 소요한 시간Disk R/W Timeio별 소요 시간
Network Sockstat
항목 이름설명TCP-tw종료된 TCP connection 수CurrEstab연결되어 있는 TCP connection 수TCP_inuse사용중인 TCP socket 수UDP_inuse사용중인 UDP socket 수TCP_allocalloc 상태인 TCP socket 수TCP_passive_opens해당 노드에서 listen 중인 포트에 연결하여 열린 TCP socketTCP_active_opens해당 노드로 부터 시작되어 열린 TCP socketTCP_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
참고 자료
https://prometheus-operator.dev
https://prometheus.io