14 commentaires
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_totalRegarde 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.
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 8Pour iostat, le await sur les disques etcd est un peu élevé, genre 50-80ms par moments. On est sur du gp3 AWS.
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 ?
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.
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 ?
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 0Après ça un mount -o remount /var/lib/etcd.
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 ?
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/schedulerEn 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 ?
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.
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.
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.
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 !
Salut à tous je me bats avec des ralentissements et des erreurs
etcdserver: request timed outsur 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 exceededcôté API server et les logs etcd montrent desleader re-electionou desslow 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 ?