refactor(k8s): consolidate to infra/+apps/ single-source tree, dedicated per-app CNPG (authentik-db/temporal-db), wire monitoring-config, forgejo→cicd ns, drop orphan/stale (data-schemas, ollama, story-crater, sqs/argocd, key-rotation)
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
# logging/grafana-values.yaml
|
||||
# Grafana — dashboarding and log/metrics exploration UI.
|
||||
# Deployed in the logging namespace alongside Loki and Promtail.
|
||||
#
|
||||
# Secrets provided by ArgoCD SOPS CMP plugin:
|
||||
# adminPassword — mounted from the grafana-admin K8s Secret (admin.existingSecret)
|
||||
# OAuth client secret — mounted from the grafana-oidc K8s Secret (envFromSecret below)
|
||||
|
||||
replicas: 1
|
||||
|
||||
# RWO PVC (Longhorn) — old pod must fully terminate before the new one can
|
||||
# mount the volume. Recreate avoids the "two pods fighting over one PVC" failure.
|
||||
deploymentStrategy:
|
||||
type: Recreate
|
||||
|
||||
podAnnotations:
|
||||
secret.reloader.stakater.com/reload: "grafana-oidc,grafana-admin"
|
||||
|
||||
adminUser: admin
|
||||
admin:
|
||||
existingSecret: grafana-admin
|
||||
existingSecretKey: admin-password
|
||||
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 256Mi
|
||||
|
||||
# ── Persistence ───────────────────────────────────────────────────────────────
|
||||
# Stores dashboards saved in the UI, datasource edits, and user sessions.
|
||||
# Longhorn provides the RWO block volume; 5Gi is ample for dashboard JSON.
|
||||
persistence:
|
||||
enabled: true
|
||||
storageClassName: longhorn
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
size: 5Gi
|
||||
|
||||
# ── Grafana config ────────────────────────────────────────────────────────────
|
||||
grafana.ini:
|
||||
server:
|
||||
root_url: https://grafana.riotpiao.com
|
||||
|
||||
# No anonymous read access — every user must log in via Authentik SSO.
|
||||
auth.anonymous:
|
||||
enabled: false
|
||||
|
||||
# Explore tab: required for ad-hoc LogQL/PromQL queries against Loki/Prometheus.
|
||||
explore:
|
||||
enabled: true
|
||||
|
||||
# WAL for the embedded SQLite DB — prevents corruption on ungraceful shutdown.
|
||||
database:
|
||||
wal: true
|
||||
|
||||
# ── Authentik OIDC (generic OAuth2) ───────────────────────────────────────
|
||||
# Grafana v10+ supports OIDC auto-discovery; we wire it manually here because
|
||||
# Authentik's discovery endpoint is internal-only (no external DNS for iam.svc).
|
||||
# All URLs use the external hostname so CoreDNS rewrites them to
|
||||
# authentik-server.iam.svc — this keeps the Host header correct so Authentik
|
||||
# doesn't return localhost redirects in its token responses.
|
||||
#
|
||||
# role_attribute_path: JMESPath expression evaluated against the userinfo
|
||||
# response. Members of the 'grafana-admins' Authentik group get Admin role;
|
||||
# everyone else gets Viewer. The group name must match exactly what Authentik
|
||||
# sends in the 'groups' claim.
|
||||
auth.generic_oauth:
|
||||
enabled: true
|
||||
name: Authentik
|
||||
allow_sign_up: true
|
||||
client_id: grafana
|
||||
scopes: openid email profile
|
||||
auth_url: https://authentik.riotpiao.com/application/o/authorize/
|
||||
token_url: https://authentik.riotpiao.com/application/o/token/
|
||||
api_url: https://authentik.riotpiao.com/application/o/userinfo/
|
||||
role_attribute_path: "contains(groups[*], 'grafana-admins') && 'Admin' || 'Viewer'"
|
||||
use_pkce: false
|
||||
use_refresh_token: false
|
||||
skip_org_role_sync: false
|
||||
tls_skip_verify_insecure: true # Authentik uses self-signed cert; verify in prod
|
||||
|
||||
# GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET is injected from the grafana-oidc K8s
|
||||
# Secret (created by k8s/talos-iam/setup_talos_iam.sh). envFromSecret mounts
|
||||
# every key in that secret as an environment variable — keeps secrets out of
|
||||
# values files and out of git.
|
||||
envFromSecret: grafana-oidc
|
||||
|
||||
# ── Datasources ───────────────────────────────────────────────────────────────
|
||||
# Provisioned at install — no manual "Add datasource" step in the UI.
|
||||
# Loki is the default (log exploration); Prometheus is secondary (metrics).
|
||||
# Both use in-cluster service DNS — Grafana never leaves the cluster for data.
|
||||
datasources:
|
||||
datasources.yaml:
|
||||
apiVersion: 1
|
||||
datasources:
|
||||
- name: Loki
|
||||
type: loki
|
||||
uid: loki
|
||||
access: proxy
|
||||
url: http://loki.logging.svc.cluster.local:3100
|
||||
isDefault: true
|
||||
version: 1
|
||||
editable: true
|
||||
jsonData:
|
||||
maxLines: 1000
|
||||
timeout: 60
|
||||
- name: Prometheus
|
||||
type: prometheus
|
||||
uid: prometheus
|
||||
access: proxy
|
||||
url: http://prometheus-kube-prometheus-prometheus.monitoring.svc.cluster.local:9090
|
||||
isDefault: false
|
||||
version: 1
|
||||
editable: true
|
||||
jsonData:
|
||||
timeInterval: 30s
|
||||
timeout: 60
|
||||
|
||||
# ── Dashboard providers ───────────────────────────────────────────────────────
|
||||
# Tells Grafana to watch a directory for dashboard JSON files.
|
||||
# The `dashboards` block below populates that directory via an init container
|
||||
# that downloads from grafana.com at install time.
|
||||
dashboardProviders:
|
||||
dashboardproviders.yaml:
|
||||
apiVersion: 1
|
||||
providers:
|
||||
- name: default
|
||||
orgId: 1
|
||||
folder: ""
|
||||
type: file
|
||||
disableDeletion: false
|
||||
editable: true
|
||||
options:
|
||||
path: /var/lib/grafana/dashboards/default
|
||||
|
||||
# ── Pre-loaded dashboards ──────────────────────────────────────────────────────
|
||||
# Fetched from grafana.com by an init container at helm-install time and baked
|
||||
# into ConfigMaps. gnetId + revision pin the exact dashboard version so an
|
||||
# upstream change on grafana.com doesn't silently alter what's deployed.
|
||||
dashboards:
|
||||
default:
|
||||
node-exporter-full:
|
||||
gnetId: 1860
|
||||
revision: 37
|
||||
datasource: Prometheus
|
||||
kubernetes-cluster:
|
||||
gnetId: 7249
|
||||
revision: 1
|
||||
datasource: Prometheus
|
||||
|
||||
# Allow scheduling on the control-plane node (talos-cp-1 carries NoSchedule taint).
|
||||
tolerations:
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
operator: Exists
|
||||
effect: NoSchedule
|
||||
|
||||
# Pin to az-a (talos-cp-1) — the only node running Longhorn. Without this the
|
||||
# scheduler may place grafana on cp-2/cp-3, where its Longhorn PVC cannot attach
|
||||
# ("CSINode does not contain driver driver.longhorn.io").
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: topology.kubernetes.io/zone
|
||||
operator: In
|
||||
values: [az-a]
|
||||
|
||||
# ClusterIP only — access via ingress (grafana.riotpiao.com) or port-forward.
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
|
||||
# Ingress managed by k8s/ingress/ingress.yaml — not the chart's built-in ingress.
|
||||
ingress:
|
||||
enabled: false
|
||||
|
||||
serviceMonitor:
|
||||
enabled: false
|
||||
|
||||
# ── Dashboard-as-code (sidecar discovery) ──────────────────────────────────────
|
||||
# Additive to the gnetId-download mechanism above. The sidecar watches for
|
||||
# ConfigMaps labeled grafana_dashboard=1 in ANY namespace and loads them live —
|
||||
# no Grafana restart needed when a new dashboard ConfigMap is applied.
|
||||
sidecar:
|
||||
dashboards:
|
||||
enabled: true
|
||||
label: grafana_dashboard
|
||||
labelValue: "1"
|
||||
folder: /var/lib/grafana/dashboards/custom
|
||||
folderAnnotation: grafana_folder
|
||||
provider:
|
||||
name: custom
|
||||
folder: "Homelab"
|
||||
disableDelete: false
|
||||
foldersFromFilesStructure: true
|
||||
searchNamespace: ALL
|
||||
Reference in New Issue
Block a user