MinIO tournait sans une seule sonde — et 8 charts sur 10 n'étaient jamais construits (#32)
Helm Charts / Detect changed charts (push) Successful in 10s
Helm Charts / Library charts tool (push) Skipped
Helm Charts / Application charts chart (push) Skipped
Helm Charts / Application charts crowdsec (push) Skipped
Helm Charts / Application charts grafana (push) Skipped
Helm Charts / Application charts hashicorp-vault (push) Skipped
Helm Charts / Application charts pgbouncer (push) Skipped
Helm Charts / Application charts pgcat (push) Skipped
Helm Charts / Application charts prometheus (push) Skipped
Helm Charts / Application charts redis (push) Skipped
Helm Charts / Application charts minio (push) Failing after 7s
Helm Charts / Detect changed charts (push) Successful in 10s
Helm Charts / Library charts tool (push) Skipped
Helm Charts / Application charts chart (push) Skipped
Helm Charts / Application charts crowdsec (push) Skipped
Helm Charts / Application charts grafana (push) Skipped
Helm Charts / Application charts hashicorp-vault (push) Skipped
Helm Charts / Application charts pgbouncer (push) Skipped
Helm Charts / Application charts pgcat (push) Skipped
Helm Charts / Application charts prometheus (push) Skipped
Helm Charts / Application charts redis (push) Skipped
Helm Charts / Application charts minio (push) Failing after 7s
Co-authored-by: Gabriel Radureau <[email protected]>
This commit was merged in pull request #32.
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# MinIO — Deployment écrit À LA MAIN, et voici pourquoi.
|
||||
#
|
||||
# ⚠⚠ LE CHART OFFICIEL `minio/minio` N'OFFRE AUCUNE SONDE DE SANTÉ.
|
||||
# Vérifié sur la 5.4.0 (la dernière au 2026-09-02) : aucune clé `livenessProbe`
|
||||
# dans ses `values.yaml`, aucun rendu de sonde dans ses `templates/`. Ce n'était
|
||||
# donc pas un oubli de configuration de notre part — il n'y avait rien à
|
||||
# configurer. On reprend le manifeste à notre charge pour pouvoir poser la sonde.
|
||||
#
|
||||
# CE QUE ÇA A COÛTÉ, MESURÉ (arcodange-org/tools#31) :
|
||||
# le 2026-08-29 à 14 h 11, les répliques Longhorn se perdent de vue sur le réseau
|
||||
# (`R/W Timeout. No response received in 8s`) ; le moteur les marque `ERR` une à
|
||||
# une ; à 15 h 32 le périphérique bloc disparaît sous MinIO ; à 17 h 54 **ext4
|
||||
# abandonne son journal** (`comm minio: Detected aborted journal`). À partir de
|
||||
# là, toute écriture rend `EIO`.
|
||||
#
|
||||
# Longhorn s'est rétabli TOUT SEUL le 30 août à 11 h 50. Mais un journal ext4
|
||||
# abandonné ne se répare jamais seul : il le reste jusqu'au démontage. MinIO est
|
||||
# donc resté assis sur un montage mort DEUX JOURS APRÈS la réparation du
|
||||
# stockage, pendant que Longhorn (`healthy`), les répliques (`RW`), les nœuds,
|
||||
# ArgoCD (`Synced, Healthy`) et le pod lui-même (`1/1 Running`, `0 restart`)
|
||||
# affichaient tous vert. Trois jours de panne totale du stockage objet, et pas
|
||||
# un seul indicateur rouge.
|
||||
#
|
||||
# ⚠ LE POD NE REDÉMARRE PAS QUAND SON SYSTÈME DE FICHIERS MEURT. Le processus
|
||||
# vit ; c'est tout ce que Kubernetes regardait, faute de sonde.
|
||||
# -----------------------------------------------------------------------------
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: minio
|
||||
namespace: tools
|
||||
labels:
|
||||
app: minio
|
||||
release: minio
|
||||
spec:
|
||||
replicas: 1
|
||||
# ⚠ IMMUABLE, et repris À L'IDENTIQUE de ce que le sous-chart avait posé :
|
||||
# changer un `selector` sur un Deployment existant fait ÉCHOUER l'application,
|
||||
# et ArgoCD le recréerait — donc détacherait puis rattacherait le volume.
|
||||
selector:
|
||||
matchLabels:
|
||||
app: minio
|
||||
release: minio
|
||||
strategy:
|
||||
# ⚠ `Recreate`, PAS `RollingUpdate` : le volume est ReadWriteOnce. Un
|
||||
# roulement voudrait deux pods à la fois, le second resterait en
|
||||
# `ContainerCreating` sur un `Multi-Attach error` jusqu'au timeout, et le
|
||||
# déploiement paraîtrait « en cours » pendant des minutes. Le chart amont
|
||||
# posait `maxSurge: 100%`, ce qui est le mauvais réglage pour un RWO.
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: minio
|
||||
release: minio
|
||||
spec:
|
||||
serviceAccountName: minio
|
||||
securityContext:
|
||||
# Repris tel quel : la donnée déjà écrite sur le volume appartient à
|
||||
# 1000:1000. Changer ces valeurs rendrait le bucket illisible.
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
fsGroup: 1000
|
||||
fsGroupChangePolicy: OnRootMismatch
|
||||
terminationGracePeriodSeconds: 30
|
||||
containers:
|
||||
- name: minio
|
||||
image: "{{ .Values.minio.image.repository }}:{{ .Values.minio.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.minio.image.pullPolicy }}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -ce
|
||||
- /usr/bin/docker-entrypoint.sh minio server /export -S /etc/minio/certs/ --address :9000 --console-address :9001
|
||||
env:
|
||||
# Identifiants JAMAIS dans le dépôt : le secret est matérialisé par
|
||||
# le Vault Secrets Operator depuis kvv2/minio/config.
|
||||
- name: MINIO_ROOT_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.minio.existingSecret }}
|
||||
key: rootUser
|
||||
- name: MINIO_ROOT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.minio.existingSecret }}
|
||||
key: rootPassword
|
||||
{{- range $cle, $valeur := .Values.minio.environment }}
|
||||
- name: {{ $cle }}
|
||||
value: {{ $valeur | quote }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 9000
|
||||
protocol: TCP
|
||||
- name: http-console
|
||||
containerPort: 9001
|
||||
protocol: TCP
|
||||
# ---------------------------------------------------------------
|
||||
# LES SONDES — la raison d'être de ce fichier.
|
||||
#
|
||||
# ⚠ `/minio/health/live` NE SUFFIT PAS, et c'est mesuré : il répond
|
||||
# 200 sur un magasin QUI NE PEUT PLUS ÉCRIRE. C'est précisément
|
||||
# pourquoi la panne du 29 août est restée invisible trois jours.
|
||||
#
|
||||
# `/minio/health/cluster` vérifie le QUORUM D'ÉCRITURE — la propriété
|
||||
# qu'on veut réellement garder.
|
||||
#
|
||||
# SABOTAGE RELEVÉ (2026-09-02, MinIO jetable, quatre disques, les deux
|
||||
# moitiés dans LE MÊME POD, même image) :
|
||||
#
|
||||
# | état du magasin | /health/live | /health/cluster |
|
||||
# |------------------------|--------------|-----------------|
|
||||
# | 4 disques sains | 200 | **200** |
|
||||
# | quorum d'écriture perdu| **200** | **503** |
|
||||
#
|
||||
# Sabotage : `format.json` de deux disques sur quatre écrasé. La bascule
|
||||
# de `cluster` est survenue entre t+20 s et t+40 s. `live` n'a jamais
|
||||
# bougé. Les DEUX moitiés comptent : la sonde rougit quand la propriété
|
||||
# est violée, ET reste verte sinon.
|
||||
# ---------------------------------------------------------------
|
||||
startupProbe:
|
||||
# Au démarrage on interroge `live` : tant que MinIO monte, `cluster`
|
||||
# répond 503 pour une raison légitime, et l'interroger ici tuerait
|
||||
# le pod avant qu'il ait fini de démarrer.
|
||||
# 24 × 5 s = 2 min accordées au démarrage.
|
||||
httpGet:
|
||||
path: /minio/health/live
|
||||
port: 9000
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 24
|
||||
readinessProbe:
|
||||
# Retire MinIO du Service quand il ne peut plus écrire : les clients
|
||||
# reçoivent un refus franc au lieu d'un dépôt qui part dans le vide.
|
||||
httpGet:
|
||||
path: /minio/health/cluster
|
||||
port: 9000
|
||||
periodSeconds: 15
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
livenessProbe:
|
||||
# ⚠ C'EST CELLE-CI QUI AURAIT LEVÉ LA PANNE : le remède au journal
|
||||
# ext4 abandonné est un démontage, donc un redémarrage du pod.
|
||||
#
|
||||
# ⚠ 6 × 30 s = 3 MINUTES de refus SOUTENU avant de redémarrer. Cette
|
||||
# grappe connaît des à-coups Longhorn de quelques secondes (le
|
||||
# déclencheur du 29 août était un `R/W Timeout` de 8 s) : une sonde
|
||||
# nerveuse redémarrerait MinIO sur un hoquet. C'est l'erreur exacte
|
||||
# que redis a payée ici en 2026-07 — 836 échecs de sonde, 135
|
||||
# redémarrages, et un `.fr` en 403 (voir redis/values.yaml).
|
||||
httpGet:
|
||||
path: /minio/health/cluster
|
||||
port: 9000
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
resources:
|
||||
{{- toYaml .Values.minio.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: export
|
||||
mountPath: /export
|
||||
- name: minio-user
|
||||
mountPath: /tmp/credentials
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: export
|
||||
persistentVolumeClaim:
|
||||
claimName: minio
|
||||
- name: minio-user
|
||||
secret:
|
||||
secretName: {{ .Values.minio.existingSecret }}
|
||||
@@ -1,3 +0,0 @@
|
||||
{{- if eq .Values.tool.kind "HelmChart" -}}
|
||||
{{- include "tool.helm-chart-config.tpl" . -}}
|
||||
{{- end -}}
|
||||
@@ -1,3 +0,0 @@
|
||||
{{- if eq .Values.tool.kind "HelmChart" -}}
|
||||
{{- include "tool.helm-chart.tpl" . -}}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,48 @@
|
||||
# Les deux expositions INTERNES (`.lab`). L'exposition publique de l'API S3 vit
|
||||
# dans ingress-public.yaml, avec ses propres avertissements.
|
||||
#
|
||||
# ⚠ La console d'administration n'est PAS exposée publiquement, et ça ne doit
|
||||
# pas changer par inadvertance : elle porte les identifiants racine.
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: minio
|
||||
namespace: tools
|
||||
labels:
|
||||
app: minio
|
||||
release: minio
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
rules:
|
||||
- host: s3.arcodange.lab
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: minio
|
||||
port:
|
||||
number: 9000
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: minio-console
|
||||
namespace: tools
|
||||
labels:
|
||||
app: minio
|
||||
release: minio
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
rules:
|
||||
- host: minio.arcodange.lab
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: minio-console
|
||||
port:
|
||||
number: 9001
|
||||
@@ -0,0 +1,39 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Le volume de données. ⚠⚠ C'EST L'OBJET LE PLUS DANGEREUX DE CE LOT.
|
||||
#
|
||||
# Il était rendu par le sous-chart `minio/minio`. En reprenant les manifestes à
|
||||
# notre charge, si on avait OUBLIÉ de le rendre ici, ArgoCD l'aurait ÉLAGUÉ —
|
||||
# c'est-à-dire supprimé, avec les vidéos dedans.
|
||||
#
|
||||
# ⚠ `volumeName` n'est VOLONTAIREMENT pas déclaré : c'est le contrôleur qui
|
||||
# pose ce champ à la liaison. ArgoCD ignore ce qui existe en vie sans être
|
||||
# déclaré, donc la liaison actuelle (pvc-ebb2605f-…) survit ; et le figer ici
|
||||
# empêcherait toute recréation future de se lier à un autre volume.
|
||||
#
|
||||
# ⚠ La plupart des champs d'un PVC sont IMMUABLES. Ce fichier reproduit à
|
||||
# l'identique ce que le sous-chart avait posé — le modifier n'aurait pas l'effet
|
||||
# qu'on croit, il ferait échouer l'application.
|
||||
# -----------------------------------------------------------------------------
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: minio
|
||||
namespace: tools
|
||||
labels:
|
||||
app: minio
|
||||
release: minio
|
||||
annotations:
|
||||
# Ceinture ET bretelles : même si ce manifeste disparaissait un jour du
|
||||
# dépôt, ArgoCD ne supprimerait pas le volume de lui-même.
|
||||
argocd.argoproj.io/sync-options: Prune=false
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
storageClassName: {{ .Values.minio.persistence.storageClass }}
|
||||
volumeMode: Filesystem
|
||||
resources:
|
||||
requests:
|
||||
# 50 Gi ≈ 250 heures de cours au palier « travail » de Kadans (360p,
|
||||
# 3,4 Mo/min — ADR-018 du front). Longhorn réplique ce volume sur les
|
||||
# nœuds : compter ×3 sur la capacité du cluster avant d'augmenter.
|
||||
storage: {{ .Values.minio.persistence.size }}
|
||||
@@ -0,0 +1,40 @@
|
||||
# API S3 (les applications parlent ici) et console d'administration (humains).
|
||||
# Deux Services distincts parce que deux ingress distincts les exposent, et que
|
||||
# seul le premier est ouvert publiquement (voir ingress-public.yaml).
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: minio
|
||||
namespace: tools
|
||||
labels:
|
||||
app: minio
|
||||
release: minio
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: minio
|
||||
release: minio
|
||||
ports:
|
||||
- name: http
|
||||
port: 9000
|
||||
targetPort: 9000
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: minio-console
|
||||
namespace: tools
|
||||
labels:
|
||||
app: minio
|
||||
release: minio
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: minio
|
||||
release: minio
|
||||
ports:
|
||||
- name: http
|
||||
port: 9001
|
||||
targetPort: 9001
|
||||
protocol: TCP
|
||||
@@ -0,0 +1,12 @@
|
||||
# Le rôle Vault du module `app_roles` borne l'authentification au SERVICE
|
||||
# ACCOUNT nommé comme l'app (`bound_service_account_names = [minio]`) : on
|
||||
# aligne donc le SA du pod sur ce nom — un SA pour le pod, le même pour Vault,
|
||||
# rien à réconcilier.
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: minio
|
||||
namespace: tools
|
||||
labels:
|
||||
app: minio
|
||||
release: minio
|
||||
Reference in New Issue
Block a user