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

Co-authored-by: Gabriel Radureau <[email protected]>
This commit was merged in pull request #32.
This commit is contained in:
2026-09-03 00:26:41 +02:00
committed by arcodange
parent 3158f2d013
commit bb3a5cdf5c
11 changed files with 415 additions and 83 deletions
+172
View File
@@ -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 }}