TIL/Monitoring(k8s, grafana)

[Grafana, K8s, helm] grafana sidecard를 활용한 dashboard provisioning in k8s

쓱쓱565 2025. 4. 29. 22:35

환경

  • Grafana
  • K8S
  • Helm
  • ArgoCD

tl;dr

  • grafana sidecar를 활용해 json 파일로 저장된 custom dashboard를 손쉽게 저장할 수 있다.

설정 - dashboard-config.yaml

# dashboard-config.yaml
{{- range $category, $dashboards := .Values.grafana.dashboards }}
  {{- range $name, $dash := $dashboards }}
    {{- if $dash.file }}
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ printf "grafana-dashboard-%s" $name | trunc 63 | trimSuffix "-" }}
  labels:
    grafana_dashboard: "1"
    dashboard-category: {{ $category }}
data:
  {{ $name }}.json: |-
{{ $.Files.Get (toString $dash.file) | indent 4 }}
    {{- end }}
  {{- end }}
{{- end }}

설정 - values.yaml

grafana:
  enabled: true
  persistence:
    enabled: true
  datasources:
    datasources.yaml:
      datasources:
      - name: Loki
        type: loki
        access: proxy
        url: http://loki:3100
        jsonData:
          maxLines: 1000
      - name: Prometheus
        type: prometheus
        access: proxy
        url: https://prometheus-server:9090
  sidecar:
    dashboards:
      enabled: true
      label: grafana_dashboard
      labelValue: "1"
      searchNamespace: ALL
      provider:
        allowUiUpdates: true
  dashboardProviders:
    dashboardproviders.yaml:
      apiVersion: 1
      providers:
      - name: 'default'
        orgId: 1
        folder: 'Default'
        type: file
        disableDeletion: false
        editable: true
        options:
          path: /var/lib/grafana/dashboards/default
      - name: 'metric'
        orgId: 1
        folder: 'Metrics'
        type: file
        disableDeletion: false
        editable: true
        options:
          path: /var/lib/grafana/dashboards/metric
      - name: 'logs'
        orgId: 1
        folder: 'Logs'
        type: file
        disableDeletion: false
        editable: true
        options:
          path: /var/lib/grafana/dashboards/logs
  dashboards:
    default:
      main-dashboard:
        file: "dashboards/main-dashboard.json"
    metric:
      metric-cluster-global-performance:
        file: "dashboards/metric-cluster-global-performance.json"
      metric-kubernetes-views-namespace:
        file: "dashboards/metric-kubernetes-views-namespace.json"
      metric-kubernetes-views-nodes-list:
        file: "dashboards/metric-kubernetes-views-nodes-list.json"
      metric-kubernetes-views-nodes:
        file: "dashboards/metric-kubernetes-views-nodes.json"
      metric-kubernetes-views-pods:
        file: "dashboards/metric-kubernetes-views-pods.json"
      metric-node-exporter-full:
        file: "dashboards/metric-node-exporter-full.json"
    logs:
      log-kubernetes-event-exporter:
        file: "dashboards/log-kubernetes-event-exporter.json"
      log-loki-kubernetes-logs:
        file: "dashboards/log-loki-kubernetes-logs.json"

해결에 오래 걸렸던 이유

  • Docker-compose 및 process 환경에서도 Grafana를 구동중이었음. 각각 환경에서 사용중인 '파일 시스템' 활용한 provisioning과 volumn mount 방식의 provisioning 방식만 익숙해졌음.
  • sidecar 관련 옵션에 익숙하지 않았음.
  • k8s에서도 volumne mount 하는 방식은 굉장히 비효율적으로 느껴짐.
  • var/lib/dashboard 하위에 custom dashboard들의 json파일을 넣는 방식 > 마찬가지로 비효율적이며, 유지보수에 매우 불리함.

grafana helm chart - values.yaml - sidecar 설명.

  • 공식 문서에서 sidecar 관련 설명을 읽을 수 있는 거의 유일한 부분.
  • label 기반으로 configmap을 수집, include시킨 파일을 적절한 경로에 저장한다고 한다.
# https://github.com/grafana/helm-charts/blob/1256a0193f8da3234334212982c116180fed9015/charts/grafana/values.yaml#L730-L738

## Sidecars that collect the configmaps with specified label and stores the included files them into the respective folders
## Requires at least Grafana 5 to work and can't be used together with parameters dashboardProviders, datasources and dashboards
sidecar:
  image:
    repository: quay.io/kiwigrid/k8s-sidecar
    tag: 1.19.2
    sha: ""
  imagePullPolicy: IfNotPresent
  resources: {}
  • grafana docs 및 google 검색으로도 해당 기능을 소개하지 않음.

배운 점

  • 검색을 최대한 다양하게 해볼 것
  • 오픈소스 특성상 docs에 고의적으로 누락시키는 설명들이 존재함. 코드를 열어서 전체 겁색하는 습관을 들일 것.