[Airflow] StatsD Exporter + Prometheus + Grafana On GKE
들어가기 앞서,
- Airflow 운영에 있어서 Airflow 모니터링은 중요한 요소이며, 모니터링은 크게 두 가지 측면으로 구분할 수 있습니다.
- 서비스 측면 (Airflow 컨테이너 동작 여부, DAG 정상 실행 여부 등)
- 시스템 측면 (CPU, Memory 등)
- 해당 포스팅에선 Airflow의 서비스 측면 모니터링을 위해, StatsD Exporter + Prometheus + Grafana를 구성하는 방법에 대해서 다뤄보겠습니다.
- StatsD Exporter
- StatsD는 애플리케이션에서 발생하는 이벤트 및 성능 지표를 수집하고, 이를 모니터링 시스템에 전송하는 데 사용되는 네트워크 데몬 및 프로토콜입니다.
- Airflow 내부적으로 생성된 Metric은, StatsD를 통해 StatsD Exporter에 Push 됩니다.
- StatsD Exporter는 StatsD에서 전송된 메트릭을 Prometheus가 이해할 수 있는 형식으로 변환하여 제공하는 중간자 역할입니다.
- Prometheus
- Prometheus는 모니터링 시스템 및 Timeseries 데이터용 데이터베이스입니다.
- 오픈소스로, 메트릭 수집 및 대시보드를 구축하는데 Grafana와 함께 많이 사용합니다.
- Grafana
- Grafana는 대시보드 툴입니다.
- 시계열 데이터에 대한 대시보드에 특화되어 있는 대시보드 툴이며 Graphite, InfluxDB, Prometheus 등을 지원합니다.
- StatsD Exporter
사전 구성 환경
- Airflow와 Grafana는 GKE에 Helm Chart를 통해 설치되어 있으며, 설치 과정은 생략하겠습니다.
- Airflow Helm Chart : https://github.com/airflow-helm/charts
- Grafana Helm Chart : https://grafana.github.io/helm-charts
StatsD Exporter + Prometheus + Grafana 구조
- Airflow 내부적으로 생성된 Metric은, StatsD를 통해 StatsD Exporter에 Push 됩니다.
- StatsD Exporter는 StatsD로부터 받은 Metric을 저장해둡니다.
- Prometheus는 StatsD Exporter가 저장하고 있는 Airflow Metric을 주기적으로 Scrape(Pull) 합니다.
- Grafana는 Prometheus에 저장된 Airflow Metric을 Pull 하여 대시보드를 구성합니다.
진행 순서
- StatsD Exporter 사용을 위한 Airflow Helm Chart Value 설정
- Prometheus 관련 자원 생성 및 StatsD Exporter Scrape 설정
- Prometheus 자원 생성은 Terraform을 통해 진행하겠습니다.
- Grafana의 Datasource로 Prometheus 추가
StatsD Exporter 사용을 위한 Airflow Helm Chart Value 설정
Airflow가 StatsD Exporter에 Metric을 보내도록 설정합니다.
airflow: config: AIRFLOW__METRICS__STATSD_ON: 'true' AIRFLOW__METRICS__STATSD_HOST: 'localhost' AIRFLOW__METRICS__STATSD_PORT: '9125'
Airflow의 Webserver, Scheduler, Worker Pod에 StatsD Exporter가 extracontainer(sidecar)로 동작하도록 설정합니다.
airflow: extraContainers: - name: prometheus-statsd-exporter image: prom/statsd-exporter:latest imagePullPolicy: Always args: - --web.listen-address=:9102 - --statsd.listen-udp=:9125 ports: - containerPort: 9102 protocol: TCP - containerPort: 9125 protocol: UDP - containerPort: 9125 protocol: TCP
Prometheus는 StatsD Exporter의 URL 주소(K8S Service DNS)를 통해 Metric을 Scrape(Pull) 해야하므로, extramanifests를 사용해 Webserver, Scheduler, Worker의 StatsD Exporter 용 Service를 생성합니다.
extraManifests: - apiVersion: v1 kind: Service metadata: name: scheduler-statsd-exporter spec: selector: app: airflow component: scheduler ports: - port: 9102 targetPort: 9102
- Webserver와 Worker의 Service 생성 코드는 생략하겠습니다.
이후, 생성한 StatsD Exporter의 Service DNS에 /metrics 경로를 추가하여, StatsD Exporter가 Airflow의 Metric을 잘 받아오고 있는지 확인할 수 있습니다.
- 해당 예제에선 “http://scheduler-statsd-exporter.default.svc.cluster.local:9102/metrics” 경로를 통해 확인할 수 있습니다.
Airflow Helm Chart Value는 아래 링크를 통해 참조하실 수 있습니다.
Prometheus 관련 자원 생성 및 StatsD Exporter Scrape 설정
kubernetes_config_map 생성
resource "kubernetes_config_map" "prometheus_config" { metadata { name = "prometheus-config" } data = { "prometheus.yml" = <<EOF global: scrape_interval: 30s evaluation_interval: 30s scrape_timeout: 10s scrape_configs: - job_name: 'airflow-scheduler-metric' static_configs: - targets: ['scheduler-statsd-exporter.default.svc.cluster.local:9102'] EOF } }
- Deployment를 통해 Prometheus Container가 시작될 때,
- Prometheus가 기본 설정 파일(prometheus.yml)을 Container 내부에서 찾아서 실행될 수 있도록,
- Prometheus Container 내부에 마운트할 파일을 kubernetes_config_map을 통해 정의합니다.
- Prometheus 기본 설정 파일(prometheus.yml) 작성 방법은 아래 링크를 참조하실 수 있습니다.
- 위 예제의 scrape_configs에는 Scheduler의 StatsD Exporter만 scrape하도록 설정되어있으며,
- Webserver와 Worker의 StatsD Exporter를 Scrape하는 코드는 생략하겠습니다.
Prometheus Deployment 생성
resource "kubernetes_deployment" "prometheus" { metadata { name = "prometheus" } spec { replicas = 1 selector { match_labels = { app = "prometheus" } } template { metadata { labels = { app = "prometheus" } } spec { container { image = "prom/prometheus" name = "prometheus" args = [ "--config.file=/etc/prometheus/prometheus.yml" ] port { container_port = 9090 } volume_mount { mount_path = "/etc/prometheus/" name = "prometheus-config-volume" } } volume { name = "prometheus-config-volume" config_map { name = kubernetes_config_map.prometheus_config.metadata[0].name } } } } } }
- kubernetes_config_map이 Prometheus Container 내부로 volume mount 될 수 있도록 설정한 뒤,
- Prometheus가 기본 설정 파일을 Container 내부에서 찾아 실행될 수 있도록,
- Prometheus Container 실행 인자로 기본 설정 파일의 경로를 넣어줍니다.
Prometheus Service 생성
resource "kubernetes_service" "prometheus" { metadata { name = "prometheus" } spec { type = "ClusterIP" selector = { app = "prometheus" } port { port = 9090 target_port = 9090 } session_affinity = "None" } }
- Grafana가 Prometheus의 Service DNS 주소를 통해 Prometheus를 Datasource로 등록할 수 있도록 Prometheus 용 Service를 생성합니다.
Grafana의 Datasource로 Prometheus 추가
Grafana 대시보드 접근 → 좌측 톱니바퀴 클릭
Data sources 카테고리에서 “Add new data source” 클릭 → “Prometheus” 선택
Prometheus Data source의 Name을 지정
HTTP URL에 Prometheus의 Service DNS를 삽입
- 해당 예제에선 “http://prometheus.default.svc.cluster.local:9090” 입니다.
Save & test 클릭
이후, 대시보드를 생성한 뒤 Data source를 Prometheus로 지정하고 원하는 패널을 만들면 됩니다.
참고
- https://magaetube.github.io/data/Airflow-Setup-Step-Monitoring/
- https://kodegeek-com.medium.com/monitoring-airflow-with-prometheus-statsd-grafana-and-spicing-the-game-with-b-tree-filesystem-37a6cc072a38
- https://swalloow.github.io/airflow-on-kubernetes-3/
- https://databand.ai/blog/everyday-data-engineering-monitoring-airflow-with-prometheus-statsd-and-grafana/
- https://www.redhat.com/en/blog/monitoring-apache-airflow-using-prometheus
- https://towardsdatascience.com/airflow-in-docker-metrics-reporting-83ad017a24eb
- https://morioh.com/a/b2881fbbd589/airflow-in-docker-metrics-reporting
- https://airflow.apache.org/docs/apache-airflow/stable/administration-and-deployment/logging-monitoring/metrics.html
- https://github.com/prometheus/statsd_exporter