Bases de données sur Kubernetes : l'enfer du stockage et des performances I/O

Posté par theodore-turpin le 05/04/2026
RÉSOLU

theodore-turpin

Membre depuis le 20/05/2024

Salut. On essaie de migrer nos clusters PostgreSQL sur Kubernetes. On utilise actuellement du stockage EBS classique via le CSI `ebs.csi.aws.com`.

Les performances sont catastrophiques dès qu'on a un peu de charge, et la latence d'écriture nous fait rater nos SLAs. On me suggère de passer sur du Local PV avec des disques NVMe locaux.

Mais comment vous gérez la haute disponibilité ? Si le node meurt, les données sont perdues ? On n'est pas en train de jouer avec le feu là ?

Commentaires

navarro-celina

Membre depuis le 13/09/2023

actif

Mettre une base de données sur Kubernetes, c'est déjà chercher les problèmes. Vouloir le faire avec du stockage réseau distant comme EBS sur une base transactionnelle, c'est du masochisme.

Le réseau rajoute une couche de latence que la pile I/O de PostgreSQL déteste. Le Local PV est la seule solution viable pour de la performance, mais ça t'oblige à gérer la réplication au niveau applicatif, pas au niveau stockage.

bgonzalez

Membre depuis le 10/07/2024

C'est n'importe quoi. On fait tourner des DBs sur K8s depuis 3 ans avec Rook et Ceph sans aucun souci majeur. Le problème n'est pas le stockage réseau, c'est ton tuning système.

Est-ce que tu as configuré ton `storage_class.yaml` pour utiliser le mode `WaitForFirstConsumer` ? Est-ce que tes limites CPU/RAM sont bien settées pour éviter le throttling du kernel ?

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-storage
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
  type: gp3
  iops: "16000"
  throughput: "1000"

chamel

Membre depuis le 18/05/2019

actif secouriste

Calmez-vous. Le Local PV avec du NVMe c'est imbattable en IOPS, c'est vrai. Pour la perte de node, il faut utiliser un opérateur comme CloudNativePG ou Zalando Postgres Operator.

Ils gèrent le failover automatiquement. Si un node crame, l'opérateur promeut un replica, et un nouveau pod est recréé ailleurs. On s'en fout que les données du node mort soient perdues puisque PostgreSQL a répliqué les WALs.

navarro-celina

Membre depuis le 13/09/2023

actif

Sauf que quand ton pod doit se reconstruire sur un nouveau node, il doit se retaper un `basebackup` complet depuis le master. Si ta DB fait 2 To, ton cluster va saturer son réseau pendant des heures et tes perfs vont s'écrouler pendant la resynchro.

Le stockage réseau type EBS permet au pod de se rattacher au même volume en quelques secondes sur un autre node. C'est ça la vraie résilience opérationnelle.

bgonzalez

Membre depuis le 10/07/2024

Le temps de détachement/rattachement d'un volume EBS sur AWS peut prendre plusieurs minutes si l'API est sous l'eau. Pendant ce temps, ta prod est down.

Avec le Local PV, l'application est déjà là, prête à servir sur les autres replicas. On sacrifie un peu de temps de reconstruction pour une disponibilité immédiate.

theodore-turpin

Membre depuis le 20/05/2024

On a testé `fio` sur nos instances. Avec EBS gp3, on plafonne à une latence de 2ms en écriture. Avec du NVMe local, on tombe à 50 microsecondes. C'est un facteur 40.

Comment je peux justifier de rester sur du stockage lent juste pour le confort du CSI ? Mais la gestion du `local-static-provisioner` me semble être une usine à gaz à maintenir.

chamel

Membre depuis le 18/05/2019

actif secouriste

C'est là qu'OpenEBS ou Mayastor entrent en jeu. Ils permettent d'avoir les perfs du local avec l'abstraction d'un CSI. Ça réplique les blocs au niveau NVMe-over-Fabrics.

C'est complexe à setup, mais c'est le bridge parfait. Par contre, prépare tes on-calls, parce que quand Mayastor décide de ne plus synchroniser ses répliques, c'est pas une partie de plaisir.

navarro-celina

Membre depuis le 13/09/2023

actif

Encore une couche de complexité... On rajoute du software pour pallier les manques d'un autre software. Pourquoi ne pas simplement utiliser RDS ou une instance EC2 dédiée pour la DB ?

Kubernetes n'est pas fait pour gérer de l'état lourd. Vouloir tout mettre dans K8s c'est une erreur d'architecte qui veut se faire plaisir sur son CV.

bgonzalez

Membre depuis le 10/07/2024

L'argument du "c'est pas fait pour" est fatigué. Avec les `PriorityClass` et les `Taints`, on peut isoler nos DBs parfaitement. On évite le lock-in de RDS et on contrôle notre cycle d'upgrade.

Pour l'I/O, vérifiez aussi vos `mount` options. Utiliser `noatime` et tuner le `dirty_ratio` du kernel Linux fait souvent plus de bien qu'un changement de disque.

sysctl -w vm.dirty_background_ratio=5
sysctl -w vm.dirty_ratio=10

chamel

Membre depuis le 18/05/2019

actif secouriste

N'oubliez pas les backups. Faire un snapshot EBS c'est trivial et consistant. Faire un backup consistant sur du Local PV sans figer les écritures au niveau filesystem, c'est une autre paire de manches.

Vous allez finir par utiliser `pgbackrest` avec du S3, ce qui est très bien, mais ça rajoute encore une brique à monitorer.

navarro-celina

Membre depuis le 13/09/2023

actif

Et le CPU pinning ? Si ton pod PostgreSQL partage ses cores avec 10 micro-services NodeJS qui font du garbage collection, tes perfs I/O vont fluctuer à cause du scheduler CPU.

Il faut impérativement utiliser le `Static` CPU Manager Policy de la `kubelet` pour dédier des cores entiers à Postgres.

bgonzalez

Membre depuis le 10/07/2024

C'est vrai. Et pour le stockage, si vous voulez vraiment du réseau rapide, regardez du côté de Portworx. C'est payant, c'est cher, mais ça gère la localité des données et la réplication synchrone proprement pour Kubernetes.

Leur scheduler sait placer le pod là où la donnée se trouve déjà.

theodore-turpin

Membre depuis le 20/05/2024

Le prix de Portworx ne passera jamais au budget. On est en plein FinOps en ce moment.

Je pense qu'on va partir sur une solution intermédiaire : garder EBS pour les DBs peu critiques et passer sur du Local PV avec l'opérateur CloudNativePG pour les clusters de prod qui ont besoin de grosses performances.

chamel

Membre depuis le 18/05/2019

actif secouriste

Sage décision. Mais par pitié, testez vos restores. Une DB qui va vite c'est bien, une DB qu'on peut restaurer après une corruption de disque local à cause d'un firmware NVMe foireux, c'est mieux.

Regardez aussi du côté du scheduler I/O du kernel, passez en `mq-deadline` ou `none` pour les SSDs.

navarro-celina

Membre depuis le 13/09/2023

actif

Bonne chance. On en reparle dans six mois quand vous aurez perdu votre premier quorum à cause d'une partition réseau entre vos nodes Local PV.

theodore-turpin

Membre depuis le 20/05/2024

Merci pour les conseils sur le tuning kernel et les opérateurs. Je vais creuser les paramètres `sysctl` et la configuration du CPU Manager.

L'approche par palier de criticité semble la moins risquée pour l'instant. Je vais commencer par migrer un replica de lecture sur Local PV pour voir comment il se comporte. À plus !

Laisser une réponse

Vous devez être connecté pour poster un message !

Rejoindre la communauté

Recevoir les derniers articles gratuitement en créant un compte !

S'inscrire