이번 블로그에서는 프로메테우스와 그라파나 실습을 진행하였다.

일단 프로메테우스와 그라파나를 설치하였다.

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

다음과 같이 모니터링 네임스페이스에 패키지로 설치된걸 확인할 수 있었다.

Untitled

route53에 들어가 확인해 보면 그라파나와 프로메테우스 서브도메인이 자동으로 들어가 있었다.

Untitled 1

Untitled 2

그리고 myeks-ingress-alb이름을 가진 alb 리스너 규칙에 들어가 보면 아래와 같이 자동으로 grafana와 prometheus 도메인 타켓팅이 되어 있고

Untitled 3

각각의 ip는 각각의 파드 ip를 의미한다. 이제 저 도메인주소로 접근하면 해당하는 파드에 접근할 수 있다. vpc cni로 인해 노드와 파드 ip 대역이 같아서 바로 ip로 타겟을 잡을 수 있다. 만약 오버레이 네트워크였으면 파드ip로는 타겟을 못잡고 service로 타겟을 잡아야 할까 싶다

Untitled 4

Untitled 5

프로메테우스

프로메테우스의 모니터링 대상이 되는 서비스는 일반적으로 자체 웹 서버의 /metrics 경로에 다양한 메트릭 정보를 노출한다. 이후 프로메테우스는 해당 경로에 http get 방식으로 메트릭 정보를 가져와 TSDB 형식으로 저장한다. 그래서 엔드포인트를 확인해 보면 각 노드는 9100 포트를 사용하고 있다.

Untitled 6

또한 각 노드에 들어가서 curl -s localhost:9100/metrics로 확인해 보면 다양한 메트릭 정보를 보여 준다.

Untitled 7

이제 프로메테우스에 들어가 보자!

Untitled 8

지금은 메인 화면이고 status에 들어가면 각종 정보를 확인할 수 있다.

Untitled 9

Storage retention은 메트릭 저장 기간을 말하는데, 5일을 경과했거나 10GiB 이상 시 오래된 것부터 삭제한다. 이는 helm 파라미터에서 수정 가능하다.

Untitled 10

프로메테우스의 설정도 볼 수 있다. 여기서 스크랩하는 인터벌 주기는 15초이며, 타임아웃은 10초라는 것을 알 수 있다.

Untitled 11

node-exporter를 검색해 보면 스크랩 주기는 동일하다.

이제 Graph에서 PromQL 쿼리 1-avg(rate(node_cpu_seconds_total{mode="idle"}[1m]))를 날려 전체 클러스터의 CPU사용량을 조회해 봤다.

Untitled 12

또한 node 혹은 kube로 자동완성되어 조회할 수 있는 메트릭이 정말 많았다.

Untitled 13

Untitled 14

조건을 명시해서 조회도 가능하다

  • 산술 이진 연산자 : + / `` ^
  • 비교 이진 연산자 : == != > < >= <=
  • 논리/집합 이진 연산자 : and, or, unless

이 밖에도 다양한 오퍼레이터를 지원한다.

Untitled 15

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

그라파나

그라파나는 TSDB 데이터를 시각화한다. 그리고 다양한 데이터 형식 지원한다.(메트릭, 로그, 트레이스 등) 그라파나는 시각화 툴일 뿐, 데이터를 저장하지는 않는다.

그라파나 파드에서 grafana cli version을 확인해 보면 10.4.0이라는 것을 알 수 있다.

Untitled 16

이제 그라파나 도메인 주소를 확인하고

Untitled 17

패스워드는 파드를 참고하고 시크릿을 참고하자_(base64로 인코딩되어 있으니 디코딩이 필요하다)_

Untitled 18

그라파나 로그인을 하면 보이는 초기 화면이다.

Untitled 19

커넥션을 보면 프로메테우스가 자동으로 설정되어 있다.

Untitled 20

이는 프로메우스의 엔드포인트다.

Untitled 21

테스트 파드를 만들어서 nslookup과 curl을 날려보면 프로메테우스의 클러스터 아이피로 연결되고 접속 확인이 가능했다.

Untitled 22

이제 아래 링크의 추천 대시보드를 만들어 보겠다

https://grafana.com/orgs/imrtfm/dashboards

Untitled 23

대시보드 > 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 시켰고

Untitled 24

프로메테우스와 그라파나에 정상적으로 메트릭을 불러 오는 것을 확인할 수 있었다!

Untitled 25

Untitled 26

실습을 마치고 모든 리소스를 삭제하자!

Categories:

Updated:

Leave a comment