사전 준비
위와 같이 사전 준비가 필요합니다.
저번 글에서 설명했듯이, EKS를 배포하기 위한 VPC를 생성하고, Public Subnet, Private Subnet을 생성합니다. 그 후 EKS Cluster에 접근하기 위한 bastion EC2를 미리 생성합니다.
추가로, 지난번 실습 때 진행했었던 ExternalDNS와 AWS LB Controller, EBS csi driver 설치, gp3 스토리지 클래스 생성까지 해주셔야합니다.
이번 포스팅에는 이전에 포스팅했던 블로그 글 에서 많이 인용하였습니다.
Prometheus
Prometheus란?
Prometheus는 SoundCloud에서 처음 개발된 오픈 소스 시스템 모니터링 및 알림 툴킷입니다. 2012년에 시작된 이후로 많은 회사와 조직이 Prometheus를 채택하였고, 매우 활발한 개발자와 사용자 커뮤니티를 가지고 있습니다.
Prometheus는 2016년 Kubernetes 에 이어 두 번째 프로젝트로 Cloud Native Computing Foundation에 합류했으며, 서비스 운영을 위해 모니터링 시스템을 구축할 때 가장 널리 사용되는 툴 중 하나입니다.
Prometheus 특징
- 다차원 데이터 모델: 메트릭 이름과 키/값 쌍으로 시계열 데이터를 식별합니다.
- PromQL: 이러한 차원성을 활용할 수 있는 유연한 쿼리 언어입니다.
- 분산 저장에 의존하지 않음: 단일 서버 노드가 자립적으로 작동합니다.
- HTTP를 통한 풀 모델: 시계열 데이터 수집이 HTTP를 통해 이루어집니다.
공식문서에서는 Prometheus의 특징을 위처럼 알려주지만, 가장 큰 특징이 2가지 있습니다.
Pull-Based Monitoring
기존의 Push-Based Monitoring 방식 대신에 Pull-Based Monitoring을 사용합니다. 대상 서버에 설치된 Exporter가 메트릭 정보를 수집하고, 이 데이터는 수집 서버가 주기적으로 가져가는 구조입니다.
즉, 클라이언트에서 서버로 데이터를 보내는 것(PUSH)가 아닌 서버가 클라이언트의 데이터를 수집(Pull) 방식입니다. 이러한 방식은 기존의 에이전트(agent) 방식보다 더 유연하고 관리하기 쉽습니다.
시계열 데이터베이스(TSDB)
관계형 데이터베이스(RDB) 대신 metric 이름과 key-value 쌍으로 식별되는 시계열 데이터 모델을 사용합니다. 이를 통해 대량의 정보를 빠르게 검색할 수 있습니다.
Prometheus 구조
Prometheus는 크게 5가지로 구조를 나눠볼 수 있습니다.
Exporter
- host서버에 설치되어 메트릭 데이터를 수집하는 역할을 합니다.
- Prometheus 서버가 접근하여 데이터를 가져올 수 있는 HTTP 엔드포인트를 제공하여 다양한 데이터를 수집합니다.
Prometheus Server
- Prometheus Server는 메트릭 데이터를 스크랩하고 저장합니다.
- 메트릭 데이터 수집 주기를 설정하여 지정된 시간마다 대상 서버에 있는 Exporter로부터 데이터를 수집합니다.
- 수집한 데이터를 저장하고 PromQL(프로메테우스 쿼리 언어)를 사용하여 데이터를 쿼리하고 필터링할 수 있습니다.
Grafana
- Grafana는 데이터 시각화 도구로, Prometheus가 수집한 메트릭 데이터를 그래프나 대시보드 형태로 시각화하여 표현할 수 있습니다.
- Prometheus Server에서 직접 제공하는 웹 뷰보다 더 다양한 시각화 기능을 제공하며, Grafana를 통해 데이터를 더 직관적으로 이해할 수 있습니다.
Alertmanager
- Prometheus가 수집한 metric 데이터를 기반으로 경고를 생성하고 규칙을 만들어 관리합니다.
Prometheus Stack
kube-prometheus-stack이란?
kube-prometheus-stack은 kubernetes cluster에 맞게 구성된 오픈 소스 프로젝트입니다. Prometheus를 기반으로 하며, 쿠버네티스 클러스터의 다양한 컴포넌트들의 메트릭 데이터를 수집하고 이를 시계열 데이터로 생성하여 모니터링 및 경고 기능을 제공합니다.
kube-prometheus-stack 구조
일반적인 Prometheus와 구조가 비슷하지만 kubernetes cluster에 맞게 구성되어있습니다.
Prometheus Operator
- 쿠버네티스 내에서 Prometheus 서버와 관련된 리소스들을 관리하기 위한 컨트롤러입니다.
- Prometheus와 관련된 설정, 서비스 디스커버리, 룰 및 대시보드를 관리할 수 있습니다.
Prometheus Server
- 고가용성을 제공하는 Prometheus 서버입니다.
- metric 데이터를 스크랩하고 저장합니다.
Alertmanager
- Prometheus가 수집한 메트릭 데이터를 기반으로 경고를 생성하고 관리하는 역할을 합니다.
Prometheus node-exporter
- node-exporter는 Host의 metric을 수집하는 역할을 합니다.
- CPU, 메모리, 디스크 사용량 등의 데이터를 수집하여 Prometheus로 전달합니다.
Prometheus Adapter for Kubernetes Metrics APIs
- 쿠버네티스의 메트릭 API와 연동하여 클러스터 내부의 리소스 메트릭 데이터를 수집하고 Prometheus로 전달합니다.
kube-state-metrics
- 쿠버네티스 클러스터의 상태 정보의 metric을 수집합니다.
- 파드, 디플로이먼트, 노드 등의 상태 정보를 모니터링할 수 있습니다.
Grafana
- Grafana는 데이터 시각화 및 대시보드 생성 도구로, 수집한 메트릭 데이터를 그래프나 대시보드 형태로 시각화하여 사용자에게 제공합니다.
kube-prometheus-stack 실습
monitoring namespace 생성
kubectl create ns monitoring
사용 리전의 인증서 ARN 확인
CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text`
echo $CERT_ARN
console창에 값이 출력된다면 정상인 것이니 정상 상태임을 확인합니다. (만료 상태면 후에 배포할 때에 에러 발생가 발생합니다!)
helm repo 설치
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
위의 명령어로 prometheus-community helm repo를 현재 cluster에 추가해줍니다.
prometheus:
prometheusSpec:
podMonitorSelectorNilUsesHelmValues: false
serviceMonitorSelectorNilUsesHelmValues: false
retention: 5d
retentionSize: "10GiB"
storageSpec:
volumeClaimTemplate:
spec:
storageClassName: gp3
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 30Gi
ingress:
enabled: true
ingressClassName: alb
hosts:
- prometheus.$MyDomain
paths:
- /*
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
alb.ingress.kubernetes.io/group.name: study
alb.ingress.kubernetes.io/ssl-redirect: '443'
grafana:
defaultDashboardsTimezone: Asia/Seoul
adminPassword: prom-operator
ingress:
enabled: true
ingressClassName: alb
hosts:
- grafana.$MyDomain
paths:
- /*
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
alb.ingress.kubernetes.io/group.name: study
alb.ingress.kubernetes.io/ssl-redirect: '443'
persistence:
enabled: true
type: sts
storageClassName: "gp3"
accessModes:
- ReadWriteOnce
size: 20Gi
defaultRules:
create: false
kubeControllerManager:
enabled: false
kubeEtcd:
enabled: false
kubeScheduler:
enabled: false
alertmanager:
enabled: false
ExternalDNS의 alb로 배포하기 위해 prometheus-stack에서 prometheus와 grafana의 설정을 몇가지 수정하도록 하겠습니다.
위에 보시면 kube-controller-manager와 etcd, kube-scheduler등 Amazon EKS의 contorle plane은 Amazon에서 관리하는 영역은 수집할 수 없습니다.
helm 배포
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 57.1.0 \
--set prometheus.prometheusSpec.scrapeInterval='15s' --set prometheus.prometheusSpec.evaluationInterval='15s' \
-f monitor-values.yaml --namespace monitoring
배포 확인
kubectl --namespace monitoring get pods -l "release=kube-prometheus-stack"
생성된 Pod들을 살펴보겠습니다.
grafana
프로메테우스는 메트릭 정보를 저장하는 용도로 사용하며, 그라파나로 시각화 처리를 합니다.
prometheus-0
모니터링 대상이 되는 파드는 ‘exporter’라는 별도의 사이드카 형식의 파드에서 모니터링 메트릭을 노출, pull 방식으로 가져와 내부의 시계열 데이터베이스에 저장합니다.
node-exporter
노드 익스포터는 물리 노드에 대한 자원 사용량(네트워크, 스토리지 등 전체) 정보를 메트릭 형태로 변경하여 노출합니다.
operator
시스템 경고 메시지 정책(prometheus rule), 애플리케이션 모니터링 대상 추가 등의 작업을 편리하게 할수 있게 CRD 지원합니다.
kube-state-metrics
쿠버네티스의 클러스터의 상태(kube-state)를 메트릭으로 변환하는 파드입니다.
AWS ELB(ALB) 갯수 확인
AWS Managed Console > EC2 > 로그밸런서 > 리로스맵에 접근해서 리스너(OSI 7계층에 해당하는 HTTP/HTTPS)별로 어떤 규칙에 의해 어떤 대상 그룹에 전달되는지 확인하실 수 있습니다.
쉽게 말해 Ingress에서 /metric의 경로에 설정한 pod가 있을 때 유저가 test.com/metric으로 접근한다면 해당 대상그룹으로 전송됩니다.
즉, 저와 같은 경우엔 lakescript.net이라는 host가 존재하며 grafana, prometheus로 서브 도메인을 설정하였고 각각 grafana와 prometheus pod로 트래픽을 전달합니다.
Prometheus 실습
prometheus는 일반적으로 모니터링 대상이 되는 서비스의 /metric 엔드포인트에 다양한 metric 정보를 수집합니다. 이후 프로메테우스는 해당 경로에 HTTP/GET 방식으로 metric 정보를 가져와 TSDB 형식으로 저장합니다.
노출 경로 확인
kubectl get node -owide
kubectl get svc,ep -n monitoring kube-prometheus-stack-prometheus-node-exporter
위의 사진처럼 Prometheus가 각 서비스의 9100 port에 접속하여 메트릭 정보를 수집합니다. 그렇기에 worker node 9100 port의 /metrics 경로에 접속 시 다양한 메트릭 정보를 확인 할 수 있습니다. (마스터 이외에 워커노드도 확인 가능합니다.)
프로메테우스 ingress 도메인으로 Web 접속
kubectl get ingress -n monitoring kube-prometheus-stack-prometheus
HOSTS에 출력된 URL에 접근하면 아래와 같이 정상적으로 접근하실 수 있습니다.!
Metric Target 확인
prometheus에서 다양한 metric 데이터를 수집하고 있는데, 어떤 것들인지 수집되고 있는지 확인해보겠습니다.
prometheus url에 접근하고 Status>Targets에 접근하면 아래와 같이 현재 어떤 targets들이 수집되고 있는지 확인하실 수 있습니다.
각 node의 9100 port로 각 node들의 metric 데이터를 수집하고 있는지 확인해보겠습니다.
마찬가지로 Status>Targets에 접근하여 kube-prometheus-stack-prometheus-node-exporter를 보시면 각 node의 9100/metric이 node의 metric 데이터를 수집하고 있는 것을 확인하실 수 있습니다.
Configure 확인
현재 어떤 설정에 의해 prometheus가 구성되었고, 실행중인지 파악하려면 Status>Configuration에 접근합니다.
그럼 위의 사진처럼 Configuration 정보들을 확인할 수 있습니다.
이중 node-exporter 설정을 한번 보도록 하겠습니다.
global:
scrape_interval: 15s # 메트릭 가져오는(scrape) 주기
scrape_timeout: 10s # 메트릭 가져오는(scrape) 타임아웃
evaluation_interval: 15s # alert 보낼지 말지 판단하는 주기
...
- job_name: serviceMonitor/monitoring/kube-prometheus-stack-prometheus-node-exporter/0
scrape_interval: 30s
scrape_timeout: 10s
metrics_path: /metrics
scheme: http
...
kubernetes_sd_configs: # 서비스 디스커버리(SD) 방식을 이용하고, 파드의 엔드포인트 List 자동 반영
- role: endpoints
kubeconfig_file: ""
follow_redirects: true
enable_http2: true
namespaces:
own_namespace: false
names:
- monitoring # 서비스 엔드포인트가 속한 네임 스페이스 이름을 지정, 서비스 네임스페이스가 속한 포트 번호를 구분하여 메트릭 정보를 가져옴
위에서 주석으로 적혀져있는 것을 보셨듯이 중요한 정보를 정리하면 아래와 같습니다.
- global.scrape_interval: 메트릭 가져오는(scrape) 주기
- global.scrape_timeout: 메트릭 가져오는(scrape) 타임아웃
- global.evaluation_interval: alert 보낼지 말지 판단하는 주기
- kubernetes_sd_configs: 서비스 디스커버리(SD) 방식을 이용하고, 파드의 엔드포인트 List 자동 반영
- kubernetes_sd_configs.namespaces.names: 서비스 엔드포인트가 속한 네임 스페이스 이름을 지정(서비스 네임스페이스가 속한 포트 번호를 구분하여 메트릭 정보를 가져옴)
Graph 확인
node_exporter metric
node_exporter로 수집된 값들을 보실려면 node만 입력후 자동완성으로 검색되는 값들을 확인하실 수 있습니다.
그 중 node_memory_Active_bytes를 한번 확인해보겠습니다.
node_memory_Active_bytes
출력되는 metric 정보는 node-exporter 를 통해서 총 3개의 노드에서 수집된 정보입니다.
node_memory_Active_bytes{instance="192.168.1.105:9100"}
이렇듯 {instance=} 구문을 통해 특정 instance의 node_memory_Active_bytes 값을 확인하실 수 있습니다.
kube-state-meric
kubenetes-api를 통해 Deployments나 CronJob등 다양한 Kind의 값들을 수집합니다.
대표적으로 kube_deployment 입력시 나오는 값들이 kube-state-metirc 데이터입니다.
kube_deployment_status_replicas
kube_deployment_status_replicas 쿼리를 입력 후 실행하면 오른쪽에 replicas들의 숫자들이 출력됩니다.
kube_deployment_status_replicas_available{deployment="coredns"}
codedns pod의 숫자를 확인해보겠습니다.
현재는 2개로 확인하실 수 있는데, replicas를 3개로 늘려보겠습니다.
kubectl scale deployment -n kube-system coredns --replicas 3
그러고 다시 kube_deployment_status_replicas_available{deployment="coredns"} 쿼리를 입력하니 3개로 보여지는 것을 확인하실 수 있습니다!
애플리케이션 모니터링 실습
nginx 를 helm 설치 시 Prometheus Exporter 옵션을 설정 하여 자동으로 nginx 를 프로메테우스 모니터링에 등록 가능합니다. 또한 프nginx 모니터링 관련 내용을 서비스 모니터 CRD로 추가 가능하며 기존 애플리케이션 파드에 프로메테우스 모니터링을 추가하려면 사이드카 방식을 사용하며 exporter 컨테이너를 추가하면 됩니다.
NGINX 배포
helm repo 추가
helm repo add bitnami https://charts.bitnami.com/bitnami
파라미터 파일 생성
metrics:
enabled: true
service:
port: 9113
serviceMonitor:
enabled: true
namespace: monitoring
interval: 10s
서비스 모니터 방식으로 nginx 모니터링 대상을 등록하고, export 는 9113 포트 사용합니다.
파라미터 파일을 설정 파일로 사용하여 nginx 배포
helm install nginx bitnami/nginx --version 15.14.0 -f nginx_metric-values.yaml
배포 확인
kubectl get pod,svc,ep
Prometheus 확인
target 확인
Prometheus에서 Target 확인하면 위의 사진과 같이 serviceMonitor/monitoring/nginx/0 이 생성된 것을 보실 수 있습니다.
Configurations 확인
nginx의 설정이 추가 되었는데, 주요 config가 적용될 시에 reloader하여 설정이 자동으로 반영됩니다.
Graph 확인
현재 nginx deployments의 갯수는 1개입니다. 해당 데이터는 nginx_up을 통해 확인하실 수 있습니다.
kubectl scale deployment nginx --replicas 2
위 명령어를 통해 nginx deployment의 수를 2개로 늘린 후 다시 확인해보겠습니다.
위처럼 2개로 정상적으로 확인하실 수 있습니다.
PromQL
PromQL은 Prometheus Query으로써 metric으로 수집된 데이터를 의미있는 값으로 가공할 수 있는 일종의 Query언어입니다.
프로메테우스 메트릭 종류에는 Counter, Gauge, Histogram, Summary가 있습니다.
- Gauge : 특정 시점의 값을 표현하기 위해서 사용하는 메트릭 타입, CPU 온도나 메모리 사용량에 대한 현재 시점 값
- Counter : 누적된 값을 표현하기 위해 사용하는 메트릭 타입, 증가 시 구간 별로 변화(추세) 확인, 계속 증가 → 함수 등으로 활용
- Summary : 구간 내에 있는 메트릭 값의 빈도, 중앙값 등 통계적 메트릭
- Histogram : 사전에 미리 정의한 구간 내에 있는 메트릭 값의 빈도를 측정 → 함수로 측정 포맷을 변경
Label Matchers
node_memory_Active_bytes
node_memory_Active_bytes{instance="192.168.1.188:9100"}
node_memory_Active_bytes{instance!="192.168.1.188:9100"}
정규표현식
node_memory_Active_bytes{instance=~"192.168.+"}
node_memory_Active_bytes{instance=~"192.168.1.+"}
다수 대상
node_memory_Active_bytes{instance=~"192.168.1.188:9100|192.168.2.170:9100"}
node_memory_Active_bytes{instance!~"192.168.1.188:9100|192.168.2.170:9100"}
여러 조건 AND
kube_deployment_status_replicas_available{namespace="kube-system"}
kube_deployment_status_replicas_available{namespace="kube-system", deployment="coredns"}
Aggregation Operators (집계 연산자)
sum : 조회된 값들을 모두 더함
min : 조회된 값에서 가장 작은 값을 선택
max : 조회된 값에서 가장 큰 값을 선택
avg : 조회된 값들의 평균 값을 계산
group : 조회된 값을 모두 ‘1’로 바꿔서 출력
stddev : 조회된 값들의 모 표준 편차를 계산
stdvar : 조회된 값들의 모 표준 분산을 계산
count : 조회된 값들의 갯수를 출력 / 인스턴스 벡터에서만 사용 가능
count_values : 같은 값을 가지는 요소의 갯수를 출력
bottomk : 조회된 값들 중에 가장 작은 값들 k 개 출력
topk : 조회된 값들 중에 가장 큰 값들 k 개 출력
quantile : 조회된 값들을 사분위로 나눠서 (0 < $ < 1)로 구성하고, $에 해당 하는 요소들을 출력
출력 값 중 Top 3
topk(3, node_memory_Active_bytes)
출력 값 중 하위 3
bottomk(3, node_memory_Active_bytes)
node 그룹별: by
avg(node_cpu_seconds_total) by (instance)
활용
파드별로 container가 사용중인 메모리를 MB 크기로 확인해보겠습니다.
sum(container_memory_working_set_bytes) by (pod)/1024/1024
Reference
- https://leehosu.github.io/kube-prometheus-stack
'스터디 이야기 > AWS EKS' 카테고리의 다른 글
[AEWS] 5-1. Amazon EKS - Autoscaling (HPA, KEDA, VPA) (0) | 2024.04.01 |
---|---|
[AEWS] 4-3. Amazon EKS - Observability (Grafana) (1) | 2024.03.29 |
[AEWS] 4-1. Amazon EKS - Observability(EKS Logging) (0) | 2024.03.25 |
[AEWS] 3-2. Amazon EKS - NodeGroup (ARM Instance, Spot Instance) (0) | 2024.03.21 |