Контроллеры в Kubernetes: ReplicationController
ReplicationController гарантирует, что указанное количество реплик Pod'ов выполняется в любой момент времени. Другими словами, ReplicationController обеспечивает постоянную доступность Pod'а или однородного набора Pod'ов. Сразу стоит отметить, что на данный момент рекомендуемым способом настройки репликации является использование контроллера Deployment, который в свою очередь настраивает ReplicaSet контроллер.
Как работает ReplicationController
Если Pod'ов слишком много, ReplicationController завершает работу дополнительных Pod'ов. Если их слишком мало, ReplicationController запускает больше Pod'ов. В отличие от созданных вручную Pod'ов, Pod'ы, поддерживаемые ReplicationController, автоматически заменяются в случае сбоя (fail), удаления (deleted) или заверешения (terminated). Например, ваши Pod'ы воссоздаются на узле после прерывистого обслуживания, такого как обновление ядра. По этой причине вам следует использовать ReplicationController, даже если вашему приложению требуется только один Pod. ReplicationController похож на супервизор процессов, но вместо того, чтобы контролировать отдельные процессы на одном узле, ReplicationController контролирует несколько Pod'ов на нескольких узлах.
ReplicationController часто сокращается до "rc" или "rcs" в обсуждении и как сокращение в командах kubectl.
Простой случай - создать один объект ReplicationController для надежного запуска одного экземпляра Pod на неопределенный срок. Более сложный вариант использования - запуск нескольких идентичных копий реплицируемой службы, например веб-серверов.
Пример ReplicationController
В этом примере конфигурация ReplicationController запускает три копии веб-сервера nginx.
controllers/replication.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 3
selector:
app: nginx
template:
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
Запустите пример, загрузив файл примера и затем выполнив следующую команду:
kubectl apply -f https://k8s.io/examples/controllers/replication.yaml
replicationcontroller/nginx created
Проверьте состояние ReplicationController с помощью этой команды:
kubectl describe replicationcontrollers/nginx
Name: nginx
Namespace: default
Selector: app=nginx
Labels: app=nginx
Annotations:
Здесь создаются три Pod'а, но ни один из них еще не запущен, возможно, из-за того, что образ еще загружается. Чуть позже та же команда может показать:
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Чтобы перечислить все Pod'ы, которые принадлежат ReplicationController, в машиночитаемой форме, вы можете использовать команду, подобную этой:
pods=$(kubectl get pods --selector=app=nginx --output=jsonpath={.items..metadata.name})
echo $pods
nginx-3ntk0 nginx-4ok8v nginx-qrm3m
Здесь селектор такой же, как селектор для ReplicationController (видно из вывода описания kubectl), и в другой форме в replication.yaml. Опция --output=jsonpath указывает выражение, которое просто получает имя из каждого Pod'а в возвращаемом списке.
Написание спецификации ReplicationController
Как и во всех других конфигурациях Kubernetes, для ReplicationController нужны поля apiVersion, kind и metadata.
ReplicationController также нужен раздел .spec.
Pod Template (Pod шаблон)
.spec.template является единственным обязательным полем .spec.
.spec.template является шаблоном pod. У него точно такая же схема, что и у pod, за исключением того, что он вложенный и не имеет apiVersion или kind.
В дополнение к обязательным полям для Pod, шаблон pod в ReplicationController должен указывать соответствующие метки и соответствующую политику перезапуска. Для меток, убедитесь, что они не перекрываются с другими контроллерами.
Разрешается только .spec.template.spec.restartPolicy, равный Always, который используется по умолчанию, если не указан.
Перезапуски локальных контейнеров ReplicationController делегирует агенту на узле, например, Kubelet или Docker.
Метки на ReplicationController
ReplicationController может сам иметь метки (.metadata.labels). Обычно вы устанавливаете их так же, как .spec.template.metadata.labels; если .metadata.labels не указан, то по умолчанию используется .spec.template.metadata.labels. Однако им разрешено быть разными, и .metadata.labels не влияют на поведение ReplicationController.
Pod Selector
Поле .spec.selector является селектором меток. ReplicationController управляет всеми Pod'ами с метками, соответствующими селектору. Он не различает созданные и удаленные им Pod'ы, а также Pod'ы созданные или удаленные другим пользователем или процессом. Это позволяет заменить ReplicationController, не затрагивая работающие Pod'ы.
Если указан, .spec.template.metadata.labels должен быть равен .spec.selector, иначе он будет отклонен API. Если .spec.selector не указан, по умолчанию будет использоваться .spec.template.metadata.labels.
Также не следует обычно создавать какие-либо Pod'ы, чьи метки соответствуют этому селектору, либо напрямую, либо с другим ReplicationController, либо с другим контроллером, таким как Job. Если вы это сделаете, ReplicationController посчитает, что он создал другие Pod'ы. Kubernetes не останавливает вас от этого.
Если у вас есть несколько контроллеров с перекрывающимися селекторами, вам придется управлять удалением самостоятельно.
Несколько реплик
Вы можете указать, сколько Pod'ов должно работать одновременно, установив в .spec.replicas количество Pod'ов, которые вы хотите запустить одновременно. Число, запущенное в любое время, может быть больше или меньше, например, если replicas были только увеличены или уменьшены, или если Pod аккуратно отключен (gracefully shutdown), и замена начинается рано.
Если вы не укажете .spec.replicas, то по умолчанию это 1.
Работа с ReplicationControllers
Удаление ReplicationController и его модулей
Чтобы удалить ReplicationController и все его Pod'ы, используйте kubectl delete. Kubectl масштабирует ReplicationController до нуля и ждет, пока он удалит каждый Pod, прежде чем удалять сам ReplicationController. Если эта команда kubectl прервана, ее можно перезапустить.
При использовании REST API или клиентской библиотеки go вам необходимо выполнить шаги явно (масштабировать реплики до 0, дождаться удаления Pod'ов, затем удалить ReplicationController).
Удаление только ReplicationController
Вы можете удалить ReplicationController, не затрагивая ни одного из его Pod'ов.
Используя kubectl, укажите опцию --cascade=false для kubectl delete.
При использовании REST API или клиентской библиотеки go просто удалите объект ReplicationController.
После удаления оригинала вы можете создать новый ReplicationController для его замены. Если старый и новый .spec.selector одинаковы, то новый будет использовать старые Pod'ы. Тем не менее, он не приложит никаких усилий, чтобы существующие Pod'ы соответствовали новому, другому Pod шаблону. Чтобы обновить Pod'ы для новой спецификации контролируемым образом, используйте выкатываемое обновление (rolling update).
Изоляция Pod'ов от ReplicationController
Pod'ы можно удалить из целевого набора ReplicationController, изменив их метки. Этот метод может использоваться для удаления Pod'ов из службы для отладки, восстановления данных и т.д. Pod'ы, которые удалены таким образом, будут заменены автоматически (при условии, что количество реплик также не изменилось).
Общепринятые шаблоны использования ReplicationController
Перепланирование (Rescheduling)
Независимо от того, есть ли у вас 1 Pod или 1000, ReplicationController обеспечит наличие указанного количества Pod'ов, даже в случае сбоя узла или прекращения работы Pod'а (например, из-за действия другого управляющий агента).
Масштабирование (Scaling)
ReplicationController позволяет легко увеличивать или уменьшать количество реплик вручную или с помощью агента автоматического масштабирования, просто обновляя поле replicas.
Бесшовные обновления (Rolling updates)
ReplicationController предназначен для упрощения непрерывного обновления службы путем замены Pod'ов один за другим.
Рекомендуемый подход заключается в создании нового ReplicationController с 1 репликой, масштабировании нового (+1) и старого (-1) контроллеров по одному, а затем удалении старого контроллера после того, как он достигнет 0 реплик. Это предсказуемо обновляет набор Pod'ов независимо от непредвиденных сбоев.
В идеале, контроллер бесшовных обновлений должен учитывать готовность приложений и обеспечивать продуктивное обслуживание достаточного количества Pod'ов в любой момент времени.
Два ReplicationControllers должны были бы создавать Pod'ы с по крайней мере одной отличительной меткой, такой как тег образа основного контейнера Pod'а, так как обычно обновления образов инициируют непрерывные обновления (rolling updates).
Непрерывные обновления реализованы в клиентском инструменте kubectl rolling-update.
Множественные треки релизов
В дополнение к запуску нескольких релизов приложения во время непрерывного обновления (rolling update), часто можно запускать несколько релизов в течение длительного периода времени или даже непрерывно, используя несколько треков релизов. Треки будут различаться по меткам.
Например, сервис может быть нацелен на все Pod'ы с tier in (frontend), environment in (prod). Теперь предположим, что у вас есть 10 реплик Pod'ов, которые составляют этот уровень (tier). Но вы хотите иметь возможность сделать canary накат для новой версии этого компонента. Вы можете установить ReplicationController с replicas, установленными в 9 для основной части реплик, с метками tier=frontend, environment=prod, track=stable; и другим ReplicationController с replicas, установленными в 1 для canary наката, с метками tier=frontend, environment=prod, track=canary. Теперь сервис распространяется как на canary, так и не canary Pod'ы. Но вы можете связываться с ReplicationControllers отдельно, чтобы протестировать, контролировать результаты и т.д.
Использование ReplicationControllers с сервисами (службами)
Несколько контроллеров ReplicationController могут находиться за одним сервисом, так что, например, часть трафика уходит в старую версию, а часть - в новую.
ReplicationController никогда не завершится сам по себе, но не ожидается, что он будет таким же долговечным, как сервисы. Службы могут состоять из Pod'ов, управляемых несколькими ReplicationControllers, и ожидается, что многие ReplicationControllers могут быть созданы и уничтожены в течение срока жизни службы (например, для обновления Pod'ов, которые запускают службу). Сами службы и их клиенты не должны обращать внимания на контроллеры ReplicationController, которые поддерживают Pod'ы служб.
Написание программ для репликации
Pod'ы, созданные ReplicationController, должны быть взаимозаменяемыми и семантически идентичными, хотя их конфигурации могут стать неоднородными со временем. Это очевидно подходит для реплицированных серверов без сохранения состояния (stateless), но ReplicationControllers также можно использовать для поддержания доступности приложений, выбранных мастером, защищенных и рабочих пулов (worker-pool). Такие приложения должны использовать механизмы динамического назначения работы (work), такие как рабочие очереди RabbitMQ, в отличие от статической/однократной настройки конфигурации каждого Pod'а, что считается антишаблоном. Любая выполняемая настройка Pod'а, такая как вертикальное автоматическое изменение размера ресурсов (например, процессора или памяти), должна выполняться другим процессом онлайн-контроллера, в отличие от самого ReplicationController.
Обязанности ReplicationController
ReplicationController просто гарантирует, что желаемое количество Pod'ов соответствует его селектору меток и работает. В настоящее время только завершенные (terminated) Pod'ы исключаются из его числа. В будущем, готовность и другая информация, доступная из системы, могут быть приняты во внимание, может быть добавлено больше контроля над политикой замены, и планируется генерировать события, которые могут использоваться внешними клиентами для реализации произвольно сложной замены и/или политик масштабирования.
ReplicationController навсегда ограничен этой узкой обязанностью. Сам по себе он не будет выполнять пробы готовности и жизнеспособности. Вместо того, чтобы выполнять автоматическое масштабирование, он предназначен для управления внешним автоматическим масштабированием, которое изменило бы его поле replicas. В ReplicationController не будут добавлены политики планирования (например, распространения (spreading)). Он также не должен проверять, что управляемые Pod'ы соответствуют текущему указанному шаблону, так как это может затруднить автоматическое изменение размера и другие автоматизированные процессы. Точно так же сроки завершения, упорядочение зависимостей, расширение конфигурации и другие функции принадлежат чему либо еще, но не ReplicationController.
ReplicationController предназначен для составного примитива строительного блока. Высокоуровневые API и/или инструменты будут построены поверх него и других дополнительных примитивов для удобства пользователей в будущем. “macro” операции, которые в настоящее время поддерживаются kubectl (run, scale, roll-update), являются примерами этой концепции.
Альтернативы ReplicationController
ReplicaSet
ReplicaSet - это ReplicationController следующего поколения, который поддерживает новый селектор меток на основе наборов. В основном он используется контроллером Deployment в качестве механизма для организации создания, удаления и обновления Pod'ов. Обратите внимание, что рекомендуется использовать Deployment вместо прямого использования ReplicaSet, если только вам не требуется настраиваемая оркестровка обновлений или совсем не требуются обновления.
Deployment (рекомендуется)
Deployment (Развертывание) - это высокоуровневый объект API, который обновляет свои базовые ReplicaSet (наборы реплик) и их Pod'ы таким же образом, как и kubectl roll-update. Deployment рекомендуется, если вы хотите использовать функцию непрерывного обновления (rolling update), потому что в отличие от kubectl roll-update, они декларативные, на стороне сервера и имеют дополнительные функции.
Голые Pod'ы
В отличие от случая, когда пользователь создал Pod, ReplicationController заменяет Pod'ы, которые были удалены или прерваны по любой причине, например, в случае сбоя узла или прерывистого обслуживания узла, такого как обновление ядра. По этой причине рекомендуется использовать ReplicationController, даже если вашему приложению требуется только один Pod. Думайте об этом подобно руководителю процессов (process supervisor), только он контролирует несколько Pod'ов в нескольких узлах, а не отдельные процессы в одном узле. ReplicationController делегирует перезапуски локального контейнера некоторому агенту на узле (например, Kubelet или Docker).
Job
Используйте Job вместо ReplicationController для Pod'ов, которые должны завершаться самостоятельно (то есть пакетные задания).
DaemonSet
Используйте DaemonSet вместо ReplicationController для Pod'ов, которые предоставляют функцию уровня машины, такую как мониторинг машины или ведение журнала машины. Срок службы этих Pod'ов зависит от срока службы машины: Pod должен быть запущен на машине до запуска других Pod'ов, и его можно безопасно завершить, когда машина в противном случае будет готова к перезагрузке/выключению.
Читайте также:
Комментарии
Отправить комментарий