Конфигурация и администрирование Raft ордеринг-службы

Аудитория: Администраторы Raft ордеринг-служб

Общие сведения

Для более высокоуровневой информации об ордеринге и о поддержке различных реализаций ордеринг-служб (включая Raft), обратитесь к статье Orderign-служба.

Для информации об установке ордеринг-службы, включая создание локального MSP и genesis-блока, обратитесь к статье Установка ordering-узла.

Настройка

Хотя каждый Raft-узел должен быть добавлен в системный канал, его не нужно добавлять в каждый другой канал. Также вы можете добавить или исключить ноду из канала бесшовно, не влияя на другие ноды, через процесс, описанный в секции Перенастройка ниже.

Рафт-узлы могут идентифицировать друг друга с помощью TLS pinning (привязывание ключей), поэтому если злоумышленник захочет притворится Raft-узлом, ему нужно будет заполучить приватный ключ TLS-сертификата узла. Для работы Raft-узла необходима валидная конфигурация TLS.

Raft-кластер настраивается в двух местах:

  • Локальная конфигурация: Определяет аспекты конкретного узла, такие как TLS, репликационное поведение и файловое хранилище.
  • Конфигурация канала: Определяет членов кластера и параметры протокола для определенного канала, такие как частота heartbeat, время ожидания соединения с лидером и т.д.

Каждый канал имеет свою конфигурацию Raft. Каждый Raft-узел, использующийся каналом, должен быть указан в конфигурации канала, куда необходимо добавить серверные и клиентские сертификаты узла в PEM-формате. Это гарантирует, что если другие узлы получат от Raft-узла сообщение, они смогут подтвердить identity узла.

Следующая секция configtx.yaml определяет три Raft-узла канала (так же называемые «consenters»):

       Consenters:
            - Host: raft0.example.com
              Port: 7050
              ClientTLSCert: path/to/ClientTLSCert0
              ServerTLSCert: path/to/ServerTLSCert0
            - Host: raft1.example.com
              Port: 7050
              ClientTLSCert: path/to/ClientTLSCert1
              ServerTLSCert: path/to/ServerTLSCert1
            - Host: raft2.example.com
              Port: 7050
              ClientTLSCert: path/to/ClientTLSCert2
              ServerTLSCert: path/to/ServerTLSCert2

Ордерер-узел будет указан как consenter в системном канале и в любом другом, в котором он состоит.

Когда конфигурация канала создана, configtxgen заменяет пути к TLS-сертификатам на соответствующие байтовые представления сертификатов.

Локальная конфигурация

orderer.yaml имеет две конфигурационные секции, относящиеся к Raft-ордерерам:

Cluster, определяющий конфигурацию TLS, и consensus, определяющий, где хранятся Write Ahead Logs и Snapshots.

Параметры Cluster:

По умолчанию, Raft-служба (Raft service) работает на том же gRPC-сервере, что клиентский сервер (используемый клиентами, чтобы отправлять транзакции или загружать блоки), но она может быть настроена на отдельном gRPC-сервере с отдельным портом.

Это полезно в случаях, когда вы хотите, чтобы TLS-сертификаты, выпущенные CA организаций, использовались только для взаимодействия узлов кластера между собой, а сертификаты, выпущенные публичным CA, использовались для клиентского API.

  • ClientCertificate, ClientPrivateKey: Путь к клиентскому TLS-сертификату и путь к соответствующему приватному ключу.
  • ListenPort: Порт, прослушиваемый кластером. Если поле не заполнено, то порт такой же, как general.listenPort.
  • ListenAddress: Адрес, прослушиваемый кластер-службой.
  • ServerCertificate, ServerPrivateKey: Путь к серверному TLS-сертификату и путь к соответствующему приватному ключу. Используется, когда кластер-служба работает на отдельном gRPC-сервере (отдельный порт).
  • SendBufferSize: Регулирует количество сообщений в выходном буфере (egress buffer).

Важно: ListenPort, ListenAddress, ServerCertificate, ServerPrivateKey должны быть либо все заполнены, либо все не заполнены. Если не заполнены, то они наследуются из секции general TLS, например general.tls.{privateKey, certificate}.

Также есть дополнительные параметры для general.cluster, которые могут использоваться для еще более тонкой настройки репликационного механизма или внутрикластерного взаимодействия:

  • DialTimeout, RPCTimeout: интервал ожидания создания соединений и gRPC-потоков.
  • ReplicationBufferSize: максимальное число байт, которое может быть выделено для каждого хранящегося в памяти буфера, используемого для репликации блоков с других узлов кластера. Каждый канал имеет свой буфер. По умолчанию 20971520 (20MB).
  • PullTimeout: максимальное время до разрыва соединения, которое узел ждет, пока клиент загрузит блок. По умолчанию 5 секунд.
  • ReplicationRetryTimeout: максимальный интервал ожидания между двумя последовательными попытками. По умолчанию 5 секунд.
  • ReplicationBackgroundRefreshInterval: интервал между двумя последовательными попытками реплицировать существующие каналы, к которым был добавлен узел, или каналы, реплицировать которые в прошлом узлу не удалось. По умолчанию 5 минут.
  • TLSHandshakeTimeShift: Если TLS-сертификаты узлов просрочились и не были вовремя заменены, взаимодействие между ними не может быть установлено и будет невозможно послать новую транзакцию ордеринг-службе. Чтобы восстановить работу в этом сценарии, возможно предположить, что TLS-рукопожатия сместились назад во времени на заданный интервал, установленный в TLSHandshakeTimeShift. Для того, чтобы это не могло быть использовано злоумышленниками, эта опция доступно только для узлов с отдельным gRPC-сервером для внутрикластерной коммуникации.

Параметры Consensus:

  • WALDir: путь, по которому хранятся Write Ahead Logs для etcd/raft. Каждый канал имеет там свою поддиректорию с именем ID канала.
  • SnapDir: путь хранения snapshots для etcd/raft. Каждый канал имеет там свою поддиректорию с именем ID канала.

Дополнительный параметр, который можно установить в секции consensus orderer.yaml:

  • EvictionSuspicion: Накопленный интервал подозрения об исключении из канала (channel eviction suspicion), при достижения этого интервала узел запросит блок канала от других узлов, чтобы понять, был ли он исключен из канала. Если да (подозрение подтвердилось, полученный блок не содержит TLS-сертификата узла), узел прекращает свою работу в этом канале. Узел подозревает о своем исключении, если он не знает про выбранного лидера и не участвует в выборах. По умолчанию 10 минут.

Конфигурация канала

Кроме consenters, Raft конфигурация канала имеет секцию Options, предоставляющую настройки конкретно для Raft. На текущий момент настройки из Options нельзя изменить, не перезапустив узел. Единственной исключение - SnapshotIntervalSize.

Рекомендуется не менять следующие значения, так как неправильная настройка может привести к тому, что кластер не сможет выбрать лидера (например если TickInterval и ElectionTick слишком низкие). Такая ситуация не разрешима, так как все изменения должны исходить от лидера.

  • TickInterval: Интервал между двумя Node.Tick.
  • ElectionTick: Число Node.Tick, которое должно пройти для новых выборов: если подписчик (follower) не получает никаких сообщений от лидера на протяжении ElectionTick, он начнет выборы и станет кандидатом.
  • ElectionTick должен быть больше, чем HeartbeatTick.
  • HeartbeatTick: Число Node.Tick, которые должны пройти между двумя heartbeats: лидер посылает heartbeat-сообщения для того, чтобы оставаться лидером каждый HeartbeatTick-по счету тик.
  • MaxInflightBlocks: Ограничивает максимальное число in-flight append блоков во время optimistic replication phase.
  • SnapshotIntervalSize: Интервал в байтах между снятием двух snapshots.

Перенастройка

Raft-ордерер поддерживает динамическое (то есть происходящее без остановки работы канала) исключение или добавление узлов по одному за раз. Заметьте, что кластер должен быть рабочим и достигать консенсуса до того, как вы попытаетесь его перенастроить. Например, если у вас есть три узла и два из них упали, вы не сможете перенастроить кластер чтобы исключить упавшие узлы. Аналогично, если один из трех узлов кластера упал, не следует пытаться обновить сертификат. Как правило, не следует делать никаких изменений конфигурации Raft consenter“ов, таких как добавление или исключение consenter“а или обновление сертификата consenter“а, если только не все constenters онлайн и работают без сбоев.

Если вы все таки решите обновить параметры, рекомендуется делать это во время технического обслуживания. Проблемы чаще всего возникают в кластерах с небольшим количеством узлов, в которых, при этом, несколько узлов (или один) упали. Например, если у вас три узла и один из них упал и вы добавите еще один узел, у вас будут работать только 2 узла из 4, и это не большинство, так как добавленный узел может начать работу только в полностью функционирующих кластерах (если размер кластера не 1 или 2).

В этом примере вы застряли до тех пор, пока не поднимите упавший, третий, узел.

Алгоритм добавления узла в Raft-кластер:

  1. Добавление TLS-сертификатов нового узла через транзакцию обновления конфигурации канала. Новый узел должен быть добавлен в системный канал до того, как будет добавлен в какой-либо другой.
  2. Получение последнего конфигурационного блока системного канала от уже существующего ордерер-узла системного канала.
  3. Проверка, что узел был добавлен в системный канал – полученный конфигурационный блок должен содержать сертификат нового узла.
  4. Запуск нового узла с путем к конфигурационному блоку, указанному в параметре конфигурации General.BootstrapFile.
  5. Ожидание узла, пока он не реплицирует блоки от существующих узлов всех каналов, в которые был добавлен сертификат нового узла. После завершения этого шага узел начинает работу в каналах.
  6. Добавление endpoint нового узла в конфигурацию всех соответствующих каналов.

Возможно добавить в канал уже работающий узел без его перезагрузки. Для этого просто добавьте сертификат узла в конфигурацию канала. Узел самостоятельно обнаружит добавление в канал (стандартный период - 5 минут, но вы можете настроит узел для более быстрого обнаружения, для этого придется его перезагрузить). Далее он извлечет блоки канала от другого узла системного канала и запустит Raft instance для нового блокчейна.

После этого добавьте в конфигурацию канала endpoint нового Raft-ордерера.

Алгоритм исключения узла из Raft-кластера:

  1. Исключить endpoint узла из всех каналов, включая системный.
  2. Исключить все его сертификаты из конфигураций всех каналов, включая системный.
  3. Остановка узла.

Алгоритм исключения узла только из одного канала:

  1. Исключить endpoint узла из конфигурации канала.
  2. Исключить все его сертификаты из конфигурации канала.
  3. Последствия второго шага:
    • Оставшиеся ордеринг-узлы канала прекращают общение с исключенным узлом в контексте канала. Эти же узлы могут продолжить общение с данным узлом в других каналах.
    • Исключенный узел самостоятельно обнаружит исключение сразу же или по истечению EvictionSuspicion (10 минут по умолчанию) и остановит Raft instance.

Обновление TLS-сертификата узла

Все TLS-сертификаты имеют срок годности (expiration date), определенный издателем сертификата (issuer). Срок может варьироваться от нескольких месяцев до нескольких лет, так что проверьте как обстоят дела с вашим издателем. До истечения срока годности вам необходимо обновить сертификат на самом узле и на каждом канале узла.

Для каждого канала обновите конфигурацию канала с новыми сертификатами. Обновите сертификаты в файловой системе узла. Перезагрузите узел.

Так как узел может иметь только одну пару сертификат+приватный ключ, узел не сможет обслуживать каналы, если его новый сертификат не был добавлен, поэтому обновление сертификата должно проходить как можно быстрее.

Если по какой-то причине обновление сертификата не может быть выполнено в каких-то каналах, рекомендуется откатиться до старого сертификата и попытаться обновить позже.

Метрики

Что такое мониторинг-служба и как ее установить.

Справочник по метрикам.

Какие метрики вы хотите мониторить зависит от случая и конфигурации, но эти две вас, скорее всего, всегда будут важны:

  • consensus_etcdraft_is_leader: определяет лидера кластера. Если никакой узел не лидер, то вы потеряли консенсус.
  • consensus_etcdraft_data_persist_duration: определяет длительность операций по записи в persistent write ahead log кластера Raft. Для безопасности протокола, сообщения должны сохранятся для использования их fsync, до того, как сообщения будут распространены остальным узлам. Если эта величина начинает возрастать, узел, возможно, не может принять участие в консенсусе (что может привести к неработоспособности узла и, возможно, сети).

Устранение неполадок

  • Если узлы работают под большой нагрузкой, вы можете захотеть изменить несколько параметров. Большная нагрузка может привести к снижению производительности. Как уже было замечено в идейной части документации, Raft начинает выборы лидера, когда подписчик не получает heartbeat- или append-сообщения с данными реестра на протяжении какого-то времени. Если узел участвует в большом количестве каналов, вы можете увеличить период ожидания сообщений, чтобы предотвратить случайные выборы.