엔지니어링

Elasticsearch Observability: 메트릭에 대한 Prometheus 및 OpenMetrics 표준 수용

이 블로그에서는 다음을 다룹니다.

  • 오픈 표준이 중요한 이유
  • Prometheus 설명 형식
  • Elastic에서 observability를 고려하는 방식
  • Elasticsearch에서 Prometheus 메트릭을 소비하는 세 가지 방식
  • Prometheus Redis 내보내기에서 노출되는 메트릭을 수집하고 시각화하는 방식의 예시

오픈 표준

웹페이지 opensource.com에는 다음과 같은 제목의 정보 전달형 자료가 있습니다. "오픈 표준이란 무엇인가요?". 이 문서에는 여러 중요한 강조점이 있지만 운영 부서에서 몇 년의 경험을 쌓은 저로서는 다음 사항이 가장 공감되는 내용이었습니다.

  1. 가용성: 오픈 표준은 모두가 읽고 구현할 수 있도록 공개되어 있습니다.
  2. 최종 사용자 선택을 최대화
  3. 차별 없음(공급업체 중립성): 오픈 표준과 이를 적용하는 조직에서는 하나의 구현자를 다른 하나에 비해 선호하지 않습니다.
  4. 의도적인 기밀 없음: 표준은 상호 운용 가능한 구현에 필요한 어떠한 세부 사항도 숨기지 않아야 합니다.

이러한 사항이 오픈 표준이 좋은 이유이며 이제는 Prometheus 설명 형식 OpenMetrics의 기반이 되는 이유를 살펴보겠습니다. Richard Hartmann은 그의 PromCon 2018 및 KubeCon + CloudNativeCon North America 2018에서 Prometheus 설명 형식에 의해 영향을 받은 오픈 표준을 생성하는 이유를 이렇게 요약했습니다.

  • 대부분의 데이터는 독점적이며, 구현이 어렵거나 두 가지 모두에 해당합니다
  • Prometheus는 사실상 클라우드 네이티브 메트릭 모니터링에서 표준이 되었습니다
  • 설명 데이터의 편의성은 호환 가능한 메트릭 엔드포인트의 급격한 성장으로 이어졌습니다
  • Prometheus의 설명 형식은 많은 운영 경험에 기반을 둔 것이었으나 몇몇 사람들 사이에서 설계되었습니다
  • 일부 기타 프로젝트와 공급업체는 “경쟁하는” 제품의 무언가를 도입하는 것에 대한 의견이 양분되었습니다

Prometheus 설명 형식

설명 형식에 대한 자세한 정보는 Prometheus Github 보관소에서 읽어보실 수 있습니다. 지금은 예시를 살펴보겠습니다. 여기 /metrics 엔드포인트로 포트 9121에서 메트릭을 게시하는 Oliver006's Redis 내보내기가 있습니다. 저는 지금 여기에 Redis “초당 동시 운영” 메트릭에 대한 정보를 보여드리고 있을 뿐입니다. 판독할 정보는 세 줄 뿐입니다.

  1. 도움말 텍스트
  2. 메트릭 유형(이 경우 게이지)
  3. 측정된 Redis 서버(로컬호스트 포트 6379), 및 현재 판독값(초당 ops 9개)

roscigno-prometheus-exposition-format.png

Elastic의 Observability

여러분께서 Elastic에서 Observability를 어떤 방식으로 고려하는지에 대한 글을 읽어보시길 권장하지만 다음은 제가 게시글에서 가장 좋아하는 구절입니다.

‘관측 가능한’ 시스템을 설계하고 구축하는 것의 목표는 시스템이 생산 단계에서 실행되는지 확인하고 시스템 관리 운영자가 바람직하지 않은 동작(예: 서비스 중단 시간, 오류, 느린 응답)을 감지할 수 있으며, 효과적인 방식(예: 자세한 이벤트 로그, 세분화된 리소스 사용 정보 및 애플리케이션 추적)으로 근본 원인을 찾아내어 조치 가능한 정보를 획득하는 것입니다.

이는 제가 진정으로 공감하는 말이며 이를 통해 우리가 제공하는 서비스를 실행, 정비 및 관리하기 위해 모든 로그, 메트릭 및 추적 정보가 필요하다는 점을 알 수 있습니다. Prometheus는 광범위한 도입 및 활성화된 커뮤니티로 인해 observability의 매우 중요한 일부분이라고 할 수 있습니다. OpenMetrics 표준은 실제로든 인식한 것이든 장벽을 없애고 상식적인 “born in ops” 메트릭 형식을 도입함으로써 가치가 계속 높아질 일밖에 남지 않았습니다.

저와 이야기를 나눈 대부분의 사람들은 로깅에 있어 Elastic Stack 또는 ELK와 굉장히 친숙합니다. Elastic Stack이 메트릭과 APM에도 훌륭하다는 점을 모르고 계셨다면 메트릭 APM / 분산 추적에 대한 당사 정보를 확인해 보세요.

메트릭을 내보내기 하는 방식으로서 Elastic Stack와 Prometheus간의 깊은 통합에 관심을 가진 주요 이유는 다음과 같습니다.

  • Elasticsearch에서 메트릭과 로그 및 APM을 결합하고 이를 Kibana에서 상호 비교합니다. Elastic Stack에서 로그와 메트릭 결합에 대한 NS1의 사용자 이야기를 확인해 보세요.
  • 현재 네이티브 클러스터링을 지원하지 않는 Prometheus 서버에서 수집한 메트릭의 장기 저장을 위해 Elasticsearch를 사용합니다.
  • 지역적으로 분포되어 있는 Prometheus 인스턴스 전반에서 메트릭에 대한 글로벌 뷰를 생성합니다.

블로그의 나머지 내용에는 당사에서 이러한 통합에 접근하는 방식이 설명되어 있습니다.

샘플 내보내기

제 데모 환경은 Google Kubernetes Engine(GKE)에서 실행 중이어서 애플리케이션과 Metricbeat, 그리고 Prometheus 내보내기를 모두 Kubernetes에서 실행 중입니다. 이는 Redis 내보내기를 Redis 이미지를 동반한 사이드카로서 Redis 내보내기를 배포하는 Oliver006의 메니페스트 일부입니다. 내보내기는 포트 9121에서 게시되고 있으며 이는 Prometheus Redis 내보내기에 대한 기본 할당 포트 번호 입니다.

...
  - name: redis-exporter
    image: oliver006/redis_exporter:latest
    resources:
      requests:
        cpu: 100m
        memory: 100Mi
    ports:
    - containerPort: 9121
...

전체 소스는 GitHub에서 확인

Metricbeat Prometheus 모듈로 메트릭 스크랩

Metricbeat는 Elastic의 메트릭에 대한 경량 데이터 전송 프로그램입니다. Metricbeat과 함께 전송하는 Prometheus 모듈은 세 가지 방식으로 메트릭을 수집할 수 있습니다:

  1. 포트 9090에서 Prometheus 서버에 연결하여 Prometheus 페더레이션 API 를 사용해 이미 수집된 메트릭을 수집(Prometheus가 수집하는 메트릭을 얻기 위해)
  2. /metrics 엔드포인트를 사용해 포트 9090에서 Prometheus 서버에 연결(Prometheus 자가 모니터링)
  3. Prometheus 내보내기에 개별적으로 연결하고 설명 형식을 구문 분석

다른 방식과 비교해 한 가지 접근 방식을 선택하는 이유는 무엇일까요? 이는 Prometheus 서버와의 편안함 정도에 따라 다릅니다.

  • 메트릭을 스크랩하기 위해 Prometheus 서버를 이미 설정하지 않았고 통합 목적을 위해 이러한 메트릭을 직접 쿼리하고자 하는 경우 옵션 (1) 및 (2)로 시작하실 수 있습니다.
  • 그러나 이미 Prometheus 서버가 준비되어 있지 않거나 내보내기를 여러 도구로 병렬 스크랩하는 것을 개의치 않는 경우 옵션 (3)을 선택하실 수 있습니다.

참고: 상기 Metricbeat 기능의 일부는 Metricbeat 버전 7.0에서 베타 버전입니다. 따라서 7.0 베타를 다운로드하시거나 컨테이너 링크를 https://www.docker.elastic.co/에서 복사해 비생산 환경에서 베타를 실행할 것을 권장합니다.

Prometheus 페더레이션 API

일반적으로 페더레이션은 조정 활성화, 데이터세트를 함께 가져오거나 서로 다른 위치에서 사용할 수 있는 데이터의 복사본을 만들 때(재난 복구용) 사용합니다. Prometheus 서버에서는 /페더레이션 엔드포인트를 제공하며 Elastic은 위에 설명한 모든 이유를 위해 Prometheus에서 수집한 메트릭을 복사하고자 이 엔드포인트에 연결합니다.

...
  - module: prometheus
    period: 10s
    hosts: ["prometheus-service.monitoring.svc.cluster.local:9090"]
    metrics_path: '/federate'
    query:
      'match[]': '{__name__!=""}'
...

GitHub에서 전체 소스 참조

위 예시에서는 쿼리가 “공백이 아닌 이름으로 된 모든 값”으로 설정되어 있습니다. 모든 것을 수집하는 것이 좋으며 Prometheus 문서에는 더욱 제한적인 일치 조건을 작성할 수 있는 방법이 나와 있습니다. 예시는 또한 Pometheus 서버에 10초마다 연결하며 제 데모 서버는 몇몇 pod와 kube-state-metrics에서만 수집하고 있지만 이 주기를 변경하시는 것이 좋습니다.

Prometheus 자가 모니터링

Prometheus에서는 내보내기와 동일하게 /metrics 엔드포인트를 제공합니다. 이는 Prometheus 서버에 대한 메트릭을 수집할 수 있도록 하기 위함입니다. 이는 다음과 같이 구성됩니다.

...
  - module: prometheus
    period: 10s
    hosts: ["prometheus-service.monitoring.svc.cluster.local:9090"]
    metrics_path: /metrics
...

전체 소스는 GitHub에서 확인

Prometheus 내보내기 스크랩

Metricbeat DaemonSet를 배포하기 위한 메니페스트의 YAML의 일부는 Metricbeat에 대해 kubernetes.labels.app == redis로 자동 검색할 것을 지시하고 해당 pod의 포트 9121에서 메트릭을 읽습니다. Redis 내보내기 컨테이너에 대해 설정된 containerPort는 9121이라는 것을 기억하실 겁니다.

...
- condition.equals:
    kubernetes.annotations.prometheus.io/scrape: "true"
  config:
    - module: prometheus
      period: 10s
      # Redis pods
      hosts: ["${data.host}:9121"]
      metrics_path: /metrics
...

Metricbeat가 배포되면 해당 조건인 kubernetes.labels.app == redis을 만족하는 모든 pod에는 적용된 Prometheus 모듈과 포트 9121에서 내보내기 사이드카로부터 수집된 메트릭이 있습니다.

하지만 메타데이터는 k8s 세계를 돌게 하는 원동력이지 않습니까? 이제 메타데이터와 Beats 자동 검색 기능을 좀 더 실행해보겠습니다. 상기 YAML의 일부에 대한 대체물을 확인해 주십시오.

...
- condition.equals:
    kubernetes.annotations.prometheus.io/scrape: "true"
  config:
    - module: prometheus
      period: 10s
      hosts: ["${data.host}:${data.kubernetes.annotations.prometheus.io/port}"]
      metrics_path: /metrics
...

전체 소스는 GitHub에서 확인

이제 Redis pod에 대한 내보내기를 찾는 대신 kubernetes.annotations.prometheus.io/scrape의 각주가 참으로 설정된 모든 pod에 대한 내보내기를 찾아 보겠습니다. 이는 또한 Prometheus 자동 검색이 설정된 방식이기도 합니다. 일반적으로 Metricbeat 자동 검색은 elastic.co 네임스페이스의 각주에 따라 구동되지만 지금 Prometheus 내보내기로부터의 판독값을 다루고 있으므로 Prometheus와 연관된 표준 k8s 각주를 적용해야 합니다. 위에서 호스트 목록을 살펴보면:

hosts: ["${data.host}:${data.kubernetes.annotations.prometheus.io/port}"]

포트 9121는 Redis 내보내기의 포트이기 때문에 이를 더이상 하드코딩하지 않는 것을 보실 수 있습니다. 각주 prometheus.io/port가 내보내기에 대한 포트 번호에 설정되어 있습니다. 완전함을 위해 이러한 각주가 설정되어 있는 guestbook.yaml의 일부를 보여드리겠습니다.

...
kind: Deployment
metadata:
  name: redis-master
spec:
  replicas: 1
  template:
    metadata:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9121"
      labels:
        app: redis
...

전체 소스는 GitHub에서 확인

메타데이터는 k8s의 세계를 돌아가게 한다고 말씀드렸습니다. 이게 아마 70년대 노래이지 않았나 싶네요.

인사이트를 얻기 위한 시각화

데이터를 Elastic Stack으로 가져오는 것은 좋지만 일단 데이터와 상호작용할 수 있어야 합니다. 아래 영상에서는 Prometheus에서 스크랩한(이후 Elastic Stack에 가져온) Redis 메트릭과 Metricbeat으로 직접 kube-state-metrics에서 수집한 Kubernetes 이벤트를 사용해 유용한 시각화 구축에 접근하는 방법을 보실 수 있습니다.

영상과 함께 따라하며 자세한 안내를 받고자 하시는 경우 먼저 예시 보관소를 참조하십시오.

Observability로 돌아와서

마지막 섹션에서는 Olive006의 Redis 내보내기로 노출된 주요 Redis 메트릭에 대한 Kibana 시각화(초당 즉각 ops)를 생성했습니다. 다음 단계는 로그를 수집하고 대시보드를 생성해 애플리케이션 전반에서 로그 및 메트릭을 함께 결합하는 것입니다.

Kubernetes 환경에서 로그를 수집하는 방법에 대해 알아보시려면 먼저 elastic/examples GitHub 보관소에 있는 지침을 따를 것을 권장합니다. 몇 분만에 Filebeat, Metricbeat 및 Packetbeat에서 데이터를 수집해 Elasticsearch에 게시할 수 있습니다. 서로 다른 Beat로 전송하는 샘플 대시보드가 있으며 여러분이 Prometheus 데이터에 대한 시각화를 자체적으로 자유롭게 생성해 시각화를 함께 혼합하여 작업하는 방식에 맞는 대시보드를 생성할 수 있습니다. 문제를 겪거나 observability에 대한 이야기를 나누고자 할 경우 토론 포럼에 글을 남겨 주세요.