Прим. перев.: Оригинальная статья была написана техническим писателем из Google, работающим над документацией для Kubernetes (Andrew Chen), и директором по software engineering из SAP (Dominik Tornow). Её цель — доступно и наглядно объяснить основы организации и реализации high availability в Kubernetes. Нам кажется, что у авторов получилось, поэтому мы рады поделиться переводом.
Kubernetes — движок оркестровки контейнеров, созданный для запуска контейнеризированных приложений на множестве узлов, которые обычно называют кластером. В этих публикациях мы используем подход системного моделирования с целью улучшить понимание Kubernetes и его нижележащих концепций. Читающим рекомендуется уже иметь базовое представление о Kubernetes.
Kubernetes — масштабируемый и надёжный движок оркестровки контейнеров. Масштабируемость здесь определяется отзывчивостью в присутствии нагрузки, а надёжность — отзывчивостью в присутствии отказов.
Заметьте, что масштабируемость и надёжность Kubernetes не означает масштабируемость и надёжность приложения, запущенного в нём. Kubernetes — масштабируемая и надёжная платформа, однако каждому приложению в K8s ещё только предстоит пройти определённые этапы для того, чтобы стать таковыми и избегать узких мест и единых точек отказа.
Например, если приложение развёрнуто как ReplicaSet или Deployment, Kubernetes (пере-)планирует и (пере-)запускает поды, затронутые падениями узла. Однако если приложение развёрнуто как поды, Kubernetes не предпримет никаких действий в случае отказа узла. Поэтому, хотя сам по себе Kubernetes остаётся функционирующим, отзывчивость вашего приложения зависит от выбранных решений по архитектуре и деплою.
В фокусе этой публикации — надёжность Kubernetes. Она рассказывает, как Kubernetes поддерживает отзывчивость в присутствии отказов.
Архитектура Kubernetes
Схема 1. Мастер и worker
На концептуальном уровне компоненты Kubernetes сгруппированы в два определённых класса: компоненты мастера (Master) и компоненты воркера (Worker).
Мастеры отвечают за управление всем кроме исполнения подов. Компоненты мастера включают в себя:
Воркеры отвечают за управление исполнением подов. У них один компонент:
Воркеры тривиально надёжны: временный или постоянный отказ любого воркера в кластере не затрагивает мастера или других воркеров кластера. Если приложение развёрнуто соответствующим образом, Kubernetes (пере-)планирует и (пере-)запускает любой под, затронутый отказом воркера.
Конфигурация с единственным мастером
Схема 2. Конфигурация с единственным мастером
В конфигурации с единственным мастером кластер Kubernetes состоит из одного мастера и множества воркеров. Последние напрямую подключаются к kube-apiserver мастера и взаимодействуют с ним.
В этой конфигурации отзывчивость Kubernetes зависит от:
- единственного мастера,
- подключения воркеров к единственному мастеру.
Поскольку единственный мастер — единая точка отказа, такая конфигурация не относится к категории высокой доступности.
Конфигурация с множеством мастеров
Схема 3. Конфигурация с множеством мастеров
В конфигурации с множеством мастеров кластер Kubernetes состоит из множества мастеров и множества воркеров. Воркеры подключаются к kube-apiserver любого мастера и взаимодействуют с ним через высокодоступный балансировщик нагрузки.
В этой конфигурации Kubernetes не зависит от:
- единственного мастера,
- подключения воркеров к единственному мастеру.
Поскольку единая точка отказа в такой конфигурации отсутствует, она считается высокодоступной.
Ведущий (leader) и ведомый (follower) в Kubernetes
В конфигурации с множеством мастеров задействованы многочисленные kube-controller-manager'ы и kube-scheduler'ы. Если два компонента будут модифицировать одни и те же объекты, могут возникнуть конфликты.
Дабы избежать потенциальных конфликтов, для kube-controller-manager и kube-scheduler в Kubernetes реализован паттерн «ведущий-ведомый» (leader/follower). Каждая группа выбирает одного ведущего (или лидера), и остальные члены группы берут роль ведомых. В любой момент времени активен лишь один ведущий, а ведомые пассивны.
Схема 4. Избыточный Deployment компонентов мастера в деталях
На этой иллюстрации показан подробный пример, в котором kube-controller-1 и kube-scheduler-2 являются ведущими среди kube-controller-manager'ов и kube-scheduler'ов. Поскольку каждая группа выбирает своего ведущего, они вовсе не обязательно должны находиться на одном и том же мастере.
Выбор ведущего
Новый ведущий выбирается членами группы в момент запуска или в случае падения ведущего. Ведущий — член, обладающий так называемым leader lease («арендованным» на данный момент статусом лидера).
Схема 5. Процесс выбора ведущего компонента мастера
Эта иллюстрация демонстрирует процесс выбора ведущего для kube-controller-manager и kube-scheduler. Логика этого процесса такова:
'Попытка получить статус лидера' успешна тогда и только тогда, когда:
- статусом лидера сейчас никто не обладает или
- время предыдущего лидера истекло
'Попытка обновить статус лидера' успешна тогда и только тогда, когда:
- leader lease существует и
- его время не истекло и
- его holderIdentity равен 'self'
Отслеживание ведущих
Текущие статусы лидеров для kube-controller-manager и kube-scheduler постоянно хранятся в объектном хранилище Kubernetes как endpoints objects в пространстве имён kube-system
. Поскольку два объекта Kubernetes не могут одновременно иметь одинаковое название, тип (kind) и пространство имён, может существовать лишь один endpoint для kube-scheduler и для kube-controller-manager.
Демонстрация с использованием консольной утилиты kubectl
:
$ kubectl get endpoints -n kube-system
NAME ENDPOINTS AGE
kube-scheduler <none> 30m
kube-controller-manager <none> 30m
Endpoint'ы kube-scheduler и kube-controller-manager хранят информацию о лидере в аннотации control-plane.alpha.kubernetes.io/leader
:
$ kubectl describe endpoints kube-scheduler -n kube-system
Name: kube-scheduler
Annotations: control-plane.alpha.kubernetes.io/leader=
{
"holderIdentity": "scheduler-2",
"leaseDurationSeconds": 15,
"acquireTime": "2018-01-01T08:00:00Z"
"renewTime": "2018-01-01T08:00:30Z"
}
Хотя Kubernetes гарантирует, что в один момент времени будет один ведущий, Kubernetes не гарантирует, что два и более компонентов мастера не будут ошибочно полагать, что являются ведущими в данный момент, — это состояние известно как split brain.
Поучительное обсуждение темы split brain и возможных способов её устранения можно найти в статье «How to do distributed locking» от Martin Kleppmann.
Kubernetes не применяет никакие контрмеры по защите от split brain. Вместо этого он полагается на свою возможность стремиться к желаемому состоянию в течение времени, что смягчает последствия конфликтных решений.
Заключение
В конфигурации с множеством мастеров Kubernetes — масштабируемый и надёжный движок оркестровки контейнеров. В этой конфигурации Kubernetes обеспечивает надёжность, используя множество мастеров и множество воркеров. Множество мастеров работает по паттерну ведущий/ведомый, а воркеры функционируют параллельно. В Kubernetes реализован свой процесс выбора ведущего, в котором информация о ведущем хранится как endpoints objects.
Информацию о том, как подготовить к работе кластер Kubernetes высокой доступности, можно получить в официальной документации.
О публикации
Этот пост — часть совместной инициативы CNCF, Google и SAP, направленной на улучшение понимания Kubernetes и его нижележащих концепций.
P.S. от переводчика
Читайте также в нашем блоге:
- «Понимаем Container Storage Interface (в Kubernetes и не только)»;
- «Понимаем RBAC в Kubernetes»;
- «Что происходит в Kubernetes при запуске kubectl run? Часть 1»;
- «Как на самом деле работает планировщик Kubernetes?»;
- «За кулисами сети в Kubernetes»;
- «Наш опыт с Kubernetes в небольших проектах» (видео доклада, включающего в себя знакомство с техническим устройством Kubernetes).
Автор: Андрей Сидоров