add grafana operator

This commit is contained in:
2025-05-14 22:15:41 -05:00
parent 9018ba7bd3
commit 0f12ce25c7
9 changed files with 453 additions and 2 deletions

View File

@@ -0,0 +1,27 @@
apiVersion: v2
name: grafana-operator
version: 1.0.0
description: Grafana Operator
keywords:
- grafana-operator
- dashboard
- metrics
- logs
home: https://wiki.alexlebens.dev/s/3e5723e1-2ab7-45ab-b496-b8854907fa39
sources:
- https://github.com/grafana/grafana-operator
- https://github.com/cloudnative-pg/cloudnative-pg
- https://github.com/grafana/grafana-operator/tree/master/deploy/helm/grafana-operator
- https://gitea.alexlebens.dev/alexlebens/helm-charts/src/branch/main/charts/postgres-cluster
maintainers:
- name: alexlebens
dependencies:
- name: grafana-operator
version: v5.18.0
repository: oci://ghcr.io/grafana/helm-charts/grafana-operator
- name: postgres-cluster
alias: postgres-17-cluster
version: 5.0.7
repository: oci://harbor.alexlebens.net/helm-charts
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/grafana.png
appVersion: v5.18.0

View File

@@ -0,0 +1,62 @@
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: grafana-auth-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: {{ .Release.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: admin-user
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/grafana/auth
metadataPolicy: None
property: admin-user
- secretKey: admin-password
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/grafana/auth
metadataPolicy: None
property: admin-password
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: grafana-oauth-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: grafana-oauth-secret
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: AUTH_CLIENT_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /authentik/oidc/grafana
metadataPolicy: None
property: client
- secretKey: AUTH_CLIENT_SECRET
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /authentik/oidc/grafana
metadataPolicy: None
property: secret

View File

@@ -0,0 +1,18 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: grafana-operator-dashboard
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: grafana-operator-dashboard
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
instanceSelector:
matchLabels:
app.kubernetes.io/name: grafana-main
grafanaCom:
id: 22785
revision: 2

View File

@@ -0,0 +1,60 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDatasource
metadata:
name: grafana-operator-prometheus-datasource
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: grafana-operator-prometheus-datasource
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: metrics
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
datasource:
name: Prometheus
type: prometheus
url: http://kube-prometheus-stack-prometheus.kube-prometheus-stack:9090/
access: proxy
isDefault: true
jsonData:
timeInterval: 30s
instanceSelector:
matchLabels:
app.kubernetes.io/name: grafana-main
plugins:
- name: grafana-clock-panel
version: 1.3.0
- name: marcusolsson-treemap-panel
version: 2.0.1
- name: camptocamp-prometheus-alertmanager-datasource
version: 2.1.0
uid: kube-prometheus-stack
---
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDatasource
metadata:
name: grafana-operator-loki-datasource
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: grafana-operator-loki-datasource
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: logs
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
datasource:
name: Loki
type: loki
url: http://loki.loki:3100
jsonData:
httpHeaderName1: "X-Scope-OrgID"
secureJsonData:
httpHeaderValue1: "1"
instanceSelector:
matchLabels:
app.kubernetes.io/name: grafana-main
plugins:
- name: grafana-lokiexplore-app
version: 1.0.15
uid: loki

View File

@@ -0,0 +1,109 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaFolder
metadata:
name: grafana-folder-application
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: grafana-folder-application
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
instanceSelector:
matchLabels:
app.kubernetes.io/name: grafana-main
title: Application
uid: grafana-folder-application
resyncPeriod: 10m0s
permissions: |
{
"items": [
{
"role": "Admin",
"permission": 4
},
{
"role": "Editor",
"permission": 2
},
{
"role": "Viewer",
"permission": 1
}
]
}
---
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaFolder
metadata:
name: grafana-folder-service
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: grafana-folder-service
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
instanceSelector:
matchLabels:
app.kubernetes.io/name: grafana-main
title: Service
uid: grafana-folder-service
resyncPeriod: 10m0s
permissions: |
{
"items": [
{
"role": "Admin",
"permission": 4
},
{
"role": "Editor",
"permission": 2
},
{
"role": "Viewer",
"permission": 1
}
]
}
---
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaFolder
metadata:
name: grafana-folder-system
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: grafana-folder-system
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
instanceSelector:
matchLabels:
app.kubernetes.io/name: grafana-main
title: System
uid: grafana-folder-system
resyncPeriod: 10m0s
permissions: |
{
"items": [
{
"role": "Admin",
"permission": 4
},
{
"role": "Editor",
"permission": 2
},
{
"role": "Viewer",
"permission": 1
}
]
}

View File

@@ -0,0 +1,107 @@
apiVersion: grafana.integreatly.org/v1beta1
kind: Grafana
metadata:
name: grafana-main
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: grafana-main
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/component: web
app.kubernetes.io/part-of: {{ .Release.Name }}
spec:
config:
analytics:
check_for_updates: false
server:
domain: alexlebens.net
root_url: https://grafana.alexlebens.net
log:
mode: "console"
security:
admin_user: ${ADMIN_USER}
admin_password: ${ADMIN_PASSWORD}
users:
auto_assign_org: true
auto_assign_org_id: 1
auth:
disable_login_form: true
oauth_auto_login: true
signout_redirect_url: https://authentik.alexlebens.net/application/o/grafana/end-session/
auth.generic_oauth:
enabled: true
name: Authentik
allow_sign_up: true
client_id: ${AUTH_CLIENT_ID}
client_secret: ${AUTH_CLIENT_SECRET}
scopes: openid profile email
auth_url: https://authentik.alexlebens.net/application/o/authorize/
token_url: https://authentik.alexlebens.net/application/o/token/
api_url: https://authentik.alexlebens.net/application/o/userinfo/
role_attribute_path: contains(groups, 'Grafana Admins') && 'Admin' || contains(groups, 'Grafana Editors') && 'Editor' || 'Viewer'
database:
type: postgres
host: "${DB_HOST}:${DB_PORT}"
name: ${DB_DATABASE}
user: ${DB_USER}
password: ${DB_PASSWORD}
unified_alerting:
enabled: true
ha_listen_address: "${POD_IP}:9094"
ha_peers: "grafana-alerting:9094"
ha_advertise_address: "${POD_IP}:9094"
ha_peer_timeout: 15s
ha_reconnect_timeout: 2m
deployment:
spec:
template:
spec:
containers:
- name: grafana
image: grafana/grafana:12.0.0
env:
- name: AUTH_CLIENT_ID
valueFrom:
secretKeyRef:
name: grafana-oauth-secret
key: AUTH_CLIENT_ID
- name: AUTH_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: grafana-oauth-secret
key: AUTH_CLIENT_SECRET
- name: ADMIN_USER
valueFrom:
secretKeyRef:
name: grafana-auth-secret
key: admin-user
- name: ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: grafana-auth-secret
key: admin-password
- name: DB_HOST
valueFrom:
secretKeyRef:
name: grafana-operator-postgresql-17-cluster-app
key: host
- name: DB_DATABASE
valueFrom:
secretKeyRef:
name: grafana-operator-postgresql-17-cluster-app
key: dbname
- name: DB_PORT
valueFrom:
secretKeyRef:
name: grafana-operator-postgresql-17-cluster-app
key: port
- name: DB_USER
valueFrom:
secretKeyRef:
name: grafana-operator-postgresql-17-cluster-app
key: user
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: grafana-operator-postgresql-17-cluster-app
key: password

View File

@@ -0,0 +1,30 @@
# apiVersion: gateway.networking.k8s.io/v1
# kind: HTTPRoute
# metadata:
# name: http-route-grafana
# namespace: {{ .Release.Namespace }}
# labels:
# app.kubernetes.io/name: http-route-grafana
# app.kubernetes.io/instance: {{ .Release.Name }}
# app.kubernetes.io/version: {{ .Chart.AppVersion }}
# app.kubernetes.io/component: web
# app.kubernetes.io/part-of: {{ .Release.Name }}
# spec:
# parentRefs:
# - group: gateway.networking.k8s.io
# kind: Gateway
# name: traefik-gateway
# namespace: traefik
# hostnames:
# - grafana.alexlebens.net
# rules:
# - matches:
# - path:
# type: PathPrefix
# value: /
# backendRefs:
# - group: ''
# kind: Service
# name: grafana
# port: 80
# weight: 100

View File

@@ -0,0 +1,38 @@
grafana-operator:
replicas: 2
serviceAccount:
create: true
rbac:
create: true
resources:
requests:
cpu: 10m
memory: 64Mi
serviceMonitor:
enabled: true
dashboard:
enabled: false
postgres-17-cluster:
mode: standalone
cluster:
storage:
storageClass: local-path
walStorage:
storageClass: local-path
monitoring:
enabled: true
prometheusRule:
enabled: true
recovery:
method: objectStore
objectStore:
endpointURL: https://nyc3.digitaloceanspaces.com
destinationPath: s3://postgres-backups-ce540ddf106d186bbddca68a/cl01tl/grafana-operator/grafana-operator-postgresql-17-cluster
endpointCredentials: grafana-operator-postgresql-17-cluster-backup-secret
recoveryIndex: 1
backup:
enabled: true
endpointURL: https://nyc3.digitaloceanspaces.com
destinationPath: s3://postgres-backups-ce540ddf106d186bbddca68a/cl01tl/grafana-operator/grafana-operator-postgresql-17-cluster
endpointCredentials: grafana-operator-postgresql-17-cluster-backup-secret
backupIndex: 1

View File

@@ -85,8 +85,8 @@ grafana:
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/blocky.json
cert-manager:
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/cert-manager.json
# cloudnativepg:
# url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/cloudnativepg.json
cloudnativepg:
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/cloudnativepg.json
coredns:
url: http://gitea-http.gitea:3000/alexlebens/grafana-dashboards/raw/branch/main/dashboards/service/coredns.json
descheduler: