[Grafana Loki] Errors loading rules
# 상황
- 중앙 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/
분명 /ruler/ring
이란 API도 존재하지만...존재하지 않습니다 (?)
# 깨달음
https://grafana.com/docs/loki/latest/rules/
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.enabled
를true
로 바꾸고, 이미 존재하는 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이 잘 추가된 것을 확인할 수 있습니다.
끝