Latence et timeouts sur etcd en forte charge Kubernetes API

Posté par plombard le 17/11/2025
RÉSOLU

plombard

Membre depuis le 08/06/2019

actif

Salut à tous je me bats avec des ralentissements et des erreurs `etcdserver: request timed out` sur notre cluster EKS.

Quand l'API server est sous charge — genre un gros déploiement ou un scaling massif de pods — les requêtes prennent une plombe. Je vois des erreurs de `context deadline exceeded` côté API server et les logs etcd montrent des `leader re-election` ou des `slow operations`.

C'est comme si etcd peinait sous la pression. On est sur du kernel 5.15 et etcd 3.5.7. Des idées d'où regarder en premier ?

Commentaires

caron-renee

Membre depuis le 12/06/2024

actif

Ugh ça sent la galère classique. Les `leader re-election` et les `slow operations` c'est le signal d'alarme d'etcd. Premiers trucs à checker les métriques:

curl -s localhost:2379/metrics | grep etcd_server_leader_changes_seen_total
curl -s localhost:2379/metrics | grep etcd_server_proposals_failed_total

Regarde si tu as des spikes de `leader changes` ou des `proposals failed`. Et la latence disque des nœuds etcd ? Un `iostat -xmt 1` pendant la charge nous aiderait.

plombard

Membre depuis le 08/06/2019

actif

Alors côté métriques etcd pendant la charge je vois bien des `leader_changes_seen_total` qui augmentent et des `proposals_failed_total` aussi mais pas en flèche non plus. Juste quelques-uns.

# etcd_server_leader_changes_seen_total 15
# etcd_server_proposals_failed_total 8

Pour `iostat`, le `await` sur les disques etcd est un peu élevé, genre `50-80ms` par moments. On est sur du `gp3` AWS.

michel-barre

Membre depuis le 06/06/2020

actif

`50-80ms` d' `await` sur du `gp3` c'est pas bon du tout pour etcd. etcd est hypersensible à la latence disque surtout sur le WAL. Le `sync-interval` par défaut est de `100ms`, donc si tes `fsync` prennent plus de `100ms` régulièrement, ça met etcd en PLS.

Tu as vérifié l'état des volumes `gp3` via CloudWatch ? Et tu n'as pas de messages de compaction lente dans les logs etcd ? Genre `compaction_ran_for_too_long_total` ?

plombard

Membre depuis le 08/06/2019

actif

CloudWatch pour les `gp3` montre des spikes d'IOPS et de throughput mais globalement dans les limites provisionnées. Pas de `compaction_ran_for_too_long_total` non plus.

Par contre, en creusant les métriques etcd plus en détail, j'ai vu que `etcd_disk_wal_fsync_duration_seconds_bucket` montre une queue de latence assez longue. Pas mal de `fsyncs` qui dépassent les `10ms` et quelques-uns au-delà de `50ms`.

caron-renee

Membre depuis le 12/06/2024

actif

`wal_fsync_duration` au-delà de `10ms` c'est un problème. Ça veut dire que le disque est le bottleneck principal. Même si `iostat` ne montre pas toujours le problème en surface, les latences de `fsync` sont le vrai indicateur.

Quel est le système de fichiers sur tes volumes etcd ? XFS ou ext4 ? Et quelles sont les options de mount ?

plombard

Membre depuis le 08/06/2019

actif

C'est du XFS par défaut avec les options de mount classiques, rien de spécial. `/dev/xvdf on /var/lib/etcd type xfs (rw,noatime,attr2,inode64,noquota)`.

On a déjà `noatime`. Faut-il aller plus loin ?

michel-barre

Membre depuis le 06/06/2020

actif

Le `noatime` c'est bien mais pas toujours suffisant. Avec XFS sur AWS, il y a une option `discard` qui peut aider, surtout si tes volumes sont réutilisés ou clonés. Ça permet à la couche bloc de signaler les blocs non utilisés au sous-jacent NVMe pour libérer des ressources.

Tu peux essayer de rajouter `discard` à tes options de mount dans `fstab` et remonter le volume.

/dev/xvdf /var/lib/etcd xfs defaults,noatime,discard 0 0

Après ça un `mount -o remount /var/lib/etcd`.

plombard

Membre depuis le 08/06/2019

actif

Ok, j'ai ajouté `discard` et remounté le volume. On a relancé un cycle de déploiements lourds et je monitor les métriques.

C'est un peu mieux mais je vois toujours des petits pics de `wal_fsync_duration` occasionnels. Moins de `50ms` mais encore des `20-30ms`.

Et pendant ces pics, j'ai aussi remarqué des montées de `context switch` pour les process etcd. Coïncidence ?

caron-renee

Membre depuis le 12/06/2024

actif

Des `context switch` élevés peuvent indiquer une contention CPU ou un scheduler agressif. Quel scheduler I/O est actif sur ces nœuds ?

cat /sys/block/nvme0n1/queue/scheduler

En général `mq-deadline` est pas mal pour les NVMe. Et est-ce que le process etcd a une priorité CPU élevée ? `chrt` ou `nice` ?

plombard

Membre depuis le 08/06/2019

actif

Le scheduler est bien `mq-deadline`. Pas de modification de priorité CPU sur etcd, il tourne avec le `nice` par défaut. On a déjà isolé des cpus avec `isolcpus` pour les API servers mais pas pour etcd.

J'ai fait un `pidstat -d -t 1` sur les nœuds etcd pendant la charge. Le thread principal de etcd n'est pas à 100% CPU mais ses threads d'écriture WAL et raft eux montrent une charge CPU plus fluctuante avec des `cswch/s` et `nvcswch/s` qui montent.

michel-barre

Membre depuis le 06/06/2020

actif

La charge CPU sur les threads WAL/raft et les context switches ça confirme la contention. Si le disque est lent, le thread se bloque en attente d'IO, le scheduler le swap, ça fait des context switch.

Revenons au `gp3`. Quel est le niveau d'IOPS/throughput provisionné pour tes volumes etcd ? Par défaut c'est `3000 IOPS` et `125 MB/s`. C'est souvent insuffisant pour un cluster k8s busy, surtout avec des écritures transactionnelles d'etcd.

plombard

Membre depuis le 08/06/2019

actif

On est à `5000 IOPS` et `200 MB/s` pour les volumes `gp3` etcd. On pensait que c'était suffisant pour notre taille de cluster.

caron-renee

Membre depuis le 12/06/2024

actif

`5000 IOPS` pour etcd sur un cluster qui fait du scaling et des déploiements intensifs c'est peut-être le problème. etcd est une bête en écriture, surtout sur le WAL. Chaque modification de l'état du cluster (création de pod, mise à jour de CRD) est une écriture.

Pendant un pic, si l'API server inonde etcd de requêtes, `5000 IOPS` peuvent être insuffisants pour absorber les bursts de `fsyncs` nécessaires. Je pousserais à `10000 IOPS` et `250 MB/s` sur les `gp3` etcd. Ça a l'air overkill mais le coût est gérable et la stabilité d'etcd c'est la survie de ton cluster.

plombard

Membre depuis le 08/06/2019

actif

Ok, on va tenter ça. J'ai provisionné les volumes `gp3` à `10000 IOPS` et `250 MB/s` pour le cluster de test.

Après plusieurs cycles de charge API intense, je ne vois plus aucun spike dans `etcd_disk_wal_fsync_duration_seconds_bucket`. La latence est stable, sous les `5ms`. Plus de `leader re-election` ou de `slow operations` signalées.

Les `context switch` sont revenus à la normale. Ça semble bien être un sous-provisionnement des IOPS pour les volumes etcd qui créait tous ces symptômes en cascade.

Un grand merci pour cette investigation chirurgicale, vous avez sauvé notre déploiement !

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