Дизайн реконфігурації під час виконання

Дизайн команд конфігурації під час виконання в etcd

Реконфігурація під час виконання є однією з найскладніших і найбільш схильних до помилок функцій у розподіленій системі, особливо в системах, заснованих на консенсусі, таких як etcd.

Читайте далі, щоб дізнатися про дизайн команд конфігурації під час виконання в etcd і як ми розвʼязали ці проблеми.

Двофазні зміни конфігурації забезпечують безпеку кластера

У etcd кожна конфігурація під час виконання повинна проходити через дві фази з міркувань безпеки. Наприклад, щоб додати учасника, спочатку повідомте кластер про нову конфігурацію, а потім запустіть нового учасника.

Фаза 1 — Повідомлення кластера про нову конфігурацію

Щоб додати учасника до кластера etcd, зробіть API-запит на додавання нового учасника до кластера. Це єдиний спосіб додати нового учасника до кластера. API-запит повертається, коли кластер погоджується на зміну конфігурації.

Фаза 2 — Запуск нового учасника

Щоб приєднати нового учасника etcd до кластера, вкажіть правильний initial-cluster і встановіть initial-cluster-state на existing. Коли учасник запускається, він спочатку звʼязується з кластером і перевіряє, чи поточна конфігурація кластера відповідає очікуваній, зазначеній у initial-cluster. Коли новий учасник успішно запускається, кластер досягає очікуваної конфігурації.

Поділ процесу на дві окремі фази змушує користувачів чітко висловлюватися щодо зміни членства в кластері. Це насправді дає користувачам більше гнучкості та полегшує розуміння. Наприклад, якщо спробувати додати нового учасника з тим самим ідентифікатором, що й в наявного учасника в кластері etcd, дія негайно зазнає невдачі під час першої фази без впливу на працюючий кластер. Подібний захист забезпечується для запобігання випадковому додаванню нових учасників. Якщо новий учасник etcd намагається приєднатися до кластера до того, як кластер прийме зміну конфігурації, кластер його не прийме.

Без явного робочого процесу навколо складу кластера etcd був би вразливий до несподіваних змін у складі кластера. Наприклад, якщо etcd працює під керуванням системи ініціалізації, такої як systemd, etcd буде перезапущено після видалення через API членства і спробує знову приєднатися до кластера під час запуску. Цей цикл продовжуватиметься щоразу, коли учасника видаляють через API, а systemd налаштовано на перезапуск etcd після збою, що є несподіваним.

Ми очікуємо, що реконфігурація під час виконання буде нечастою операцією. Ми вирішили зробити її явною та керованою користувачем, щоб забезпечити безпеку конфігурації та постійну безперебійну роботу кластера під явним контролем.

Постійна втрата кворуму вимагає нового кластера

Якщо кластер назавжди втрачає більшість своїх учасників, потрібно буде запустити новий кластер зі старої теки даних, щоб відновити попередній стан.

Цілком можливо примусово видалити невдалі учасники з наявного кластера для відновлення. Однак ми вирішили не підтримувати цей метод, оскільки він обходить нормальну фазу досягнення консенсусу, що є небезпечним. Якщо учасник, якого потрібно видалити, насправді не мертвий або примусово видалений через різних учасників у тому ж кластері, etcd закінчиться розділеним кластером з тим самим ідентифікатором кластера. Це дуже небезпечно і важко виправити/усунути потім.

З правильним розгортанням ймовірність постійної втрати більшості дуже низька. Але це досить серйозна проблема, яка варта особливої уваги. Ми наполегливо рекомендуємо прочитати документацію з відновлення після катастроф і підготуватися до постійної втрати більшості перед введенням etcd у промислову експлуатацію.

Не використовуйте публічну службу виявлення для конфігурації під час виконання

Публічна служба виявлення повинна використовуватися лише для початкового завантаження кластера. Щоб приєднати учасника до наявного кластера, використовуйте API конфігурації під час виконання.

Служба виявлення призначена для початкового завантаження кластера etcd у хмарному середовищі, коли IP-адреси всіх учасників заздалегідь невідомі. Після успішного початкового завантаження кластера IP-адреси всіх учасників відомі. Технічно, служба виявлення більше не потрібна.

Здається, що використання публічної служби виявлення є зручним способом для конфігурації під час виконання, адже служба виявлення вже має всю інформацію про конфігурацію кластера. Однак покладання на публічну службу виявлення приносить проблеми:

  1. це вводить зовнішні залежності для всього життєвого циклу кластера, а не лише для часу початкового завантаження. Якщо виникне проблема з мережею між кластером і публічною службою виявлення, кластер постраждає від цього.

  2. публічна служба виявлення повинна відображати правильну конфігурацію під час виконання кластера протягом його життєвого циклу. Вона повинна забезпечувати механізми безпеки для уникнення поганих дій, і це важко.

  3. публічна служба виявлення повинна зберігати десятки тисяч конфігурацій кластерів. Наш бекенд публічної служби виявлення не готовий до такого навантаження.

Щоб мати службу виявлення, яка підтримує конфігурацію під час виконання, найкращим вибором є створення приватної служби.