Към съдържанието

Отстраняване на неизправности в etcd

Информация

Цялата процедура трябва да се изпълни като root. За да повишите привилегиите си до root, можете да използвате командата su -.

etcd е разпределено хранилище от тип ключ-стойност, използвано като точка за координация между възлите на клъстера PostgreSQL. То надеждно централизира и споделя състоянието на клъстера, включително самоличността на лидера, състоянието на членовете и механизмите за заключване.

patroni разчита на etcd, за да управлява избора на водещ възел и автоматично да задейства превключвания при отказ, когато възникне инцидент. Инсталиран на всички възли, etcd гарантира цялостната съгласуваност на клъстера, без да участва в съхраняването или обработката на данните на PostgreSQL.

Следователно patroni зависи от etcd и не може да работи правилно, ако etcd не работи.

Информация

Конфигурацията на etcd се съхранява във файла /etc/default/etcd на всеки възел.

Logs

Цялата процедура се основава на дневниците на услугата etcd, които получавате с командата по-долу:

1
journalctl -u etcd

Съвет

За да следите дневниците в реално време, добавете опцията -f към командата:

1
journalctl -fu etcd

Информация

Дневниците на etcd са налични и в /var/log/syslog.

Обяснения на дневниците с грешки

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

Ако потокът TCP/2380 не е отворен между два възела, времето за изчакване на връзката изтича и etcd записва следните редове в дневника:

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

Където <PEER_PSQL_NODE_ID> е идентификаторът, присвоен от etcd на целевия възел, а <PEER_IP_PSQL_NODE> – IP адресът на целевия възел.

Пример

В нашия пример клъстерът PostgreSQL е конфигуриран, както следва:

Възел IP на възела ID на etcd
PSQL_1 192.168.1.1 53d2c129945ccb8b
PSQL_2 192.168.1.2 7176dd381f583d83
PSQL_3 192.168.1.3 e3d5ef565a5bb46c

Изпълнението на командата journalctl -fu etcd от сървъра PSQL_1 дава следните записи в дневника:

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

Тези записи показват, че връзката от сървъра PSQL_1 към сървъра с IP адрес 192.168.1.2 (PSQL_2) и ID на etcd 7176dd381f583d83 на порт TCP/2380 не е успешна: времето за изчакване е изтекло. Можем да заключим, че потокът от сървъра PSQL_1 към сървъра PSQL_2 се блокира (DROP) от защитна стена.

Този поток може да бъде блокиран (DROP) от локалната защитна стена на устройството PostgreSQL: проверете конфигурацията на защитната стена на устройството на засегнатите възли. Ако тази конфигурация е правилна, защитна стена в инфраструктурата блокира (DROP) потока TCP/2380 между двата възела.

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

Когато връзка между два възела бъде отказана, etcd съобщава за това със следните записи в дневника:

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

Където <PEER_PSQL_NODE_ID> е идентификаторът, присвоен от etcd на целевия възел, а <PEER_IP_PSQL_NODE> – IP адресът на целевия възел.

Отказът може да има няколко причини:

  • Услугата etcd не работи правилно или е спряна на целевия възел. В този случай проверете състоянието (systemctl status etcd) и дневниците на услугата etcd на този възел.
  • Защитна стена отхвърля (REJECT) потока TCP/2380 между двата възела. Това може да бъде локалната защитна стена на устройството или защитна стена в инфраструктурата.
Пример

В нашия пример клъстерът PostgreSQL е конфигуриран, както следва:

Възел IP на възела ID на etcd
PSQL_1 192.168.1.1 53d2c129945ccb8b
PSQL_2 192.168.1.2 7176dd381f583d83
PSQL_3 192.168.1.3 e3d5ef565a5bb46c

Изпълнението на командата journalctl -fu etcd от сървъра PSQL_1 дава следните записи в дневника:

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

Тези записи показват, че връзката от сървъра PSQL_1 към сървъра с IP адрес 192.168.1.3 (PSQL_3) и ID на etcd e3d5ef565a5bb46c на порт TCP/2380 е отказана.

На сървъра PSQL_3 командата systemctl status etcd показва, че etcd е спрян:

 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.

След като etcd бъде стартиран, проблемът е решен.

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

Ако сертификатите на клъстера PostgreSQL са изтекли или не са били правилно инсталирани или подновени на възела, от който четете дневниците, в дневниците на 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")

Където <PEER_IP_PSQL_NODE> е IP адресът на един от възлите на клъстера.

Този запис показва, че когато възелът, към който сте свързани, се е опитал да установи връзка с другите възли на клъстера (<PEER_IP_PSQL_NODE>), те са я отказали, като са съобщили за грешка в сертификата на текущия възел.

Следователно трябва да проверите валидността на сертификатите на клъстера на възела, към който сте свързани.

Предупреждение

Ако сертифициращият орган, конфигуриран на отдалечен възел (в /etc/etcd/ca.crt), е неправилен, грешката също се появява на възела, от който четете дневниците: тогава тя показва, че отдалеченият възел не може да провери представения сертификат, защото не разполага с правилния сертифициращ орган.

Пример

В нашия пример клъстерът PostgreSQL е конфигуриран, както следва:

Възел IP на възела ID на etcd
PSQL_1 192.168.1.1 53d2c129945ccb8b
PSQL_2 192.168.1.2 7176dd381f583d83
PSQL_3 192.168.1.3 e3d5ef565a5bb46c

Изпълнението на командата journalctl -fu etcd от сървъра PSQL_1 дава следните записи в дневника:

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")

Тези записи показват, че възлите PSQL_2 и PSQL_3 са отказали връзката от възела PSQL_1, защото сертификатът на PSQL_1 не е валиден в този контекст.

Затова проверяваме валидността на сертификатите на възела PSQL_1, като следваме процедурата за проверка на сертификатите на клъстера:

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

Резултатът показва, че сертификатът на възела е изтекъл:

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

В този случай трябва да подновите сертификатите на клъстера PostgreSQL.

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

Ако etcd няма правилните разрешения за директорията /var/lib/etcd/cleanroom, услугата отказва да стартира и записва следните редове в дневника:

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

За да решите този проблем, задайте правилните разрешения за директорията със следната команда:

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