모니터링, 프로메테우스와 그라파나

문한성·2023년 6월 4일
0

부트캠프

목록 보기
102/123
post-thumbnail

컨테이너 인프라 환경 모니터링하기

모니터링이 어떤 것인지 간단히 살펴보겠습니다.

m-k8s 노드에서 bpytop 명령을 실행하면 다음 그림과 같이 시스템 상태 정보가 보입니다.

화면에서 리소스의 상태 및 문제가 될 가능성이 있는 정보를 한눈에 파악할 수 있습니다.

  • bpytop

그러나 bpytop은 현재 노드에 대한 정보만 보여줄 뿐,

다수의 노드로 구성된 클러스터 정보를 모두 표현하기는 어렵습니다.

그래서 이러한 정보를 수집하고 분류해서 따로 저장해야 합니다.

거의 모든 모니터링 도구는 다음과 같이 수집 -> 통합 -> 시각화 구조로 돼 있습니다.

우리가 구축한 컨테이너 인프라 환경에서는 모니터링 데이터를 프로메테우스로 수집하고,

수집한 정보를 한 곳에 모아(통합), 그라파나로 시각화합니다.

모니터링 도구 선택하기

여기서 사용하는 프로메테우스와 그라파나는 오픈 소스 도구입니다.

오픈 소스는 가능한 한 단일 도구에서 단일 기능만을 구현하는 것을 선호합니다.

데이터 수집과 통합, 시각화는 서로 다른 영역이므로 이를 함꼐 구현하지 않으려는 경향이 있습니다.

물론 서비스형 모니터링 도구는 사용자 편의를 위해 이러한 기능을 모아서 한꺼번에 제공합니다.

그런데 왜 하나의 도구로 처리하지 않고 이런 혼합 구조를 사용할까요?

프로메테우스와 그라파나의 혼합 구조를 사용하는 이유는 크게 두 가지입니다.

  1. 비용 : 모니터링 대상마다 라이선스(License) 관련 비용이 발생하고, 클라우드 같은 과금제 서비스를 이용하면 네트워크와 저장 공간에 따른 추가 비용이 발생합니다.
  2. 보안 : 서비스형 모니터링 도구들은 대부분 외부에 데이터를 저장해 모니터링합니다. 보안에 민감해서 내부에서 모든 데이터를 처리하려는 경우에는 사용하기 어렵습니다.

그럼 다른 데이터 수집과 통합, 시각화에 사용하는 도구들은 무엇이 있을까요?

데이터 수집과 통합 도구

여러 모니터링 도구를 비교하며 프로메테우스를 선택한 이유를 알아보겠습니다.

  • 프로메테우스(Prometheus)
    • 사운드클라우드(SoundCloud)에서 자사 서비스의 모니터링을 위해 개발한 도구
    • 현재는 오픈 소스로 전환돼 CNCF에서 관리, 2018년 8월 졸업 프로젝트가 됨
    • 시계열 DB를 내장하고 있고, 자체적인 질의 페이지 외에 시각화 기능은 없으나 그라파나와 연계하면 현업에서 사용할 수 있는 시각화 기능 제공 가능
    • 중앙 서버에서 에이전트의 데이터를 수집하는 풀(Pull) 방식을 사용하므로 쿠버네티스 환경에서 설치된 에이전트를 통해 노드와 컨테이너 상태를 모두 수집해 모니터링 가능
    • 에이전트를 통해 내부 메트릭을 외부로 노출하기 때문에 사용자가 수집 대상에 접속할 수만 있다면 개인 컴퓨터에서도 메트릭을 가져올 수 있음, 따라서 모니터링과 관련된 개발을 하기 용이함
    • 일회성으로 모니터링 대상에 대한 세부적인 메트릭도 간단하게 웹 브라우저로 확인 가능
    • 완전한 오픈 소스 모델을 선택해 사용자 층이 넓고 자료가 풍부하며 각종 대시보드 도구나 메신저 등이 프로메테우스와의 연계를 지원하므로 직접 모니터링 시스템을 구축할 때 좋음
  • 데이터톡(Datadog)
    • 모니터링 데이터를 업체에서 관리하는 경우를 서비스형이라고 하고, 데이터를 사용자가 직접 관리하는 경우를 설치형이라고 하는데, 데이터독은 서비스형 소프트웨어(SaaS) 형태로 제공
    • 웹사이트에서 모니터링 대상을 관리할 수 있고 쿠버네티스를 비롯해 여러 클라우드 서비스나 애플리케이션과 연결이 쉬우므로 관리 부담이 적음
    • 모니터링 대상마다 요금을 부과하기 때문에 모니터링 대상이 늘면 비용이 커지는 단점이 존재
  • 뉴 렐릭(New Relic)
    • 데이터독과 같은 Saas, 다만 데이터독과 비교했을 때 애플리케이션 성능 모니터링(APM, Application Performance Monitoring)에 더 특화됌
    • 데이터독과 마찬가지로 모니터링 대상이 많을수록 비용 증가
  • 인플럭스DB(InfluxDB)
    • 2013년 인플럭스데이터(InFluxdata)에서 개발한 시계열 DB
    • 오픈소스로 공개된 무료 버전과 클라우드에서 바로 사용할 수 있는 SaaS, 라이선스를 구매해 설치할 수 있는 엔터프라이 버전, 총 3가지 유형을 제공
    • 무료 버전은 프로메테우스와 유사하지만 인플럭스DB가 쓰기 성능이 더 뛰어나 대량의 이벤트를 모니터링하는 데는 좀 더 적합
    • 엔터프라이즈 버전은 프로메테유스에서 부족한 부분인 고가용성을 위한 분산 저장을 좀 더 쉽게 구성할 수 있는 기능 제공
    • 프로메테우스와 더불어 오픈 소스로 모니터링 플랫폼을 구축하기 위한 최선의 도구이고, 유료 서비스도 있어 선택의 폭이 좀 더 넓음
    • 하지만 간단한 구성으로 데이터를 받아오는 프로메테우스보다 상대적으로 구성이 어렵다는 단점이 존재

메트릭이란?

메트릭(Metric)은 간단히 말해 현재 시스템의 상태를 알 수 있는 측정값입니다.

컨테이너 인프라 환경에서는 크게 2가지 상태로 메트릭을 구분합니다.

파드 같은 오브젝트에서 측정되는 CPU와 메모리 사용량을 나타내는 시스템 메트릭(System Metric),

HTTP 상태 코드 같은 서비스 상태를 나타내는 지표인 서비스 메트릭(Service Metric) 입니다.

시계열 데이터베이스란?

시계열 DB는 시간을 축(키)으로 시간의 흐름에 따라 발생하는 데이터를 저장하는 데 최적화된 데이터베이스입니다.

예를 들어 네트워크 흐름을 알 수 있는 패킷과 각종 기기로부터 전달받는 IoT 센서 값, 이벤트 로그 등이 있습니다.

이 책에서는 프로메테우스의 시계열 DB에 쿠버네티스와 노드에서 공개하는 메트릭을 저장하고,

이를 효과적으로 조합해 사용자가 원하는 모니터링을 구성합니다.

데이터 수집과 통합 도구의 기능을 간단히 정리하면 다음과 같습니다.

구분프로메테우스데이터독뉴 렐릭인플럭스DB
가격무료유료유료유/무료
형태설치형서비스형서비스형서비스형/설치형
참고 자료매무 많음많음많음많음
기능 확장성매우 좋음좋음좋음좋음

데이터 시각화 도구

프로메테우스와 인플럭스DB가 제공하는 대시보드는

서비스형으로 사용하는 데이터톡과 뉴 렐릭보다 시각화 부분이 다소 약합니다.

그래서 부족한 시각화 기능을 보강하는 다음과 같은 도구를 사용합니다.

  • 그라파나(Grafana)
    • 그라파나 랩스(Grafana Labs)에서 개발했으며, 특정 소프트웨어에 종속되지 않은 독립적인 시각화 도구
    • 30가지 이상의 다양한 수집 도구 및 DB들과 연계를 지원
    • 주로 시계열 데이터 시각화에 많이 쓰임, 관계형 데이터베이스 데이터를 표 형태로 시각화해 사용할 수도 있음
    • 기능을 확장하는 플러그인과 개별 사용자들이 만들어 둔 대시보드의 공유가 매우 활발
    • 오픈 소스라서 사용자의 요구 사항에 맞게 수정 가능, 필요에 따라 설치형과 서비스형 모두 선택 가능
  • 키바나(Kibana)
    • 엘라스틱서치(ElasticSearch)를 개발한 엘라스틱에서 만든 시각화 도구
    • 엘리스틱서치에 적재된 데이터를 시각화하거나 검색하는 데 사용, 이러한 데이터를 분석할 때도 사용
    • 엘라스틱서치의 데이터만을 시각화할 수 있기 때문에 프로메테우스의 시계열 데이터를 메트릭비트(Metricbeat)라는 도구로 엘라스틱서치에 전달해야 하는 불편함 존재
    • 시각화 기능이 매우 강력해서 시각화를 중점적으로 다루는 경우에는 고려해볼만 함
  • 크로노그래프(Chronograf)
    • 인플럭스DB를 개발한 인플럭스데이터에서 만든 시각화 도구
    • 오픈소스로 제공돼 사용자 편의에 맞게 수정 가능
    • 설치형과 서비스형 모두 제공
    • 키바나와 마찬가지로 자사 제품인 인플럭스DB만 시각화할 수 있으므로 다양한 대상을 시각화할 수 없음
구분그라파나키바나크로노그래프
가격유/무료유/무료유/무료
형태서비스/설치형서비스/설치형서비스/설치형
시각화 대상다양한 대상 시각화 가능엘라스틱서치인플럭스DB
정보량많음많음적음
기능 확장성좋음좋음적음

엘라스틱 제품들을 설치형으로 구성하면 무료로 사용할 수 있지만, 엘라스틱서치로 저장해야 해서 필요한 도구가 늘어납니다.

자유도가 높은 오픈 소스를 활용해 컨테이너 인프라 환경을 구현하고 실습하는 것이 목적이라면

기능이 부족하지 않고, 확장성도 뛰어난 프로메테우스와 그라파나의 조합으로 모니터링 시스템을 구축하는게 좋습니다.

쿠버네티스 환경에 적합한 모니터링 데이터 수집 방법

쿠버네티스 노드는 kubelet을 통해 파드를 관리하며,

파드의 CPU나 메모리 같은 메트릭 정보를 수집하기 위해 kubelet에 내장된 cAdvisor를 사용합니다.

cAdvisor는 구글이 만든 컨테이너 메트릭 수집 도구로, 쿠버네티스 클러스터 위에 배포된

여러 컨테이너가 사용하는 메트릭 정보를 수집한 후 이를 가공해서 kubelet에 전달하는 역할을 합니다.

하지만 cAdvisor로 수집되고 kubelet으로 공개되는 데이터가 있어도 외부에서 이를 모아서 표현해주는 도구가 없다면 의미가 없습니다.

그래서 메트릭 데이터를 수집하는 목적으로 메티륵 서버를 설치해 HPA와 같은 기능을 구현하고

쿠버네티스 대시보드를 설치해 현재 상태를 확인할 수도 있습니다.

쿠버네티스 대시보드에 관한 내용은 추후 포스팅 하겠습니다.

이렇게 메트릭 서버에서 수집한 데이터로 여러 기능을 수행하도록 구성한 것을

리소스 메트릭 파이프라인(Resource Metric Pipeline) 이라고 합니다.

하지만 메트릭 서버는 집계한 데이터를 메모리에만 저장하므로 데이터를 영구적으로 보존하기 어렵고 현재 시점의 데이터만 출력됩니다.

그래서 메트릭 데이터를 저장 공간에 따로 저장하는 완전한 모니터링 파이프라인(Full Monitoring Pipeline) 으로 구축하기를 권장합니다.

이 설계 방식을 반영한 도구가 프로메테우스입니다.

완전한 모니터링 파이프라인으로 구성한 프로메테우스는 여러 수집 대상이 공개하는 메트릭 데이터를 모아 시계열 데이터베이스에 저장합니다.

저장된 데이터는 시간이 지나도 확인할 수 있는 영속적인 데이터입니다.

누적된 메트릭 데이터로는 쿠버네티스 인프라의 상태 변화를 파악할 수 있고, 적절한 위험 감지 및 조치를 취할 수 있습니다.


프로메테우스로 모니터링 데이터 수집과 통합하기

프로메테우스는 많은 종류의 오브젝트를 설치합니다.

다음과 같은 오브젝트를 설치하며, 오브젝트를 통해 설치된 요소로 모니터링에 필요한 데이터를 수집하고 저장합니다.

프로메테우스 서버(prometheus-server)

프로메테우스의 주요 기능을 수행하는 요소로 3가지 역할을 맡습니다.

노드 익스포터 외 여러 대상에서 공개된 메트릭을 수집해오는 수집기,

수집한 시계열 메트릭 데이터를 저장하는 시계열 데이터베이스,

저장된 데이터를 질의하거나 수집 대상의 상태를 확인할 수 있는 웹 UI입니다.

프로메테우스를 사용하려면 웹 UI를 가장 먼저 알아야합니다.

프로메테우스의 수집기는 매우 독특한 방법으로 수집 대상을 찾습니다.

서비스 디스커버리(Service Discovery) 라는 방법입니다.

노드 익스포터(node-exporter)

노드의 시스템 메트릭 정보를 HTTP로 공개하는 역할을 합니다.

설치된 노드에서 특정 파일들을 읽고, 이를 프로메테우스 서버가 수집할 수 있는 메트릭 데이터로 변환한 후에

노드 익스포터에서 HTTP 서버로 공개합니다.

공개된 내용을 프로메테우스 서버에서 수집해 가게 됩니다.

쿠버 스테이트 메트릭(kube-state-metrics)

API 서버로 쿠버네티스 클러스터의 여러 메트릭 데이터를 수집한 후,

이를 프로메테우스 서버가 수집할 수 있는 메트릭 데이터로 변환해 공개하는 역할을 합니다.

프로메테우스가 쿠버네티스 클러스터의 여러 정보를 손쉽게 획득할 수 있는 것이 이 쿠버 스테이트 메트릭 덕분입니다.

얼럿매니저(alertmanager)

얼럿매니저는 프로메테우스에 경보(alert) 규칙을 설정하고, 경보 이벤트가 발생하면 설정된 경보 메세지를 대상에서 전달하는 기능을 제공합니다.

프로메테우스에 설치하면 프로메테우스 서버에서 주기적으로 경보를 보낼 대상을 감시해 시스템을 안정적으로 운영할 수 있게 합니다.

푸시게이트웨이(pushgateway)

배치와 스케줄 작업 시 수행되는 일회성 작업들의 상태를 저장하고 모아서 프로메테우스가 주기적으로 가져갈 수 있도록 공개합니다.

일반적으로 짧은 시간 동안 실행되고 종료되는 배치성 프로그램의 메트릭을 저장하거나

외부망에서 접근할 수 없는 내부 시스템의 메트릭을 프록시 형태로 제공하는 용도로 사용합니다.

프로메테우스 그라파나 실습


  • helm와 minikube(Docker Desktop) 을 이용해서 실습하였다.

ingress-nginx 를 통해 nginx 를 앱에 적용시키기

ingress-nginx 컨트롤러 설치

  • helm 을 통해 ingress-nginx 컨트롤러 설치
    레퍼런스
    ```
    # 헬름 저장소 추가
    $ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
    
    # 저장소 정보 갱신
    $ helm repo update
    
    # 저장소 리스트 확인
    $ helm repo list
    
    # k8s 에 ingress-nginx 컨트롤러 설치
    # helm install [RELEASE_NAME] ingress-nginx/ingress-nginx
    helm install ingress-nginx ingress-nginx/ingress-nginx
    ```
  • ingress-nginx 컨트롤러 환경변수 수정
    레퍼런스
    ```
    # window에서 namespace가 자동 생성되지 않아서 수동으로 생성해줘야 한다.
    $ kubectl create namespace ingress-nginx
    $ helm upgrade -i ingress-nginx ingress-nginx/ingress-nginx \
    --namespace ingress-nginx \
    --set controller.metrics.enabled=true \
    --set-string controller.podAnnotations."prometheus\.io/scrape"="true" \
    --set-string controller.podAnnotations."prometheus\.io/port"="10254"
    ```

Ingress, Deployment, Service 생성

  • 예제 이미지를 사용해서 deployment와 Ingress Service 생성 yml
# deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: simple-app-deployment
  labels:
    app: simple-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: simple-app
  template:
    metadata:
      labels:
        app: simple-app
    spec:
      containers:
      - name: simple-app
        image: cozserver/simple-node-app:v1
        ports:
        - containerPort: 80

#ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  labels:
    app: simple-app
spec:
  ingressClassName: nginx
  rules:
    - host: "localhost"
      http:
        paths:
        - path: /test
        - path: /
          pathType: Prefix
          backend:
            service:
              name: simple-app-service
              port:
                number: 8055

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: simple-app-service
  namespace: default
spec:
  selector:
    app: simple-app
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 8055
    targetPort: 80


# kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# metadata:
#  name: arbitrary

# Example configuration for the webserver
# at https://github.com/monopole/hello
commonLabels:
  app: test-k8s

resources:
- deployment.yaml
- service.yaml
- ingress.yaml

ingress의 hostname을 적어줘야 그라파나에서 정확하게 정보를 얻어올 수 있다.

  • [Ingress, Deployment, Service].yaml 들을 적용한다.
  	# deployment.yaml, ingress.yaml, service.yaml 을 모두 적용한다.
    
    # service, deployment, ingress 생성됨
    $ kubectl apply --kustomize . 
    
    # 'kubectl kustomize . ' 명령어를 치면 어떻게 반영이 될 예정인 지 확인할 수 있다.
    
  • 적용 확인
    # 리소스 확인
    $ kubectl get all,ingress

여기까지 하면 HTTP 인그래스 , node-app 서비스, Pod 리스트 가 만들어진다.

ingress가 잘 적용되었는지 확인

  • 포트포워딩을 통해 로컬호스트의 포트와 쿠버네틱스의 ingress-controller 의 포트를 연결한다.
    # localhost 의 8080포트에 접속 시 nginx-controller 의 80포트에 전달되도록 한다.
    $ kubectl port-forward --namespace=ingress-nginx service/ingress-nginx-controller 8080:80
  • 접속 테스트를 한다.
    • 첫번째 방법: GET /test 터미널 명령어를 통한 확인
      $ curl -X GET localhost:8080/test
      # 정상적으로 받아진 것이 확인됨.
      reponsed for 'GET /test'
    • 두번째 방법: 브라우저에서 localhost:8080 (GET /) 으로 접속한다.

참고: ingress.yaml 을 통해 hostname 을 통한 라우팅과 path 를 통한 라우팅이 가능하다.

프로메테우스 적용

프로메테우스 설치

레퍼런스

  • k8s 에 프로메테우스를 배포한다.
    $ kubectl apply --kustomize github.com/kubernetes/ingress-nginx/deploy/prometheus/
  • k8s 에 프로메테우스가 정상적으로 설치되었는 지 확인한다.
$ kubectl get all -n ingress-nginx
# 프로메테우스가 정상적으로 설치되었음을 확인할 수 있다.

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE

deployment.apps/ingress-nginx-controller   1/1     1            1           2d
deployment.apps/prometheus-server          1/1     1            1           2d

프로메테우스 접속

  • 프로메테우스를 포트포워딩한다.
kubectl --namespace ingress-nginx port-forward svc/prometheus-server 9090
  • 프로메테우스에 접속한다.
  • 프로메테우스가 ingress-controller로부터 메트릭 정보를 받아올 수 있는 지 확인한다.
  • 위에서 ingress-nginx 컨트롤러 환경변수 설정 을 진행하였었다면 확인이 가능해야한다.nginx_ingress_controller_success 검색 시 GET / 등의 메소드 성공 관련 정보를 받을 수 있다.

그라파나 적용

그라파나 설치

레퍼런스

  • k8s 에 그라파나를 배포한다.
    $ kubectl apply --kustomize github.com/kubernetes/ingress-nginx/deploy/grafana/
    # 결과:
    service/grafana created
    deployment.apps/grafana created
  • k8s 에 그라파나가 정상적으로 설치되었는 지 확인한다.
$ kubectl get all -n ingress-nginx | grep grafana
# 그라파나가 정상적으로 설치되었음을 확인할 수 있다.

NAME                                         TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
service/grafana                              NodePort       10.109.147.15    <none>        3000:31922/TCP               2d
service/ingress-nginx-controller             LoadBalancer   10.107.148.172   localhost     80:32619/TCP,443:30300/TCP   2d
service/ingress-nginx-controller-admission   ClusterIP      10.105.3.33      <none>        443/TCP                      2d
service/ingress-nginx-controller-metrics     ClusterIP      10.111.99.250    <none>        10254/TCP                    2d
service/prometheus-server                    NodePort       10.106.250.37    <none>        9090:32565/TCP               2d

그라파나 접속

  • 그라파나를 포트포워딩 한다.
    $ kubectl --namespace ingress-nginx port-forward svc/grafana 3000
  • 그라파나 에 접속한다.

localhost:3000

그라파나 대시보드는 아래 다음을 보고 활성화 할 수 있다.

레퍼런스

profile
기록하고 공유하려고 노력하는 DevOps 엔지니어

0개의 댓글