[AEKS2] 4주차 - EKS Observability (2)
이번 블로그에서는 프로메테우스와 그라파나 실습을 진행하였다.
일단 프로메테우스와 그라파나를 설치하였다.
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
헬름차트를 먼저 추가해 주고
monitor-values.yaml를 만들었다
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
다음은 모니터링 네임스페이스를 생성하고 프로메테우스와 그라파나의 몇몇 설정 값을 변경한 values.yaml 파일로 헬름차트를 인스톨한다.
kubectl create ns monitoring
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
다음과 같이 모니터링 네임스페이스에 패키지로 설치된걸 확인할 수 있었다.
route53에 들어가 확인해 보면 그라파나와 프로메테우스 서브도메인이 자동으로 들어가 있었다.
그리고 myeks-ingress-alb이름을 가진 alb 리스너 규칙에 들어가 보면 아래와 같이 자동으로 grafana와 prometheus 도메인 타켓팅이 되어 있고
각각의 ip는 각각의 파드 ip를 의미한다. 이제 저 도메인주소로 접근하면 해당하는 파드에 접근할 수 있다. vpc cni로 인해 노드와 파드 ip 대역이 같아서 바로 ip로 타겟을 잡을 수 있다. 만약 오버레이 네트워크였으면 파드ip로는 타겟을 못잡고 service로 타겟을 잡아야 할까 싶다
프로메테우스
프로메테우스의 모니터링 대상이 되는 서비스는 일반적으로 자체 웹 서버의 /metrics 경로에 다양한 메트릭 정보를 노출한다. 이후 프로메테우스는 해당 경로에 http get 방식으로 메트릭 정보를 가져와 TSDB 형식으로 저장한다. 그래서 엔드포인트를 확인해 보면 각 노드는 9100 포트를 사용하고 있다.
또한 각 노드에 들어가서 curl -s localhost:9100/metrics
로 확인해 보면 다양한 메트릭 정보를 보여 준다.
이제 프로메테우스에 들어가 보자!
지금은 메인 화면이고 status에 들어가면 각종 정보를 확인할 수 있다.
Storage retention은 메트릭 저장 기간을 말하는데, 5일을 경과했거나 10GiB 이상 시 오래된 것부터 삭제한다. 이는 helm 파라미터에서 수정 가능하다.
프로메테우스의 설정도 볼 수 있다. 여기서 스크랩하는 인터벌 주기는 15초이며, 타임아웃은 10초라는 것을 알 수 있다.
node-exporter를 검색해 보면 스크랩 주기는 동일하다.
이제 Graph에서 PromQL 쿼리 1-avg(rate(node_cpu_seconds_total{mode="idle"}[1m]))
를 날려 전체 클러스터의 CPU사용량을 조회해 봤다.
또한 node 혹은 kube로 자동완성되어 조회할 수 있는 메트릭이 정말 많았다.
조건을 명시해서 조회도 가능하다
- 산술 이진 연산자 :
+
/
``^
- 비교 이진 연산자 :
==
!=
>
<
>=
<=
- 논리/집합 이진 연산자 :
and
,or
,unless
이 밖에도 다양한 오퍼레이터를 지원한다.
https://prometheus.io/docs/prometheus/latest/querying/basics/
그라파나
그라파나는 TSDB 데이터를 시각화한다. 그리고 다양한 데이터 형식 지원한다.(메트릭, 로그, 트레이스 등) 그라파나는 시각화 툴일 뿐, 데이터를 저장하지는 않는다.
그라파나 파드에서 grafana cli version을 확인해 보면 10.4.0이라는 것을 알 수 있다.
이제 그라파나 도메인 주소를 확인하고
패스워드는 파드를 참고하고 시크릿을 참고하자_(base64로 인코딩되어 있으니 디코딩이 필요하다)_
그라파나 로그인을 하면 보이는 초기 화면이다.
커넥션을 보면 프로메테우스가 자동으로 설정되어 있다.
이는 프로메우스의 엔드포인트다.
테스트 파드를 만들어서 nslookup과 curl을 날려보면 프로메테우스의 클러스터 아이피로 연결되고 접속 확인이 가능했다.
이제 아래 링크의 추천 대시보드를 만들어 보겠다
https://grafana.com/orgs/imrtfm/dashboards
대시보드 > New > Import 로 공식 대시보드를 가져 올 수 있다. 하지만 NO DATA로 가져오지 못하는 데이터가 있는데 이럴 땐 쿼리문을 다시 봐야한다. 해당 대시보드를 edit하고 쿼리문을 보자. 이 쿼리들을 프로메테우스에서 직접 실행해서 조회되는지 확인해 보았다.
-
파드의 cpu throttle
sum(rate(container_cpu_cfs_throttled_seconds_total{namespace=~"$namespace", image!="", pod=~"${created_by}.*", cluster="$cluster"}[$__rate_interval])) by (pod) > 0
container_cpu_cfs_throttled_seconds_total은 프로메테우스에서 없는 메트릭이라서 지웠다.
-
네임스페이스 또는 파드당 oom 이벤트
sum(increase(container_oom_events_total{namespace=~"${namespace}", cluster="$cluster"}[$__rate_interval])) by (namespace, pod) > 0
sum(increase(container_oom_events_total[1m])) by (namespace, pod) > 0
으로 변경했다 increase는 범위 시간당 증가율을 의미한다. $__rate_interval을 받아오지 못하는 것 같아 임의 값을 지정해 줬다. -
네임스페이스 또는 파드당 컨테이너 restart
sum(increase(kube_pod_container_status_restarts_total{namespace=~"${namespace}", cluster="$cluster"}[$__rate_interval])) by (namespace, pod) > 0
sum(increase(kube_pod_container_status_restarts_total[1m])) by (namespace, pod) > 0
로 변경했다
정말 찍히는지 보기 위해 nginx 파드에 들어가서 nginx 프로세스를 죽여서 restart 시켰고
프로메테우스와 그라파나에 정상적으로 메트릭을 불러 오는 것을 확인할 수 있었다!
실습을 마치고 모든 리소스를 삭제하자!
Leave a comment