Как Kubernetes управляет вашим кластером с помощью концепций системного программирования
Раскрытие информации: Manifold , торговая площадка для разработчиков, ранее спонсировала Hacker Noon. Используйте код HACKERNOON2018, чтобы получить скидку 10 долларов на любую услугу.
Kubernetes - безусловно, самый популярный оркестратор контейнеров. Во многом его успех объясняется его надежностью. Во всем софте есть ошибки. Kubernetes почему-то менее глючит, чем альтернативы, когда дело доходит до запуска ваших контейнеров.
Kubernetes в конечном итоге достигает желаемого количества запущенных контейнеров вовремя. Он неумолимо поддерживает это число. В документации Kubernetes это называется самовосстановлением Kubernetes. Такое поведение проистекает из основной философии разработки Kubernetes.
«Целеустремленное поведение контура управления очень стабильно. Это было доказано в Kubernetes, где у нас были ошибки, которые остались незамеченными, потому что цикл управления в основном стабилен и со временем исправится.
Если вы срабатываете по краю, вы рискуете скомпрометировать свое состояние и никогда не сможете его воссоздать. Если вы запускаете уровень, шаблон очень щадящий и оставляет место для компонентов, которые ведут себя не так, как они должны быть исправлены. Это то, что заставляет Kubernetes так хорошо работать ».
- Джо Беда, технический директор Heptio (цитируется в Cloud Native Infrastructure Джастином Гаррисоном и Крисом Нова)
Прерывания: запуск по фронту и уровню
Запуск по фронту и по уровню - это концепции, пришедшие из электроники и системного программирования. Они относятся к тому, как система должна реагировать на форму электрического сигнала (или цифровой логики) с течением времени. Должна ли система заботиться о том, когда сигнал меняется с низкого на высокий и с высокого на низкий, или она должна заботиться о том, если сигнал высокий?
Чтобы объяснить это по-другому, с учетом следующего простого добавления:
> let a = 3; > a += 4; < 7
В представлении операции с запуском по фронту мы увидим:
add 4 to a
Это произойдет один раз во время добавления.
В представлении операции с триггером уровня мы увидим:
a is 7
Мы будем наблюдать это постоянно с момента добавления до следующего события.
Запуск по границе и по уровню в распределенных системах
Говоря абстрактно, нет очевидной разницы между срабатыванием по фронту и по уровню. В реальном мире, даже на уровне системного программирования, нам приходится иметь дело с практическими ограничениями. Распространенным ограничением является частота дискретизации. Если система не производит выборку сигнала достаточно часто, она может пропустить триггер либо для перехода фронта, либо для кратковременного изменения уровня.
В большем масштабе целых компьютеров и больших сетей приходится иметь дело с большим количеством проблем. Сеть ненадежна. Люди неповоротливы. Белки неумолимы. В некотором смысле эти проблемы похожи на плохую или непостоянную частоту дискретизации. Они заслоняют наш взгляд на сигнал.
Нарушения меняют восприятие
Давайте посмотрим, как нарушение сигнала влияет на его наблюдение в системах с синхронизацией по фронту и уровню:
Идеальные условия
В идеальных условиях системы с синхронизацией по фронту и по уровню обеспечивают правильное отображение сигнала. Сразу после того, как сигнал переходит из включенного в выключенное состояние, они оба видят, что сигнал находится в выключенном состоянии.
Два сбоя
С двумя нарушениями, размещенными вокруг первых двух изменений состояния сигнала, различия между системами, запускаемыми по фронту и по уровню, очевидны. Вид сигнала, запускаемый по фронту, пропускает первое повышение. Система, запускаемая по уровню, предполагает, что сигнал находится в последнем наблюдаемом состоянии, пока не увидит иное. Это приводит к наблюдаемому сигналу, который в основном является правильным, но с задержкой до момента нарушения.
Одно нарушение
Меньшее количество сбоев не всегда приводит к лучшему результату. С единичным срывом, скрывающим падение от высокого к низкому, система, запускаемая уровнем, в основном снова верна. Система с синхронизацией по фронту видит только два подъема, что приводит к состоянию, в котором исходный сигнал никогда не находился.
Чтобы выразить это еще раз с добавлением, сигнал выражался:
> let a = 1; > a += 1; > a -= 1; > a += 1; < 2
Но по системе с торцевым срабатыванием наблюдаются:
> let a = 1; > a += 1; > a += 1; < 3
Согласование желаемого и фактического состояний
Kubernetes отслеживает не просто один сигнал, а два: желаемое состояние кластера и фактическое состояние. Желаемое состояние - это состояние, в котором люди, использующие кластер, хотят, чтобы он находился («Запустить два экземпляра контейнера моего приложения»). Фактическое состояние идеально соответствует желаемому, но оно подвержено любому количеству аппаратных сбоев и злонамеренных грызунов. Они могут увести его из желаемого состояния. Важным фактором является даже время, поскольку невозможно мгновенно привести фактическое состояние в соответствие с желаемым. Образы контейнеров должны загружаться из реестра, приложениям требуется время для корректного завершения работы и т. Д.
Kubernetes должен принять фактическое состояние и согласовать его с желаемым состоянием. Он делает это непрерывно, принимая оба состояния, определяя различия между ними и применяя любые изменения, которые необходимо внести, чтобы привести фактическое состояние к желаемому состоянию.
Масштабирование развертывания в Kubernetes
Даже без сбоев в сети система с запуском по фронту, пытающаяся согласовать два состояния, может закончиться неверным результатом.
Если мы начнем с одной реплики контейнера и хотим масштабироваться до 5 реплик, а затем до двух реплик, система с запуском по границе увидит следующее для желаемого состояния:
> let replicas = 1; > replicas += 4; > replicas -= 3;
Фактическое состояние системы не может мгновенно реагировать на эти команды. Как показано на диаграмме, он может завершить работу трех реплик, если их всего три. Это оставляет нам 0 реплик вместо 2 желаемых.
В системе с триггером уровней мы всегда полностью сравниваем желаемое и фактическое состояния. Это снижает вероятность десинхронизации состояния (ошибка).
Выравнивание
Запуск по фронту не является плохим по своей сути; у него есть преимущества перед запуском по уровню. Запуск по фронту передает только то, что изменилось, когда оно изменилось.
Проблемы, связанные с сбоями в работе систем, запускаемых фронтом, могут быть уменьшены. Это часто выполняется посредством периодической сверки с полным состоянием, например, как работает система с запуском уровня. Сбои также могут быть уменьшены за счет явного упорядочивания и управления версиями событий.
Для Kubernetes представление о проблеме как о системе с триггером уровня привело к созданию чистой, простой архитектуры, которая делает то, что хочет пользователь, несмотря на присущие распределенным вычислениям проблемы.
Особая благодарность Мэг Смит за диаграммы, включенные в эту статью.