공부/Monitoring

[Grafana Loki] Errors loading rules

haejang 2023. 7. 27. 22:00
728x90
728x90

 

 

# 상황

- 중앙 EKS 클러스터에 grafana chart를 사용해 Grafana가 설치되어 있음

- 각 EKS 클러스터별로 loki-stack chart를 사용해 Loki와 promtail이 설치되어 있음

- 각 EKS 클러스터별로 kube-prometheus-stack chart를 통해 Prometheus와 AlertManager가 설치되어 있음

(로키 스택에서 프로메테우스도 전부 깔 수 있지만, 프로메테우스가 먼저 깔려있는 상태에서 로키 도입하다 보니 이렇게 됨)

 

 

# 문제 상황

Grafana와 Loki를 별도로 쿠버네티스 위에 띄우고, Grafana에서 Data Source로 Loki를 추가했습니다.

Connection Test는 성공하지만,,,

위 사진처럼 Alert rules로 가면 로키 데이터소스에서 Rule을 불러오는데 실패한다고 뜹니다.

Full 에러메세지는 아래와 같습니다.

Errors loading rules
Failed to load the data source configuration for <Loki Datasource Name>: Unable to fetch alert rules. Is the <Loki Datasource Name> data source property configured?

 

https://grafana.com/docs/loki/latest/api/

 

Grafana Loki HTTP API | Grafana Loki documentation

Open source Grafana Loki HTTP API Grafana Loki exposes an HTTP API for pushing, querying, and tailing log data. Note that authenticating against the API is out of scope for Loki. Microservices mode When deploying Loki in microservices mode, the set of endp

grafana.com

 

분명 /ruler/ring 이란 API도 존재하지만...존재하지 않습니다 (?)

 

 

# 깨달음

https://grafana.com/docs/loki/latest/rules/

 

Alerting and Recording Rules | Grafana Loki documentation

Open source Alerting and Recording Rules Grafana Loki includes a component called the ruler. The ruler is responsible for continually evaluating a set of configurable queries and performing an action based on the result. This example configuration sources

grafana.com

 

Loki 설치 시 Alert용 Rule은 별도 설정 없이는 기본으로 제공되는 템플릿이 없습니다. 저에게 당장 필요한건 아니지만 (아직 시범구축 단계) 빨간 에러 메세지를 계속 보고싶진 않으니 처리해 보겠습니다.

 

처리맨이 너굴해 보겠습니다.

 

 

# ruler config 추가

Loki Chart에 Example 설정이 주석처리되어 존재합니다.

loki:
  config:
    ruler:
      storage:
        type: local
        local:
          directory: /rules
      rule_path: /tmp/scratch
      alertmanager_url: http://alertmanager.svc.namespace:9093
      ring:
        kvstore:
          store: inmemory
      enable_api: true

 

alertmanager_url만 바꿔주도록 하겠습니다. 전 kube-prometheus-stack을 통해 알랏매니저를 깔아놨기 때문에 kube-prometheus-stack-alertmanager 라는 서비스 이름으로 바꿔주겠습니다. (네임스페이스는 동일하므로 생략)

 

즉, 실제로는 아래와 같이 추가해 주었습니다.

loki:
  config:
    ruler:
      storage:
        type: local
        local:
          directory: /rules
      rule_path: /tmp/scratch
      alertmanager_url: http://kube-prometheus-stack-alertmanager:9093
      ring:
        kvstore:
          store: inmemory
      enable_api: true

 

# 한번에 될리가 없지

위에처처럼만 추가하면 아래와 같은 에러가 뜹니다.

⚠️ msg="error running loki" err="mkdir /rules: read-only file"

생각해보면 당연합니다. /rules 라는 디렉토리를 사용하는 로컬 볼륨을 사용하겠다고 명시해 두었지만, 그런 볼륨을 만들지도 마운트해주지도 않았습니다.

 

https://github.com/grafana/helm-charts/issues/577#issuecomment-1404782937

/rules 로컬 볼륨만 마운트해주려고 조금 알아보던 중, Demonsthere씨가 Loki에선 2개 볼륨/볼륨마운트가 필요하다고 알려주십니다.

1. Full 권한을 가져야 하는 디렉토리

  • 로키 서버 설치 후, 콘솔이나 API 등을 통해 Rule을 생성하게 되는 경우 그에 대한 정보가 저장되는 경로를 뜻하게 되는 것 같습니다.
  • Read 권한은 물론, 서버에서 Write할 권한이 같이 필요합니다.
  • Demonsthere씨는 /rules 경로를 사용하는 loki-rules-generated 란 Local Volume으로 정의해 두었습니다.

2. Read 만 해도 되는 디렉토리

  • 로키 서버 설치 시 물고 올라가는, Rule에 대한 설정들이 있는 경로를 뜻하는 것 같습니다.
  • 따라서 서버에서 Write까진 필요없습니다.
  • Demonsthere씨는 /var/loki/rules 경로를 사용하는 loki-rules 란 Volume으로 정의해 두었습니다.
  • 그리고, 이 친구는 loki-alertinggroups 란 ConfigMap을 실제 볼륨으로 사용합니다....

 

 

# 저 ConfigMap은 어떻게 만들죠

loki stack chart에서 alert 관련해서 만들어진 configmap이 없어서 뭐지...직접 만들어야 하나... 라고 생각하던 중,

{{ template "loki.fullname" . }}-alerting-rules 이란 이름으로 ConfgMap을 만들어질 수 있단 것을 확인했습니다.

이 CM을 만들기 위해서는

  • useExistingAlertingGroup.enabledtrue로 바꾸고, 이미 존재하는 CM을 useExistingAlertingGroup.configmapName 에 매핑시켜 주거나
  • 새 룰을 하나 alerting_groups 에 작성해 줌으로써 만들 수 있습니다.

저희는 미리 만들어둔 CM은 없으니까, alerting_groups에 예시로 제공하는 룰을 하나 넣어주겠습니다.

loki:
  alerting_groups:
  - name: example-${cluster_name}
    rules:
    - alert: HighThroughputLogStreams
      expr: sum by(container) (rate({job=~"loki-dev/.*"}[1m])) > 1000
      for: 2m

마찬가지로 기본으로 제공되는 예시를 그대로 사용했는데, 모든 클러스터의 로키들이 동일한 이름의 rule을 가지면 식별하기 어려우므로 클러스터 이름을 group name에 추가해 주었습니다.

 

 

# 최종

본 글에서 추가된 loki-stack의 value는 아래와 같습니다.

loki:
  config:
    # Example 활용
    ruler:
      storage:
        type: local
        local:
          directory: /rules
      rule_path: /tmp/scratch
      # 현재 클러스터에 깔려있는 prometheus alertmanager svc name으로 대체
      alertmanager_url: http://kube-prometheus-stack-alertmanager:9093
      ring:
        kvstore:
          store: inmemory
      enable_api: true

  # Example 활용
  alerting_groups:
  # Cluster별로 다른 이름을 갖게 하기 위해 클러스터 네임 추가
  - name: example-${cluster_name}
    rules:
    - alert: HighThroughputLogStreams
      expr: sum by(container) (rate({job=~"loki-dev/.*"}[1m])) > 1000
      for: 2m
  # https://github.com/grafana/helm-charts/issues/577#issuecomment-1404782937 참조
  extraVolumes:
    - name: loki-rules-generated
      emptyDir: {}
    - name: loki-rules
      configMap:
        # 템플릿에 맞게 생성될 이름으로 대체.
        # 나는 loki-stack 이란 이름으로 Release하기 때문에 loki-stack-alerting-rules 로 만들어진다.
        name: loki-stack-alerting-rules
  extraVolumeMounts:
    - name: loki-rules-generated
      mountPath: /rules
    - name: loki-rules
      mountPath: /var/loki/rules

이렇게 변경하고 helm을 upgrade 해주면…

 

Rule이 잘 추가된 것을 확인할 수 있습니다.

 

너굴완료.

 

 

 

 

 

728x90
728x90