# ============================================================================= # Grafana -- tableaux de bord (logs Loki + metriques Prometheus) # ============================================================================= # Expose sur grafana.xpeditis.com, protege par TROIS couches : # 1. le firewall Hetzner (seules les IP Cloudflare atteignent le serveur) # 2. le middleware Traefik admin-ip-allowlist (vos IP d'administration) # 3. l'authentification Grafana (Secret grafana-admin) # L'inscription et l'acces anonyme sont desactives. --- apiVersion: v1 kind: ConfigMap metadata: name: grafana-provisioning namespace: monitoring data: datasources.yaml: | apiVersion: 1 datasources: - name: Loki type: loki access: proxy url: http://loki:3100 isDefault: false jsonData: maxLines: 2000 - name: Prometheus type: prometheus access: proxy url: http://prometheus:9090 isDefault: true jsonData: timeInterval: 30s dashboards.yaml: | apiVersion: 1 providers: - name: xpeditis orgId: 1 folder: Xpeditis type: file disableDeletion: false updateIntervalSeconds: 60 allowUiUpdates: true options: path: /var/lib/grafana/dashboards --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: grafana-data namespace: monitoring spec: accessModes: [ReadWriteOnce] storageClassName: local-path resources: requests: storage: 5Gi --- apiVersion: apps/v1 kind: Deployment metadata: name: grafana namespace: monitoring labels: app.kubernetes.io/name: grafana spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app.kubernetes.io/name: grafana template: metadata: labels: app.kubernetes.io/name: grafana spec: securityContext: runAsNonRoot: true runAsUser: 472 runAsGroup: 472 fsGroup: 472 seccompProfile: type: RuntimeDefault containers: - name: grafana image: grafana/grafana:11.4.0 ports: - name: http containerPort: 3000 env: - name: GF_SECURITY_ADMIN_USER valueFrom: secretKeyRef: name: grafana-admin key: admin-user - name: GF_SECURITY_ADMIN_PASSWORD valueFrom: secretKeyRef: name: grafana-admin key: admin-password - name: GF_SERVER_ROOT_URL value: "https://grafana.xpeditis.com" - name: GF_USERS_ALLOW_SIGN_UP value: "false" - name: GF_AUTH_ANONYMOUS_ENABLED value: "false" # Empeche l'integration de Grafana dans une iframe tierce. - name: GF_SECURITY_ALLOW_EMBEDDING value: "false" - name: GF_SECURITY_COOKIE_SECURE value: "true" - name: GF_SECURITY_COOKIE_SAMESITE value: "strict" - name: GF_SECURITY_STRICT_TRANSPORT_SECURITY value: "true" - name: GF_ANALYTICS_REPORTING_ENABLED value: "false" - name: GF_ANALYTICS_CHECK_FOR_UPDATES value: "false" # Les alertes sont evaluees par Prometheus et routees par # Alertmanager : l'alerting Grafana ferait doublon. - name: GF_UNIFIED_ALERTING_ENABLED value: "false" - name: GF_ALERTING_ENABLED value: "false" readinessProbe: httpGet: path: /api/health port: http initialDelaySeconds: 20 livenessProbe: httpGet: path: /api/health port: http initialDelaySeconds: 60 periodSeconds: 30 resources: requests: cpu: 50m memory: 128Mi limits: cpu: 500m memory: 512Mi securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"] volumeMounts: - name: provisioning-datasources mountPath: /etc/grafana/provisioning/datasources - name: provisioning-dashboards mountPath: /etc/grafana/provisioning/dashboards - name: dashboards mountPath: /var/lib/grafana/dashboards - name: data mountPath: /var/lib/grafana volumes: - name: provisioning-datasources configMap: name: grafana-provisioning items: - key: datasources.yaml path: datasources.yaml - name: provisioning-dashboards configMap: name: grafana-provisioning items: - key: dashboards.yaml path: dashboards.yaml # Cree par scripts/deploy-monitoring.sh depuis infra/logging/grafana/. - name: dashboards configMap: name: grafana-dashboards optional: true - name: data persistentVolumeClaim: claimName: grafana-data --- apiVersion: v1 kind: Service metadata: name: grafana namespace: monitoring spec: type: ClusterIP selector: app.kubernetes.io/name: grafana ports: - name: http port: 3000 targetPort: http --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: grafana namespace: monitoring annotations: traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.middlewares: monitoring-admin-ip-allowlist@kubernetescrd,monitoring-security-headers@kubernetescrd spec: ingressClassName: traefik tls: - hosts: - grafana.xpeditis.com secretName: grafana-tls rules: - host: grafana.xpeditis.com http: paths: - path: / pathType: Prefix backend: service: name: grafana port: name: http