# ============================================================================= # Loki -- agregation des journaux # ============================================================================= # Mode "single binary", stockage sur le disque local du noeud (local-path de # k3s). Suffisant jusqu'a ~10 Go/mois de logs, ce qui couvre tres largement la # phase 1. Au-dela, basculer le stockage sur Hetzner Object Storage. --- apiVersion: v1 kind: ConfigMap metadata: name: loki-config namespace: monitoring data: loki.yaml: | auth_enabled: false server: http_listen_port: 3100 grpc_listen_port: 9096 log_level: warn common: instance_addr: 127.0.0.1 path_prefix: /loki storage: filesystem: chunks_directory: /loki/chunks rules_directory: /loki/rules replication_factor: 1 ring: kvstore: store: inmemory schema_config: configs: - from: 2024-01-01 store: tsdb object_store: filesystem schema: v13 index: prefix: index_ period: 24h limits_config: allow_structured_metadata: true volume_enabled: true # 31 jours : couvre l'analyse d'incident et reste sous le seuil ou les # journaux applicatifs deviendraient une base de donnees personnelles # a part entiere au sens du RGPD (cf. 16 dans la doc de mise en prod). retention_period: 744h reject_old_samples: true reject_old_samples_max_age: 168h ingestion_rate_mb: 8 ingestion_burst_size_mb: 16 max_entries_limit_per_query: 5000 max_query_series: 500 compactor: working_directory: /loki/compactor compaction_interval: 10m retention_enabled: true retention_delete_delay: 2h retention_delete_worker_count: 50 delete_request_store: filesystem query_range: results_cache: cache: embedded_cache: enabled: true max_size_mb: 100 analytics: reporting_enabled: false --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: loki-data namespace: monitoring spec: accessModes: [ReadWriteOnce] storageClassName: local-path resources: requests: storage: 20Gi --- apiVersion: apps/v1 kind: Deployment metadata: name: loki namespace: monitoring labels: app.kubernetes.io/name: loki spec: replicas: 1 # Un seul volume RWO : on remplace avant de recreer, jamais l'inverse. strategy: type: Recreate selector: matchLabels: app.kubernetes.io/name: loki template: metadata: labels: app.kubernetes.io/name: loki spec: securityContext: runAsNonRoot: true runAsUser: 10001 runAsGroup: 10001 fsGroup: 10001 seccompProfile: type: RuntimeDefault containers: - name: loki image: grafana/loki:3.3.2 args: ["-config.file=/etc/loki/loki.yaml"] ports: - name: http containerPort: 3100 readinessProbe: httpGet: path: /ready port: http initialDelaySeconds: 30 periodSeconds: 10 livenessProbe: httpGet: path: /ready port: http initialDelaySeconds: 60 periodSeconds: 30 resources: requests: cpu: 100m memory: 256Mi limits: cpu: 1000m memory: 1Gi securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"] volumeMounts: - name: config mountPath: /etc/loki - name: data mountPath: /loki volumes: - name: config configMap: name: loki-config - name: data persistentVolumeClaim: claimName: loki-data --- apiVersion: v1 kind: Service metadata: name: loki namespace: monitoring labels: app.kubernetes.io/name: loki spec: type: ClusterIP selector: app.kubernetes.io/name: loki ports: - name: http port: 3100 targetPort: http