Переключение на уровне данных
Workload Availability переключает нагрузку одним из двух способов. При переключении силами Opfield (backend failover) Opfield замечает пропажу узла и создаёт замену; для этого Opfield должен работать. При переключении на уровне данных (режим аренды) Docker-узлы, узлы Ingress и Relay нагрузки сами решают, кто её обслуживает, поэтому отказавший или отрезанный узел заменяется примерно за 45 секунд, даже когда Opfield остановлен, обновляется или недоступен.
Режим аренды входит в Business и Enterprise. Включать его не нужно: политика переходит в него, как только его поддерживают все участники и они стабильно проработали 2 минуты. Участники — это Docker-узлы, на которых может работать нагрузка (кандидаты), узлы Ingress её Routes и Relay, которые передают её трафик. Они должны объявлять возможность availability_lease_v2; её объявляют Docker-демон, nginx-демон и Relay из Opfield 2.11. Компоненты ранних кандидатов в выпуск 2.11, объявляющие availability_lease_v1, считаются устаревшими.
В сводке Availability нагрузки строка Lease mode показывает Lease, когда узлы переключают нагрузку сами, Legacy при переключении силами Opfield, а также Bootstrapping или Closing, пока политика меняет режим. Причину показывает подсказка при наведении на значок.
Как это работает
Заголовок раздела «Как это работает»Каждое обслуживающее размещение — это слот: в режиме Failover он один, в режиме Replicated — по одному на реплику. Для каждого слота узлы и Relay политики поддерживают аренду, и свою копию нагрузки запускает только узел, который её держит (держатель).
- Продление. Держатель продлевает аренду каждые несколько секунд с большинством голосующих участников политики. Если это не удаётся, он останавливает свою копию раньше, чем аренда может перейти к кому-то другому. Затем свободный слот занимает следующий кандидат и запускает свою копию — примерно через 45 секунд после сбоя.
- Резервные копии. Opfield заранее готовит до двух резервных размещений на других узлах-кандидатах: образ загружен, контейнер создан, но не запущен, поэтому при перехвате его остаётся только запустить.
- Трафик. Запросы получает только держатель каждого слота. Secure Link каждого размещения зарегистрирована на каждом Relay с поддержкой режима аренды; ссылки резервных копий остаются зарегистрированными, но закрытыми, пока их узел не станет держателем, поэтому сразу после перехвата новый держатель доступен через любой Relay. Держатель получает трафик, только когда нагрузка готова; см. Routes и привязки баз данных.
- Освобождение. Держатель, остановивший копию по локальной причине (истёк его таймер аренды, пропал сторожевой процесс, обнаружена заморозка, аренда закрыта), освобождает слот, как только остановка контейнера подтверждена. Поэтому следующий кандидат запускается через несколько секунд, а не ждёт истечения аренды.
- Один слот на узел. В режиме Replicated узел никогда не держит два слота одной политики. Вернувшийся узел сначала забирает свой прежний слот.
- Недоступные держатели. Когда хост держателя перестаёт отвечать, Relay разрывают его соединение примерно за 3,5 секунды, и узлы Ingress перестают отправлять ему запросы; см. Routes и привязки баз данных. В режиме Replicated с этого момента запросы обслуживают остальные реплики; сам слот переходит к следующему кандидату, когда к нему переходит аренда.
Зависший Docker Engine (dockerd) на держателе не останавливает трафик к работающей копии и не считается причиной её остановить. Если за это время аренда держателя истекает, копию останавливает сторожевой процесс аренды.
Сторожевой процесс аренды
Заголовок раздела «Сторожевой процесс аренды»На каждом Docker-узле, который может держать слот, работает сторожевой процесс аренды (lease watchdog) — небольшая служба gateway-lease-watchdog со своей линией релизов. Она останавливает контейнер в режиме аренды, как только срок его аренды прошёл, даже если Docker-демон или dockerd зависли. Её устанавливает установщик Docker-узла, на существующих узлах её ставит сам Docker-демон, если он работает от root, а затем она обновляется сама. Если демон не может её установить, политика показывает этот узел с причиной watchdog_missing: запустите на нём установщик узла ещё раз.
Сторожевой процесс, который несколько секунд (примерно до 8) отвечает с задержкой, никогда не останавливает нагрузку. Если его сигнала нет около 10 секунд, держатель останавливает свою копию и передаёт слот следующему кандидату. Если Docker-демон откатили на релиз без поддержки аренды, сторожевой процесс через 10 минут удаляет оставшиеся сроки и не останавливает контейнеры, которые запускает старый демон.
Голосующие участники и свидетель
Заголовок раздела «Голосующие участники и свидетель»У каждой политики свои голосующие участники: её узлы-кандидаты, по одному на физический хост, в порядке перехвата, плюс свидетели, чтобы число голосов было нечётным, не меньше 3 и не больше 7. Голосуют только узлы и Relay, которые объявляют availability_lease_v2 и сообщили свою идентичность аренды. Политике с тремя кандидатами свидетель не нужен.
Свидетель — это Relay или Docker-узел на хосте, отличном от хостов всех кандидатов. Он выбирается в поле Witness политики: Auto (farthest by latency) выбирает подходящего участника, у которого наименьшее время приёма-передачи до кандидатов самое большое, то есть с наименьшей вероятностью оказаться с ними на одной площадке; можно также выбрать конкретный Relay или узел. Автоматический свидетель никогда не выбирается из локального Relay Opfield, пока свидетелем может быть другой Relay или узел, потому что локальный Relay останавливается вместе с Opfield. Он остаётся свидетелем, пока может голосовать, поэтому колебания задержки никогда не меняют состав голосующих. Сводка предупреждает, если свидетель, вероятно, находится на одной площадке с кандидатом (меньше 2 мс), если подходящего свидетеля нет или если заданный свидетель не может голосовать и вместо него используется автоматический.
Голосующие должны связываться друг с другом без Opfield. Каждый узел политики в режиме аренды подключается к каждому Relay для трафика аренды, и одного работающего Relay достаточно, пока через него большинство голосующих доступно друг другу. Сводка предупреждает Voter reachability margin is insufficient, если потеря ещё одного голосующего оставит политику без большинства; локальный Relay Opfield в этот запас не входит. У политики с двумя кандидатами и Relay на другом хосте запас — один голос.
Разделение сети
Заголовок раздела «Разделение сети»Allow available mode (partitionMode в API) определяет, что происходит, когда сеть разделяет голосующих:
- Выключено (
strict, по умолчанию). Две копии слота никогда не работают одновременно. Обслуживает только сторона с большинством голосующих; держатель на другой стороне останавливает свою копию. - Включено (
available). Обе стороны разделения продолжают обслуживать запросы, и недолго могут работать две копии. Никогда не включайте его для нагрузок, которые должны работать в единственном экземпляре: индексаторов, обработчиков очередей или заданий по расписанию.
Заморозка хостов и изменение часов
Заголовок раздела «Заморозка хостов и изменение часов»Таймеры аренды используют монотонные часы каждого хоста. Изменение системного времени, например коррекция NTP в любую сторону и на любую величину, никогда не останавливает копию.
Если хост или виртуальная машина держателя были приостановлены, заморожены или усыплены дольше примерно 2 секунд, его аренда за это время могла перейти к другому узлу. После возобновления узел определяет потерянное время по часам первого Relay или голосующего, от которого получает сообщение, и сразу останавливает копию — без отсрочки, если время его аренды уже истекло. Docker-демон записывает это в журнал как остановку с причиной host_frozen. Аренду, полученную узлом после заморозки, она никогда не прерывает, а более короткие паузы укладываются в обычные временные запасы. Держатель, которому после возобновления никто не отвечает, останавливает копию по своему таймеру аренды.
Исключённые узлы
Заголовок раздела «Исключённые узлы»Состояние одного узла никогда не меняет режим политики. Вместо этого узел попадает в список Excluded nodes сводки (lease.excludedNodes в API) с одной из причин:
| Причина | Подпись в сводке | Значение и исправление |
|---|---|---|
offline |
offline |
У узла нет управляющего соединения с Opfield. Восстановите хост или его демон. |
watchdog_missing |
lease watchdog not running |
Сторожевой процесс аренды не работает. Запустите gateway-lease-watchdog или повторно выполните установщик узла. |
daemon_outdated |
daemon outdated |
Docker-демон не объявляет availability_lease_v2. Обновите его. |
identity_pending |
no lease identity yet |
Демон ещё не сообщил свою идентичность аренды — обычно сразу после обновления. |
Исключённый узел не получает новых резервных копий, на него не выполняются возврат и другие плановые переносы, и его демон не занимает слот — это делает следующий кандидат. Opfield никогда не отрезает по этой причине узел, который держит слот: узел без сторожевого процесса сам останавливает свою копию, а устаревший держатель сохраняет слот, пока его не обновят или он не передаст слот. Устаревший или неопознанный узел выходит из голосующих и списка кандидатов, только если это состояние длится 2 минуты, поэтому перезапуск демона или поэтапное обновление ничего не меняют. Возврат на узел, который был исключён, ждёт Return to the primary after с момента окончания исключения.
Переход в режим аренды
Заголовок раздела «Переход в режим аренды»Политика, работающая с переключением силами Opfield, переходит в режим аренды, только когда все нужные ей участники 2 минуты без перерыва и без перезапуска работают с availability_lease_v2: каждый Docker-узел-кандидат со своим сторожевым процессом и идентичностью, узлы Ingress её Routes, Relay, которые её передают, и её свидетели. До этого её причина — participants_settling со списком ещё не устоявшихся узлов или Relay, поэтому парк в середине обновления никогда не переключается наполовину. После перезапуска Opfield эти 2 минуты отсчитываются заново.
Переход также ждёт завершения текущего включения или обновления политики. Первым держателем каждого слота становится узел, на котором нагрузка обслуживает запросы в этот момент, независимо от порядка приоритета; возврат по приоритету переносит её позже как плановую передачу. Если этот узел не готов занять слот, например потому что не нашёл копию нагрузки, его сторожевой процесс аренды не работает или политика перезапуска копии не no, его Docker-демон один раз для каждой причины записывает её в журнал.
Переход в режим аренды не прерывает нагрузку. Обслуживающие копии продолжают работать и сохраняют свои Secure Links: для слота учитывается только аренда, сформированная после переключения, поэтому старая аренда из прежнего периода режима аренды никогда не заставляет узел остановить собственную копию, а ссылки обслуживающих копий меняют роль на месте, без повторной регистрации.
Выход из режима аренды
Заголовок раздела «Выход из режима аренды»Политика выходит из режима аренды, только когда он стал невозможен:
| Причина | Когда возникает |
|---|---|
insufficient_voters |
Голосующих участников меньше, чем нужно для большинства; обновите кандидатов или добавьте Relay в качестве свидетеля |
ingress_not_capable |
Узел Ingress для Routes нагрузки работает с nginx-демоном без availability_lease_v2 |
relays_not_capable |
Relay, который передаёт нагрузку, работает с версией без availability_lease_v2 |
candidates_not_capable, watchdog_missing |
Ни один кандидат не может держать слот, и ни один слот не занят |
controller_unsupported |
Эта редакция Opfield переключает нагрузку Availability только силами Opfield |
signing_key_pending |
Ни один ключ подписи политики Relay пока не может подписывать данные аренды |
controller_unsupported означает сборку Community без контроллера аренды. Лицензия никогда не закрывает режим аренды: ни одно изменение состояния лицензии, включая истечение, не влияет на это решение.
Кроме отключения Availability и операций жизненного цикла вроде Stop, Start и Restart, которые выводят из режима аренды сразу, условие должно длиться 2 минуты без перерыва. Всё это время аренда продолжает работать, API показывает начало в lease.reason.since, а сводка предупреждает: Data-plane failover is impossible right now: … The policy goes back to backend failover at … unless this is fixed before; the serving copy keeps running.
Выход из режима аренды никогда не останавливает обслуживающую копию. Политика проходит этап Closing: Opfield публикует закрытую аренду, в которой для каждого слота назван узел, который его держит. Как только большинство голосующих подтвердит этому узлу закрытие, он продолжает запускать свою копию уже без аренды, сторожевой процесс больше её не контролирует, а переключение силами Opfield принимает её как работающую — обычно за несколько секунд; ничто её не перезапускает, и её Secure Links продолжают обслуживать запросы. В это время сводка показывает узел в строке Kept serving с пометкой confirming, а затем keeps running (lease.retainedHolders в API). Держатель, который во время закрытия не может достучаться до большинства, потому что отрезан, останавливает копию как любой держатель аренды, и Opfield снова запускает этот слот, когда его аренда истечёт — примерно через 47 секунд после того, как закрытие увидело большинство голосующих.
Закрытие сохраняет все размещения, включая исходную нагрузку: резервные копии остаются подготовленными, ничего не удаляется и не ставится в очередь на очистку. Если потом копию нужно запустить силами Opfield, сначала запускается подготовленная резервная копия, и только потом создаётся новое размещение. Нагрузку останавливает только Stop — после закрытия. Отключение Availability оставляет выбранное размещение работающим и само удаляет остальные размещения. Когда причина устранена, политика сама возвращается в режим аренды после обычных 2 минут стабилизации и принимает сохранённые резервные копии как есть.
Что по-прежнему делает Opfield
Заголовок раздела «Что по-прежнему делает Opfield»Opfield планирует все переносы и ведёт учёт; узлы только решают, кто обслуживает нагрузку при сбое.
- Операции разных политик идут параллельно. Каждая политика выполняет по одной операции за раз. Восстановление, масштабирование, обновление и похожие фоновые операции одновременно идут не более чем для 4 политик; возврат, запуск, остановка, перезапуск и отключение этого ограничения не ждут. Поэтому вернувшийся узел может вернуть себе несколько нагрузок, не стоя в очереди за восстановлением других политик.
- Плановые переносы — это передачи. Возврат, вывод, ручной перенос, изменение порядка приоритета или обновление переносят слот как передачу: обслуживающий узел останавливает копию и освобождает аренду, и только затем следующий узел запускает свою. Secure Links участников меняют роли на месте: ссылка старого держателя становится резервной, а нового — обслуживающей, поэтому при передаче не создаётся ни одной ссылки или адреса Relay. Слот ничего не обслуживает, пока старая копия останавливается, а новая запускается и становится готовой, обычно 5–15 секунд. В режиме Failover с выключенным Allow available mode запросы в это время завершаются ошибкой; в режиме Replicated запросы обслуживают остальные реплики.
- Восстановление. Политика, у которой меньше обслуживающих копий или резервных копий, чем нужно, и есть подходящая подключённая ёмкость, получает обслуживание каждые 15 секунд и при каждом подключении узла. Вернувшийся узел получает свой свободный слот обратно: его размещение сохраняется, а пропавшее создаётся заново. Узел, оказавшийся держателем двух слотов, передаёт один резервной копии на другом узле с короткой паузой для этой копии.
- Резервные копии остаются как есть. Повторная подготовка резервной копии, которую регулярно выполняют восстановление, переподключение или обслуживание, ничего не меняет, пока не изменились её настройки, образ (сравнивается по идентификатору образа) и параметры подключения к управляемой базе данных, которые она получит. Резервная копия, у которой изменились параметры подключения к базе данных, например после смены учётных данных привязки, считается неготовой и готовится заново. Docker-демон, занятый долгими командами, откладывает восстановление (
AVAILABILITY_DAEMON_BUSY, с повтором), а не переводит размещения в ошибку. - После разделения сети или сбоя. Когда узел возвращается, Opfield берёт состояние его размещений у его демона: остановленная копия становится готовой резервной, и возврат по приоритету выполняется так же, как после любого сбоя.
- Когда Opfield возвращается. Обслуживающая копия сохраняет путь Secure Link, пока Opfield заново подключает узлы: если обновить ссылку участника не удаётся, потому что узел ещё не подключился, ссылка сохраняет адрес Relay, и Opfield повторяет попытку. Relay, который переподключился, сразу получает все изменения политики.
- Учёт. Через несколько секунд после запуска Opfield узнаёт фактических держателей от своего локального Relay, ещё до переподключения узлов. Самостоятельный перехват появляется в журнале аудита как
docker.availability.lease_failover, плановый перенос — какdocker.availability.lease_handoff. Обе записи датируются временем, когда новый держатель получил слот; оно может быть раньше момента, когда Opfield его заметил. Слот, аренда которого истекла и который снова занял тот же узел, потому что его копия была остановлена или отрезана, в том числе пока Opfield был недоступен, появляется какdocker.availability.lease_reacquired. Перезапуск демона, копия которого сохранила аренду, не считается новым владением и ничего не меняет. Для времени выбирается лучший источник: собственное сообщение нового держателя, затем самое раннее время, когда его увидел голосующий, и только потом время, когда это заметил Opfield. Время, которое сообщает Docker-демон, исправляется на измеренное смещение его часов относительно часов Opfield, если оно больше 2 секунд, например у виртуальной машины, которая возобновила работу с отстающими часами; если часы измерить нельзя, решают время голосующих или момент, когда это заметил Opfield. Если собственное время держателя ещё неизвестно, например потому что он перехватил слот, пока Opfield был недоступен, запись появляется, когда время установлено: сразу после сообщения держателя, иначе через 60 секунд со временем голосующих или через 5 минут, если время не сообщил ни один участник. В подробностях записи естьtakeoverAt,noticedAt,takeoverSource(holder,votersилиnoticed) иtakeoverId. Ожидающая запись хранится в базе данных, поэтому перезапуск или сбой Opfield во время ожидания ничего не теряет и никогда не записывает её дважды. Время держателя в сводке (holderSinceв API) — то же время перехвата, и оно уточняется по мере поступления более точных сообщений.
Обновления и разные версии
Заголовок раздела «Обновления и разные версии»Сначала обновите Opfield, затем демоны узлов и Relay Pool; почему при обновлении с 2.10 демоны стоит обновлять первыми, см. обновления Relay. Политика с переключением силами Opfield остаётся в нём, пока хотя бы один участник работает на старом релизе, и переходит в режим аренды один раз — через 2 минуты после обновления последнего участника. Политика, уже работающая в режиме аренды, сохраняет его, пока устарели только Docker-узлы-кандидаты: они исключаются, а устаревший держатель продолжает обслуживать, пока его не обновят. Узел Ingress или Relay, оставшийся на старом релизе дольше 2 минут, переводит политику к переключению силами Opfield через Closing, при этом обслуживающие копии продолжают работать; после их обновления она возвращается сама.
Opfield сам упорядочивает обновления демонов участников аренды. Обновление Docker-демона или Relay, который голосует в политике в режиме аренды или может держать её слот, ждёт, пока остальные голосующие и кандидаты этой политики снова подключатся, сообщат своё состояние аренды и начнут голосовать. Всё это время узел показывается обновляющимся, а API сообщает updatePhase: waiting_for_lease_peers и список участников в updateWaitingFor. Обновления, запрошенные вместе, выполняются сначала для резервных копий, затем для держателей; узлы без общих политик обновляются параллельно. Участник, не стабилизировавшийся за 3 минуты после перезапуска, перестаёт блокировать, а обновление, прождавшее 30 минут, завершается ошибкой со списком участников.
Ожидание важно в основном один раз. Первый перезапуск узла, обновлённого с 2.10, воздерживается от голосования примерно 33 секунды — как и любой запуск после перезагрузки или с чистым состоянием, поэтому тогда обновление может ждать своих участников аренды около минуты на каждого из них. Следующие перезапуски в пределах той же загрузки продолжают голосовать сразу, а держатель, чей демон перезапускается, сохраняет слот и продолжает обслуживать: его аренда действует до срока сторожевого процесса, поэтому копия снова получает трафик, как только новый процесс демона зарегистрируется, и продлевает аренду до момента за 2 секунды до этого срока. См. Перезапуски Docker-демона.
После обновления до 2.11 резервная копия с привязкой к управляемой базе данных готовится ещё раз, потому что теперь резервные копии запоминают параметры подключения к базе, с которыми были подготовлены.
Узел, откаченный на любой релиз начиная с 2.10.0, по-прежнему запускается: демоны хранят файлы состояния в виде, который могут прочитать старые релизы.
Сведения об аренде в API
Заголовок раздела «Сведения об аренде в API»get в manage_docker_availability и API Availability возвращают объект lease:
mode:legacy,bootstrapping,leaseилиclosing;reason: почему политика работает с переключением силами Opfield или почему режим аренды сейчас невозможен — с полямиcode,message,nodeIdsилиrelayIdsдля исправления иsince, пока политика в режиме аренды выжидает 2 минуты;excludedNodes:[{ nodeId, reason }];retainedHoldersна этапеclosing:[{ slot, holderNodeId, confirmed }]— копии, которые продолжают работать во время закрытия;holders: для каждого слотаholderNodeId,placementIdиholderSince;votersиwitnessс полемwarning:witness_near_candidate,no_eligible_witnessилиconfigured_witness_unavailable;voterMargin:voters,reachable,requiredиmargin. Еслиmarginравен 0 или меньше, потеря ещё одного голосующего останавливает автономное переключение.
Ограничения
Заголовок раздела «Ограничения»- Переключение на уровне данных защищает размещения нагрузки, а не Opfield, nginx, движки баз данных, хранилище реестра или общие тома.
- Копия, которая не может продлить аренду, останавливается. Поэтому при выключенном Allow available mode разделение сети останавливает нагрузку на стороне без большинства.
- Плановые переносы дают короткую паузу для единственного экземпляра в режиме Failover, как описано выше.