Відновлення після катастрофи
etcd розроблений для витримування збоїв машин. Кластер etcd автоматично відновлюється після тимчасових збоїв (наприклад, перезавантаження машини) і витримує до (N-1)/2 постійних збоїв для кластера з N учасників. Коли учасник постійно виходить з ладу, хай то через апаратний збій або пошкодження диска, він втрачає доступ до кластера. Якщо кластер постійно втрачає більше ніж (N-1)/2 учасників, то він катастрофічно виходить з ладу, безповоротно втрачаючи кворум. Після втрати кворуму кластер не може досягти консенсусу і, отже, не може продовжувати приймати оновлення.
Щоб відновитися після катастрофічного збою, etcd v3 надає можливості знімка та відновлення для відтворення кластера без втрати даних ключів v3. Щоб відновити ключі v2, зверніться до посібника адміністратора v2.
Знімок простору ключів
Для відновлення кластера спочатку потрібен знімок простору ключів від учасника etcd. Знімок можна зробити або з живого учасника за допомогою команди etcdctl snapshot save
, або скопіювавши файл member/snap/db
з теки даних etcd. Наприклад, наступна команда створює знімок простору ключів, який обслуговується $ENDPOINT
, у файл snapshot.db
:
$ ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save snapshot.db
Зверніть увагу, що створення знімка з файлу member/snap/db
може призвести до втрати даних, які ще не були записані, але включені у теку wal (журнал попереднього запису).
Статус знімка
Щоб зрозуміти, який перегляд і хеш містить даний знімок, ви можете використовувати команду etcdutl snapshot status
:
$ etcdutl snapshot status snapshot.db -w table
+---------+----------+------------+------------+
| HASH | REVISION | TOTAL KEYS | TOTAL SIZE |
+---------+----------+------------+------------+
| 7ef846e | 485261 | 11642 | 94 MB |
+---------+----------+------------+------------+
Відновлення кластера
Різниця між ревізіями
Коли ви відновлюєте кластер, наявні клієнти можуть сприймати ревізію як таку, що повернулася на багато сотень або тисяч кроків назад. Це повʼязано з тим, що певний знімок містить лише послідовність даних до того моменту, коли його було зроблено, тоді як поточний стан може бути вже далеко попереду.
Це особливо актуально при запуску Kubernetes за допомогою etcd, де контролери та оператори можуть використовувати так звані інформери, які діють як локальний кеш і отримують сповіщення про оновлення за допомогою watch. Відновлення до старішої ревізії може неправильно оновити кеш, що призведе до непередбачуваної та непослідовної поведінки контролерів.
При відновленні зі знімка в контексті: відомих споживачів watch API, локальних кешованих копій даних etcd або при використанні Kubernetes в цілому, наполегливо рекомендується відновлювати за допомогою «revision bumps», наведених нижче.
Відновлення зі знімка
Для відновлення кластера потрібен лише один файл “db” знімка. Відновлення кластера за допомогою etcdutl snapshot restore
створює нові теки даних etcd; всі учасники повинні відновлюватися з одного і того ж знімка. Відновлення перезаписує деякі метадані знімка (зокрема, ідентифікатор учасника та ідентифікатор кластера); учасник втрачає свою колишню ідентичність. Цей перезапис метаданих запобігає випадковому приєднанню нового учасника до наявного кластера. Тому для запуску кластера зі знімка відновлення повинно почати новий логічний кластер.
Просте відновлення можна виконати так:
$ etcdutl snapshot restore snapshot.db --data-dir output-dir
Перевірка цілісності
Цілісність знімка може бути перевірена під час відновлення. Якщо знімок зроблено за допомогою etcdctl snapshot save
, він матиме хеш цілісності, який перевіряється etcdutl snapshot restore
. Якщо знімок скопійовано з теки даних, хеш цілісності відсутній, і він буде відновлений лише за допомогою --skip-hash-check
.
Відновлення з revison bump
Щоб гарантувати, що після відновлення ревізія не зменшиться, ви можете вказати параметр --bump-revision
. Цей параметр приймає 64-бітове ціле число, яке вказує на кількість ревізій, які слід додати до поточної ревізії знімка. Оскільки кожен запис до etcd збільшує ревізію на одиницю, ви можете покрити тижневий знімок зсувом на 1'000'000'000, якщо припустити, що etcd працює зі швидкістю менше ніж 1500 записів на секунду.
У контексті контролерів Kubernetes важливо також позначити всі перегляди, включаючи підвищення, як стиснуті за допомогою --mark-compacted
. Це забезпечує завершення всіх спостережень і etcd не відповідає на запити про ревізії, які відбулися після створення знімка, що ефективно анулює кеші інформерів.
Повний виклик може виглядати так:
$ etcdutl snapshot restore snapshot.db --bump-revision 1000000000 --mark-compacted --data-dir output-dir
Відновлення з оновленим членством
Учасники кластера etcd зберігаються в самому etcd і підтримуються за допомогою алгоритму консенсусу raft. Коли кворум повністю втрачено, ви можете переглянути, де і як формується новий кластер, наприклад, на абсолютно новому наборі учасників.
При відновленні зі знімка ви можете безпосередньо надати нове членство в сховище даних наступним чином:
$ etcdutl snapshot restore snapshot.db \
--name m1 \
--initial-cluster m1=http://host1:2380,m2=http://host2:2380,m3=http://host3:2380 \
--initial-cluster-token etcd-cluster-1 \
--initial-advertise-peer-urls http://host1:2380
Це забезпечує, що новостворений кластер підключається лише до інших відновлених учасників з даним токеном, а не до старих учасників, які можуть ще бути живими та намагатися приєднатися.
Альтернативно, при запуску etcd, ви можете використовувати --force-new-cluster
для перезапису членства кластера, зберігаючи наявні дані застосунків. Зверніть увагу, що це наполегливо не рекомендується, оскільки це викличе паніку, якщо інші учасники з попереднього кластера ще живі. Обовʼязково періодично зберігайте знімки.
Приклад від початку до кінця
Отримайте знімок з живого кластера за допомогою:
$ etcdctl snapshot save snapshot.db
Продовжуючи з попереднього прикладу, наступне створює нові теки даних etcd (m1.etcd
, m2.etcd
, m3.etcd
) для кластера з трьох учасників:
$ etcdutl snapshot restore snapshot.db \
--name m1 \
--initial-cluster m1=http://host1:2380,m2=http://host2:2380,m3=http://host3:2380 \
--initial-cluster-token etcd-cluster-1 \
--initial-advertise-peer-urls http://host1:2380
$ etcdutl snapshot restore snapshot.db \
--name m2 \
--initial-cluster m1=http://host1:2380,m2=http://host2:2380,m3=http://host3:2380 \
--initial-cluster-token etcd-cluster-1 \
--initial-advertise-peer-urls http://host2:2380
$ etcdutl snapshot restore snapshot.db \
--name m3 \
--initial-cluster m1=http://host1:2380,m2=http://host2:2380,m3=http://host3:2380 \
--initial-cluster-token etcd-cluster-1 \
--initial-advertise-peer-urls http://host3:2380
Далі, запустіть etcd
з новими теками даних:
$ etcd \
--name m1 \
--listen-client-urls http://host1:2379 \
--advertise-client-urls http://host1:2379 \
--listen-peer-urls http://host1:2380 &
$ etcd \
--name m2 \
--listen-client-urls http://host2:2379 \
--advertise-client-urls http://host2:2379 \
--listen-peer-urls http://host2:2380 &
$ etcd \
--name m3 \
--listen-client-urls http://host3:2379 \
--advertise-client-urls http://host3:2379 \
--listen-peer-urls http://host3:2380 &
Тепер відновлений кластер etcd повинен бути доступним і обслуговувати простір ключів зі знімка.
Відгук
Чи це було корисним?
Раді чути! Будь ласка, повідомте нам, як ми можемо зробити краще.
Дуже шкода це чути. Будь ласка, повідомте нам, як ми можемо зробити краще.