Zum Inhalt

Fehlerbehebung bei etcd

Info

Das gesamte Verfahren muss als root durchgeführt werden. Um Ihre Berechtigungen auf root zu erhöhen, können Sie den Befehl su - verwenden.

etcd ist ein verteilter Schlüssel-Wert-Speicher, der als Koordinationspunkt zwischen den Knoten des PostgreSQL-Clusters dient. Er zentralisiert den Zustand des Clusters zuverlässig und stellt ihn bereit, einschließlich der Identität des Leaders, des Zustands der Mitglieder und der Sperrmechanismen.

patroni stützt sich auf etcd, um die Wahl des Leader-Knotens zu steuern und bei einem Vorfall automatisch Failover auszulösen. etcd ist auf allen Knoten installiert und gewährleistet die Gesamtkonsistenz des Clusters, ohne an der Speicherung oder Verarbeitung der PostgreSQL-Daten beteiligt zu sein.

patroni hängt daher von etcd ab und kann nicht ordnungsgemäß funktionieren, wenn etcd nicht funktioniert.

Info

Die Konfiguration von etcd ist auf jedem Knoten in der Datei /etc/default/etcd gespeichert.

Protokolle

Das gesamte Verfahren stützt sich auf die Protokolle des Dienstes etcd, die Sie mit dem folgenden Befehl abrufen:

1
journalctl -u etcd

Tipp

Um die Protokolle live zu verfolgen, fügen Sie dem Befehl die Option -f hinzu:

1
journalctl -fu etcd

Info

Die Protokolle von etcd sind auch in /var/log/syslog verfügbar.

Erläuterungen zu Fehlerprotokollen

health check for peer <PEER_PSQL_NODE_ID> could not connect: dial tcp <PEER_IP_PSQL_NODE>:2380: i/o timeout

Wenn der Netzwerkfluss TCP/2380 zwischen zwei Knoten nicht geöffnet ist, tritt bei der Verbindung eine Zeitüberschreitung auf und etcd schreibt die folgenden Protokolle:

1
2
3
4
5
6
Apr 15 11:48:09 PSQL_1 etcd[1342933]: health check for peer <PEER_PSQL_NODE_ID> could not connect: dial tcp <PEER_IP_PSQL_NODE>:2380: i/o timeout
Apr 15 11:48:09 PSQL_1 etcd[1342933]: health check for peer <PEER_PSQL_NODE_ID> could not connect: dial tcp <PEER_IP_PSQL_NODE>:2380: i/o timeout
Apr 15 11:48:14 PSQL_1 etcd[1342933]: health check for peer <PEER_PSQL_NODE_ID> could not connect: dial tcp <PEER_IP_PSQL_NODE>:2380: i/o timeout
Apr 15 11:48:14 PSQL_1 etcd[1342933]: health check for peer <PEER_PSQL_NODE_ID> could not connect: dial tcp <PEER_IP_PSQL_NODE>:2380: i/o timeout
Apr 15 11:48:19 PSQL_1 etcd[1342933]: health check for peer <PEER_PSQL_NODE_ID> could not connect: dial tcp <PEER_IP_PSQL_NODE>:2380: i/o timeout
Apr 15 11:48:19 PSQL_1 etcd[1342933]: health check for peer <PEER_PSQL_NODE_ID> could not connect: dial tcp <PEER_IP_PSQL_NODE>:2380: i/o timeout

Dabei ist <PEER_PSQL_NODE_ID> die ID, die etcd dem Zielknoten zugewiesen hat, und <PEER_IP_PSQL_NODE> die IP-Adresse des Zielknotens.

Beispiel

In unserem Beispiel ist der PostgreSQL-Cluster wie folgt konfiguriert:

Knoten IP des Knotens etcd-ID
PSQL_1 192.168.1.1 53d2c129945ccb8b
PSQL_2 192.168.1.2 7176dd381f583d83
PSQL_3 192.168.1.3 e3d5ef565a5bb46c

Die Ausführung des Befehls journalctl -fu etcd auf dem Server PSQL_1 liefert die folgenden Protokolle:

1
2
3
4
5
Apr 15 11:50:39 PSQL_1 etcd[1342933]: health check for peer 7176dd381f583d83 could not connect: dial tcp 192.168.1.2:2380: i/o timeout
Apr 15 11:50:44 PSQL_1 etcd[1342933]: health check for peer 7176dd381f583d83 could not connect: dial tcp 192.168.1.2:2380: i/o timeout
Apr 15 11:50:44 PSQL_1 etcd[1342933]: health check for peer 7176dd381f583d83 could not connect: dial tcp 192.168.1.2:2380: i/o timeout
Apr 15 11:50:49 PSQL_1 etcd[1342933]: health check for peer 7176dd381f583d83 could not connect: dial tcp 192.168.1.2:2380: i/o timeout
Apr 15 11:50:49 PSQL_1 etcd[1342933]: health check for peer 7176dd381f583d83 could not connect: dial tcp 192.168.1.2:2380: i/o timeout

Diese Protokolle zeigen, dass die Verbindung vom Server PSQL_1 zum Server mit der IP-Adresse 192.168.1.2 (PSQL_2) und der etcd-ID 7176dd381f583d83 auf Port TCP/2380 nicht zustande gekommen ist: Es ist eine Zeitüberschreitung aufgetreten. Daraus lässt sich ableiten, dass der Netzwerkfluss vom Server PSQL_1 zum Server PSQL_2 von einer Firewall verworfen (DROP) wird.

Dieser Netzwerkfluss kann von der lokalen Firewall der PostgreSQL-Appliance verworfen (DROP) werden: Überprüfen Sie die Firewall-Konfiguration der Appliance auf den betroffenen Knoten. Wenn diese Konfiguration korrekt ist, verwirft (DROP) eine Firewall der Infrastruktur den Netzwerkfluss TCP/2380 zwischen den beiden Knoten.

health check for peer <PEER_PSQL_NODE_ID> could not connect: dial tcp <PEER_IP_PSQL_NODE>:2380: connect: connection refused

Wenn eine Verbindung zwischen zwei Knoten abgelehnt wird, meldet etcd dies mit den folgenden Protokollen:

1
2
3
4
5
6
Apr 15 14:04:30 PSQL_1 etcd[1342933]: health check for peer <PEER_PSQL_NODE_ID> could not connect: dial tcp <PEER_IP_PSQL_NODE>:2380: connect: connection refused
Apr 15 14:04:30 PSQL_1 etcd[1342933]: health check for peer <PEER_PSQL_NODE_ID> could not connect: dial tcp <PEER_IP_PSQL_NODE>:2380: connect: connection refused
Apr 15 14:04:35 PSQL_1 etcd[1342933]: health check for peer <PEER_PSQL_NODE_ID> could not connect: dial tcp <PEER_IP_PSQL_NODE>:2380: connect: connection refused
Apr 15 14:04:35 PSQL_1 etcd[1342933]: health check for peer <PEER_PSQL_NODE_ID> could not connect: dial tcp <PEER_IP_PSQL_NODE>:2380: connect: connection refused
Apr 15 14:04:40 PSQL_1 etcd[1342933]: health check for peer <PEER_PSQL_NODE_ID> could not connect: dial tcp <PEER_IP_PSQL_NODE>:2380: connect: connection refused
Apr 15 14:04:40 PSQL_1 etcd[1342933]: health check for peer <PEER_PSQL_NODE_ID> could not connect: dial tcp <PEER_IP_PSQL_NODE>:2380: connect: connection refused

Dabei ist <PEER_PSQL_NODE_ID> die ID, die etcd dem Zielknoten zugewiesen hat, und <PEER_IP_PSQL_NODE> die IP-Adresse des Zielknotens.

Die Ablehnung kann mehrere Ursachen haben:

  • Der Dienst etcd funktioniert auf dem Zielknoten nicht ordnungsgemäß oder ist gestoppt. Überprüfen Sie in diesem Fall den Status (systemctl status etcd) und die Protokolle des Dienstes etcd auf diesem Knoten.
  • Eine Firewall weist den Netzwerkfluss TCP/2380 zwischen den beiden Knoten zurück (REJECT). Dabei kann es sich um die lokale Firewall der Appliance oder um eine Firewall der Infrastruktur handeln.
Beispiel

In unserem Beispiel ist der PostgreSQL-Cluster wie folgt konfiguriert:

Knoten IP des Knotens etcd-ID
PSQL_1 192.168.1.1 53d2c129945ccb8b
PSQL_2 192.168.1.2 7176dd381f583d83
PSQL_3 192.168.1.3 e3d5ef565a5bb46c

Die Ausführung des Befehls journalctl -fu etcd auf dem Server PSQL_1 liefert die folgenden Protokolle:

1
2
3
4
5
Apr 15 14:04:15 PSQL_1 etcd[1342933]: health check for peer e3d5ef565a5bb46c could not connect: dial tcp 192.168.1.3:2380: connect: connection refused
Apr 15 14:04:15 PSQL_1 etcd[1342933]: health check for peer e3d5ef565a5bb46c could not connect: dial tcp 192.168.1.3:2380: connect: connection refused
Apr 15 14:04:20 PSQL_1 etcd[1342933]: health check for peer e3d5ef565a5bb46c could not connect: dial tcp 192.168.1.3:2380: connect: connection refused
Apr 15 14:04:20 PSQL_1 etcd[1342933]: health check for peer e3d5ef565a5bb46c could not connect: dial tcp 192.168.1.3:2380: connect: connection refused
Apr 15 14:04:25 PSQL_1 etcd[1342933]: health check for peer e3d5ef565a5bb46c could not connect: dial tcp 192.168.1.3:2380: connect: connection refused

Diese Protokolle zeigen, dass die Verbindung vom Server PSQL_1 zum Server mit der IP-Adresse 192.168.1.3 (PSQL_3) und der etcd-ID e3d5ef565a5bb46c auf Port TCP/2380 abgelehnt wurde.

Auf dem Server PSQL_3 zeigt der Befehl systemctl status etcd, dass etcd gestoppt ist:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
○ etcd.service - etcd - highly-available key value store
    Loaded: loaded (/lib/systemd/system/etcd.service; enabled; preset: enabled)
    Active: inactive (dead) since Wed 2026-04-15 16:09:34 CEST; 38s ago
Duration: 1min 36.087s
    Docs: https://etcd.io/docs
            man:etcd
    Process: 1400558 ExecStart=/usr/bin/etcd $DAEMON_ARGS (code=killed, signal=TERM)
Main PID: 1400558 (code=killed, signal=TERM)
        CPU: 49.071s

Apr 15 12:26:32 PSQL_3 etcd[1197556]: finished scheduled compaction at 1665243 (took 583.297µs)
Apr 15 13:26:32 PSQL_3 etcd[1197556]: store.index: compact 1665949
Apr 15 13:26:32 PSQL_3 etcd[1197556]: finished scheduled compaction at 1665949 (took 574.496µs)
Apr 15 14:26:32 PSQL_3 etcd[1197556]: store.index: compact 1666658
Apr 15 14:26:32 PSQL_3 etcd[1197556]: finished scheduled compaction at 1666658 (took 567.196µs)
Apr 15 15:26:32 PSQL_3 etcd[1197556]: store.index: compact 1667368
Apr 15 15:26:32 PSQL_3 etcd[1197556]: finished scheduled compaction at 1667368 (took 568.096µs)
Apr 15 16:09:34 PSQL_3 systemd[1]: etcd.service: Deactivated successfully.
Apr 15 16:09:34 PSQL_3 systemd[1]: Stopped etcd.service - etcd - highly-available key value store.
Apr 15 16:09:34 PSQL_3 systemd[1]: etcd.service: Consumed 49.071s CPU time.

Sobald etcd gestartet ist, ist das Problem behoben.

rejected connection from "<PEER_IP_PSQL_NODE>:35956" (error "remote error: tls: bad certificate", ServerName "PSQL_1")

Wenn die Zertifikate des PostgreSQL-Clusters abgelaufen sind oder auf dem Knoten, auf dem Sie die Protokolle lesen, nicht ordnungsgemäß installiert oder erneuert wurden, erscheint der folgende Fehler in den Protokollen von etcd:

1
2
3
4
5
6
Apr 15 16:38:54 PSQL_1 etcd[1407644]: rejected connection from "<PEER_IP_PSQL_NODE>:49274" (error "remote error: tls: bad certificate", ServerName "PSQL_1")
Apr 15 16:38:54 PSQL_1 etcd[1407644]: rejected connection from "<PEER_IP_PSQL_NODE>:49294" (error "remote error: tls: bad certificate", ServerName "PSQL_1")
Apr 15 16:38:54 PSQL_1 etcd[1407644]: rejected connection from "<PEER_IP_PSQL_NODE>:49288" (error "remote error: tls: bad certificate", ServerName "PSQL_1")
Apr 15 16:38:55 PSQL_1 etcd[1407644]: rejected connection from "<PEER_IP_PSQL_NODE>:49316" (error "remote error: tls: bad certificate", ServerName "PSQL_1")
Apr 15 16:38:55 PSQL_1 etcd[1407644]: rejected connection from "<PEER_IP_PSQL_NODE>:49304" (error "remote error: tls: bad certificate", ServerName "PSQL_1")
Apr 15 16:38:55 PSQL_1 etcd[1407644]: rejected connection from "<PEER_IP_PSQL_NODE>:60958" (error "remote error: tls: bad certificate", ServerName "PSQL_1")

Dabei ist <PEER_IP_PSQL_NODE> die IP-Adresse eines der Cluster-Knoten.

Dieser Protokolleintrag zeigt, dass die anderen Cluster-Knoten (<PEER_IP_PSQL_NODE>) den Verbindungsversuch des Knotens, mit dem Sie verbunden sind, abgelehnt und dabei einen Fehler im Zertifikat des aktuellen Knotens gemeldet haben.

Überprüfen Sie daher auf dem Knoten, mit dem Sie verbunden sind, die Gültigkeit der Cluster-Zertifikate.

Achtung

Wenn die auf einem entfernten Knoten konfigurierte Zertifizierungsstelle (in /etc/etcd/ca.crt) falsch ist, erscheint der Fehler ebenfalls auf dem Knoten, auf dem Sie die Protokolle lesen: Er bedeutet dann, dass der entfernte Knoten das vorgelegte Zertifikat nicht validieren kann, weil er nicht über die richtige CA verfügt.

Beispiel

In unserem Beispiel ist der PostgreSQL-Cluster wie folgt konfiguriert:

Knoten IP des Knotens etcd-ID
PSQL_1 192.168.1.1 53d2c129945ccb8b
PSQL_2 192.168.1.2 7176dd381f583d83
PSQL_3 192.168.1.3 e3d5ef565a5bb46c

Die Ausführung des Befehls journalctl -fu etcd auf dem Server PSQL_1 liefert die folgenden Protokolle:

1
2
3
4
5
6
Apr 15 16:38:54 PSQL_1 etcd[1407644]: rejected connection from "192.168.1.2:49274" (error "remote error: tls: bad certificate", ServerName "PSQL_1")
Apr 15 16:38:54 PSQL_1 etcd[1407644]: rejected connection from "192.168.1.3:49294" (error "remote error: tls: bad certificate", ServerName "PSQL_1")
Apr 15 16:38:54 PSQL_1 etcd[1407644]: rejected connection from "192.168.1.2:49288" (error "remote error: tls: bad certificate", ServerName "PSQL_1")
Apr 15 16:38:55 PSQL_1 etcd[1407644]: rejected connection from "192.168.1.2:49316" (error "remote error: tls: bad certificate", ServerName "PSQL_1")
Apr 15 16:38:55 PSQL_1 etcd[1407644]: rejected connection from "192.168.1.3:49304" (error "remote error: tls: bad certificate", ServerName "PSQL_1")
Apr 15 16:38:55 PSQL_1 etcd[1407644]: rejected connection from "192.168.1.3:60958" (error "remote error: tls: bad certificate", ServerName "PSQL_1")

Diese Protokolle zeigen, dass die Knoten PSQL_2 und PSQL_3 die Verbindung des Knotens PSQL_1 abgelehnt haben, weil das Zertifikat von PSQL_1 in diesem Kontext nicht gültig ist.

Wir überprüfen daher die Gültigkeit der Zertifikate des Knotens PSQL_1 gemäß dem Verfahren zur Überprüfung der Cluster-Zertifikate:

1
2
openssl x509 -in /etc/etcd/peer.crt -noout -enddate
openssl x509 -in /etc/etcd/ca.crt -noout -enddate

Die Ausgabe zeigt, dass das Knotenzertifikat abgelaufen ist:

1
2
notAfter=Dec 18 14:04:09 2025 GMT
notAfter=Dec 17 14:03:47 2030 GMT

In diesem Fall müssen Sie die Zertifikate des PostgreSQL-Clusters erneuern.

error listing data dir: /var/lib/etcd/cleanroom

Wenn etcd nicht über die richtigen Berechtigungen für das Verzeichnis /var/lib/etcd/cleanroom verfügt, verweigert der Dienst den Start und schreibt die folgenden Protokolle:

1
2
3
4
5
6
Apr 10 14:15:26 PSQL_1 etcd[454701]: Go OS/Arch: linux/amd64
Apr 10 14:15:26 PSQL_1 etcd[454701]: setting maximum number of CPUs to 1, total number of available CPUs is 1
Apr 10 14:15:26 PSQL_1 etcd[454701]: error listing data dir: /var/lib/etcd/cleanroom
Apr 10 14:15:26 PSQL_1 systemd[1]: etcd.service: Main process exited, code=exited, status=1/FAILURE
Apr 10 14:15:26 PSQL_1 systemd[1]: etcd.service: Failed with result 'exit-code'.
Apr 10 14:15:26 PSQL_1 systemd[1]: Failed to start etcd.service - etcd - highly-available key value store

Um dieses Problem zu beheben, weisen Sie dem Verzeichnis mit dem folgenden Befehl die richtigen Berechtigungen zu:

1
chown -R etcd:etcd /var/lib/etcd/cleanroom