Neuigkeiten von trion.
Immer gut informiert.

etcd Wartung in Kubernetes

etcd

etcd spielt in Kubernetes Clustern typischerweise eine essentielle Rolle, denn hier wird der gesamte Zustand des Clusters gehalten. Die einzelnen Kubernetes API Server Instanzen selbst sind zustandslos.

etcd ist ein verteilter Key-Value-Store, der mit Multi-Version-Concurrency-Control arbeitet und darüber Change-Notification and Zugriff auf ältere Versionen ermöglicht.

Die Implementierung verwendet dazu einen Revisions-Zähler. Werden Daten gelöscht, hinzugefügt oder überschrieben, so werden diese Operationen stets zu einer neuen Revision assoziiert. Die vorheigen Zustände bleiben zunächst gespeichert, auch wenn sie überholt sind.

Damit diese quasi unendliche Geschichte nicht dazu führt, dass die Festplatte volläuft, müssen regelmäßig Wartungsaufgaben erfüllt werden.

Bei der Wartung von etcd gibt es neben empfohlenen regelmäßigen Backups im wesentlichen zwei Tätigkeiten:

  • Compaction, dabei werden alte Revisionsstände tatsächlich gelöscht

  • Defragmentierung, dabei werden die bei der Compaction entstehenden Löcher entfernt und die Datenbank wieder in einen linearen Speicherzustand überführt

Beide Operationen verbessern die Effizienz bezüglich I/O-Operationen und Speicherplatzbedarf.

Compaction

etcd verfügt selbst über zwei Optionen zur automatischen Compaction: --auto-compaction-mode und --auto-compaction-retention. Durch den Modus lässt sich zwischen einer zeitlichen Steuerung (periodic), z.B. in Minuten oder Stunden und einer Steuerung über die Anzahl erstellter Revisionen (revision) umschalten. ( https://etcd.io/docs/v3.6/op-guide/maintenance/#auto-compaction )

Der Rentention-Schalter dient dazu, einzustellen, wie viel historische Daten, in Abhängigkeit vom Modus, aufbewahrt werden sollen. So kann die Anzahl Revisionen oder der Zeitpunkt, bis zu dem Daten der Vergangenheit aufbewahrt werden sollen, eingestellt werden.

Manuell kann ebenfalls eine Compaction gestartet werden, dabei muss angegeben werden, bis zu welcher Revision eine Historie erhalten bleiben soll. Nach einem manuellen Compaction-Lauf ist nicht direkt eine Veränderung der Datenbankgröße sichtbar.

Um eine manuelle Compaction zu starten muss zunächst ermittelt werden, bei welcher Revision etcd ist. Dies lässt sich über etcdctl status lediglich im JSON Format abfragen.

Statusabfrage etcd (In Kubernetes)
$ kubectl exec $(kubectl get pods --selector=component=etcd -A -o name | head -n 1) -n kube-system -- etcdctl  --endpoints=https://127.0.0.1:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt endpoint status -w table

+------------------------+--------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
|        ENDPOINT        |   ID   | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+------------------------+--------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| https://127.0.0.1:2379 | 17e83b |  3.5.21 |  8.9 MB |      true |      false |       192 |  439796869 |          439796869 |        |
+------------------------+--------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

$ kubectl exec $(kubectl get pods --selector=component=etcd -A -o name | head -n 1) -n kube-system -- etcdctl  --endpoints=https://127.0.0.1:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt endpoint status --write-out json

[{"Endpoint":"https://127.0.0.1:2379","Status":{"header":{"cluster_id":6560482667720351512,"member_id":1722692037798516920,"revision":389324466,"raft_term":192},"version":"3.5.21","dbSize":54104064,"leader":1722692037798516920,"raftIndex":439796740,"raftTerm":192,"raftAppliedIndex":439796740,"dbSizeInUse":9994240}}]

Im Gegensatz zur Tabellenausgabe ist im JSON Format auch die Revision zu sehen, die als Basis für die Compaction genutzt werden kann. Hier werden die letzten 500 Revisionen aufbewahrt.

Manuelle Compaction etcd
$ kubectl exec $(kubectl get pods --selector=component=etcd -A -o name | head -n 1) -n kube-system -- etcdctl  --endpoints=https://127.0.0.1:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt compact 389323966
compacted revision 389323966

In Kubernetes wird eine automatische Compaction auch durch den Kubernetes API Server durchgeführt. Dies lässt sich durch den Parameter --etcd-compaction-interval, der mit dem Wert "5m0s" vorbelegt ist, übersteuern.

Im Log von etcd sind diese periodischen Aufrufe auch gut zu sehen.

Periodische Compaction in etcd durch Kubernetes API Server
$ kubectl -n kube-system logs etcd-n2-master0 -f

{"level":"info","ts":"2025-10-22T19:18:51.475467Z","caller":"mvcc/index.go:214","msg":"compact tree index","revision":389325573}
{"level":"info","ts":"2025-10-22T19:18:51.514484Z","caller":"mvcc/kvstore_compaction.go:71","msg":"finished scheduled compaction","compact-revision":389325573,"took":"35.45586ms","hash":2491560121,"current-db-size-bytes":10948608,"current-db-size":"11 MB","current-db-size-in-use-bytes":9994240,"current-db-size-in-use":"10 MB"}
{"level":"info","ts":"2025-10-22T19:18:51.514595Z","caller":"mvcc/hash.go:151","msg":"storing new hash","hash":2491560121,"revision":389325573,"compact-revision":389324999}

{"level":"info","ts":"2025-10-22T19:23:51.480937Z","caller":"mvcc/index.go:214","msg":"compact tree index","revision":389326180}
{"level":"info","ts":"2025-10-22T19:23:51.519406Z","caller":"mvcc/kvstore_compaction.go:71","msg":"finished scheduled compaction","compact-revision":389326180,"took":"36.683809ms","hash":3732905419,"current-db-size-bytes":10964992,"current-db-size":"11 MB","current-db-size-in-use-bytes":9940992,"current-db-size-in-use":"9.9 MB"}
{"level":"info","ts":"2025-10-22T19:23:51.519528Z","caller":"mvcc/hash.go:151","msg":"storing new hash","hash":3732905419,"revision":389326180,"compact-revision":389325573}
{"level":"info","ts":"2025-10-22T19:28:51.488395Z","caller":"mvcc/index.go:214","msg":"compact tree index","revision":389326757}

Die Werte current-db-size-bytes und current-db-size-in-use-bytes spiegeln wieder, wie Speicherplatz tatsächlich genutzt wird. Weichen diese Werte stark voneinander ab, so kann dies ein Hinweis sein, eine Defragmentierung durchzuführen.

Defragmentierung

Eine Defragmentierung sorgt dafür, dass der nicht verwendete Speicherplatz wieder freigegeben wird und eine zusammenhängende Speicherstruktur ohne "Löcher" geschaffen wird.
Dies kann manuell durch etcdctl ausgelöst werden.

Beispiel manuelle Defragmentierung von etcd
$ kubectl exec $(kubectl get pods --selector=component=etcd -A -o name | head -n 1) -n kube-system -- etcdctl  --endpoints=https://127.0.0.1:2379 --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key --cacert=/etc/kubernetes/pki/etcd/ca.crt defrag
Finished defragmenting etcd member[https://127.0.0.1:2379]

etcd ist in der Zeit, in der eine Defragmentierung durchgeführt wird, nicht verfügbar ist. Deswegen sollte eine Defragmentierung nicht parallel bei allen etcd-Mitgliedern des Clusters durchgeführt werden, sondern nacheinander.

Diese Aufgaben lassen sich natürlich auch gut automatisieren. Manche Kubernetes-Distributionen bringen dafür bereits Controller oder CronJob-Objekte mit.
Mindestens sollte ein entsprechendes Monitoring der Metrikdaten von etcd erfolgen und eine Alarmierung eingerichtet werden, wenn etcd sich dem maximal konfigurierten Speicher nähert bzw. die Nutzung und der reservierte Speicher stark auseinander klaffen.




Zu den Themen Kubernetes, Docker und Cloudarchitektur bieten wir sowohl Beratung, Entwicklungsunterstützung als auch passende Schulungen an:

Auch für Ihren individuellen Bedarf können wir Workshops und Schulungen anbieten. Sprechen Sie uns gerne an.

Feedback oder Fragen zu einem Artikel – per E-Mail an (info a-t trion.de) oder über unser Kontaktformular. Wir freuen uns auf eine Kontaktaufnahme!

Los geht's!

Bitte teilen Sie uns mit, wie wir Sie am besten erreichen können.