Что такое Kubernetes?

Введение

Кубернетес – мощная система с открытым исходным кодом, изначально разработанная Google и поддерживаемая Cloud Native Computing Foundation (CNCF), для управления контейнеризированными приложениями в кластерной среде. Он стремится предоставить лучшие способы управления связанными, распределенными компонентами и службами на различной инфраструктуре. Чтобы узнать больше о Kubernetes, изучите руководство ниже. Если вы ищете управляемый сервис хостинга Kubernetes, посмотрите наш простой, управляемый сервис Kubernetes, созданный для роста.

В этом руководстве мы обсудим, что такое Kubernetes, некоторые основные концепции Kubernetes. Мы поговорим об архитектуре системы, проблемах, которые она решает, и модели, которую она использует для управления контейнеризированными развертываниями и масштабированием.

Что такое Kubernetes?

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

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

Архитектура Kubernetes

Чтобы понять, как Kubernetes может предоставлять эти возможности, полезно понимать, как он спроектирован и организован на высоком уровне. Kubernetes можно представить как систему, построенную на слоях, при этом каждый более высокий слой абстрагирует сложность, присутствующую на более низких уровнях.

На своей основе Kubernetes объединяет отдельные физические или виртуальные машины в кластер, используя общую сеть для связи между каждым сервером, снова независимо от того, являются ли они физическими или виртуальными машинами. Этот кластер Kubernetes – это физическая платформа, на которой настраиваются все компоненты, возможности и рабочие нагрузки Kubernetes.

Машины в кластере Kubernetes каждая получает свою роль в экосистеме Kubernetes. Один сервер (или небольшая группа в высокодоступных развертываниях) действует в качестве мастер-сервера. Этот сервер выступает в роли шлюза и мозга кластера, предоставляя API Kubernetes для пользователей и клиентов, проверяя состояние здоровья других серверов, принимая решения о том, как лучше разбить и назначить работу (известную как “планирование”), и оркестрируя общение между другими компонентами (иногда называемыми оркестрацией контейнеров). Мастер-сервер действует как основная точка контакта с кластером и отвечает за большую часть централизованной логики, которую предоставляет Kubernetes.

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

Как упоминалось выше, сами приложения и службы запускаются на кластере в контейнерах. Основные компоненты гарантируют, что желаемое состояние приложений соответствует фактическому состоянию кластера. Пользователи взаимодействуют с кластером, общаясь с основным сервером API Kubernetes напрямую или с помощью клиентов и библиотек. Для запуска приложения или службы представляется декларативный план в формате JSON или YAML, определяющий, что нужно создать и как это должно управляться. Затем главный сервер анализирует план и определяет, как его запустить на инфраструктуре, исходя из требований и текущего состояния системы. Эта группа пользовательских приложений, работающих в соответствии с заданным планом, представляет собой окончательный уровень Kubernetes.

Компоненты главного сервера

Как описано выше, главный сервер действует как основное управляющее плоскость для кластеров Kubernetes. Он служит основной точкой контакта для администраторов и пользователей, а также предоставляет множество кластерных систем для относительно несложных рабочих узлов. В целом компоненты на главном сервере работают вместе для принятия запросов пользователей, определения лучших способов планирования контейнеров с рабочей нагрузкой, аутентификации клиентов и узлов, настройки кластерной сети и управления масштабированием и проверкой состояния.

Эти компоненты могут быть установлены на одной машине или распределены по нескольким серверам. В этом разделе мы рассмотрим каждый из отдельных компонентов, связанных с мастер-серверами кластеров Kubernetes.

etcd

Один из фундаментальных компонентов, необходимых Kubernetes для функционирования, – это глобально доступное хранилище конфигурации. Проект etcd, разработанный командой CoreOS (операционная система), является легковесным, распределенным хранилищем ключ-значение, которое можно настроить для работы на нескольких узлах.

Kubernetes использует etcd для хранения конфигурационных данных, к которым может обращаться каждый из узлов в кластере. Это может использоваться для обнаружения служб и может помочь компонентам настроить или перенастроить себя в соответствии с актуальной информацией. Это также помогает поддерживать состояние кластера с функциями, такими как выбор лидера и распределенная блокировка. Предоставляя простой HTTP/JSON API, интерфейс для установки или извлечения значений очень прост в использовании.

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

kube-apiserver

Один из самых важных служб мастера – это сервер API. Это основная точка управления всем кластером, поскольку позволяет пользователю настраивать нагрузки и организационные единицы Kubernetes. Он также отвечает за то, чтобы хранилище etcd и детали обслуживания развернутых контейнеров были согласованы. Он выступает в качестве моста между различными компонентами для поддержания здоровья кластера и распространения информации и команд.

Сервер API реализует интерфейс RESTful, что означает, что множество различных инструментов и библиотек могут легко общаться с ним. Для взаимодействия с кластером Kubernetes с локального компьютера доступен клиент под названием kubectl по умолчанию.

kube-controller-manager

Менеджер контроллера – это общая служба, которая имеет множество обязанностей. В первую очередь, он управляет различными контроллерами, которые регулируют состояние кластера, управляют жизненным циклом нагрузки и выполняют рутинные задачи. Например, контроллер репликации обеспечивает соответствие количества реплик (идентичных копий), определенных для pod, количеству, в настоящее время развернутых в кластере. Детали этих операций записываются в etcd, где менеджер контроллера отслеживает изменения через сервер API.

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

kube-scheduler

Процесс, который фактически назначает рабочие нагрузки на конкретные узлы в кластере, – это планировщик. Этот сервис считывает требования к работе, анализирует текущую среду инфраструктуры и размещает работу на подходящем узле или узлах.

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

cloud-controller-manager

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

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

Компоненты сервера узла

В Kubernetes серверы, которые выполняют работу путем запуска контейнеров, известны как узлы. Узлы сервера имеют несколько требований, которые необходимы для взаимодействия с основными компонентами, настройки сети контейнеров и выполнения фактических рабочих нагрузок, назначенных на них.

A Container Runtime

Первый компонент, который должен быть у каждого узла, – это среда выполнения контейнеров. Обычно это требование удовлетворяется установкой и запуском Docker, но также доступны альтернативы, такие как rkt и runc.

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

kubelet

Основной точкой контакта для каждого узла с группой кластеров является небольшая служба, называемая kubelet. Эта служба отвечает за передачу информации от и к службам управляющей плоскости, а также взаимодействие с хранилищем etcd для чтения конфигурационных данных или записи новых значений.

Служба kubelet взаимодействует с главными компонентами для аутентификации в кластере и получения команд и работы. Работа принимается в форме манифеста, который определяет нагрузку и операционные параметры. Процесс kubelet затем берет на себя ответственность за поддержание состояния работы на узле сервера. Он контролирует контейнерный рантайм для запуска или уничтожения контейнеров по мере необходимости.

kube-proxy

Чтобы управлять подсетями индивидуальных хостов и предоставлять услуги другим компонентам, на каждом узле сервера запускается небольшой прокси-сервис под названием kube-proxy. Этот процесс перенаправляет запросы к правильным контейнерам, может выполнять примитивное балансирование нагрузки и в целом отвечает за обеспечение предсказуемой и доступной сетевой среды, но с изоляцией в необходимых случаях.

Объекты и нагрузки Kubernetes

Хотя контейнеры являются базовым механизмом для развертывания контейнеризованных приложений, Kubernetes использует дополнительные уровни абстракции над интерфейсом контейнера для предоставления функций масштабирования, устойчивости и управления жизненным циклом. Вместо прямого управления контейнерами пользователи определяют и взаимодействуют с экземплярами, составленными из различных примитивов, предоставляемых моделью объектов Kubernetes. Ниже мы рассмотрим различные типы объектов, которые могут использоваться для определения этих рабочих нагрузок.

Поды

A pod is the most basic unit that Kubernetes deals with. Containers themselves are not assigned to hosts. Instead, one or more tightly coupled containers are encapsulated in an object called a pod.

A pod generally represents containers that should be controlled as a single application. Pods consist of containers that operate closely together, share a life cycle, and should always be scheduled on the same node. They are managed entirely as a unit and share their environment, volumes, and IP space. In spite of their containerized implementation, you should generally think of pods as a single, monolithic application to best conceptualize how the cluster will manage the pod’s resources and scheduling.

Обычно, поды состоят из основного контейнера, который удовлетворяет общему назначению нагрузки и, по желанию, из некоторых вспомогательных контейнеров, которые облегчают тесно связанные задачи. Это программы, которые выигрывают от того, что их запускают и управляют в их собственных контейнерах, но тесно связаны с основным приложением. Например, у пода может быть один контейнер, запускающий основной сервер приложений, и вспомогательный контейнер, загружающий файлы в общую файловую систему, когда изменения обнаруживаются во внешнем репозитории. Горизонтальное масштабирование обычно не рекомендуется на уровне пода, потому что существуют другие объекты более подходящие для этой задачи.

Обычно пользователи не должны управлять подами сами, потому что они не предоставляют некоторые из функций, обычно необходимых в приложениях (например, сложное управление жизненным циклом и масштабирование). Вместо этого пользователей призывают работать с более высокоуровневыми объектами, которые используют поды или шаблоны подов в качестве базовых компонентов, но реализуют дополнительную функциональность.

Контроллеры репликации и наборы репликации

Часто, при работе с Kubernetes, вместо работы с отдельными подами вы будете управлять группами идентичных, реплицированных подов. Они создаются из шаблонов подов и могут быть горизонтально масштабированы контроллерами, известными как контроллеры репликации и наборы репликации.

A replication controller is an object that defines a pod template and control parameters to scale identical replicas of a pod horizontally by increasing or decreasing the number of running copies. This is an easy way to distribute load and increase availability natively within Kubernetes. The replication controller knows how to create new pods as needed because a template that closely resembles a pod definition is embedded within the replication controller configuration.

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

Наборы репликации – это итерация дизайна контроллера репликации с большей гибкостью в том, как контроллер определяет поды, которыми он должен управлять. Наборы репликации начинают заменять контроллеры репликации из-за их более широких возможностей выбора реплики, однако они не могут выполнять пошаговые обновления для переключения бэкендов на новую версию, как это делают контроллеры репликации. Вместо этого наборы репликации предназначены для использования внутри дополнительных более высокоуровневых единиц, которые предоставляют эту функциональность.

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

Развертывания

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

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

Развертывания – это объект высокого уровня, предназначенный для упрощения управления жизненным циклом реплицированных подов. Развертывания могут быть легко изменены путем изменения конфигурации, и Kubernetes автоматически адаптирует наборы репликации, управляет переходами между различными версиями приложений и, по желанию, автоматически поддерживает историю событий и возможности отмены. Из-за этих особенностей развертывания, вероятно, будут типом объекта Kubernetes, с которым вы чаще всего работаете.

Наборы с состоянием

Stateful sets – это специализированные контроллеры pod, которые предоставляют гарантии упорядочивания и уникальности. Прежде всего, они используются для более тонкой настройки при наличии специальных требований, связанных с порядком развертывания, постоянными данными или стабильной сетевой работой. Например, наборы устойчивых состояний часто ассоциируются с приложениями, ориентированными на данные, такими как базы данных, которым необходим доступ к тем же томам даже в случае переназначения на новый узел.

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

При развертывании или изменении масштаба наборы устойчивых состояний выполняют операции в соответствии с числовым идентификатором в их имени. Это обеспечивает большую предсказуемость и контроль над порядком выполнения, что может быть полезно в некоторых случаях.

Наборы демонов

Наборы демонов – это еще одна специализированная форма контроллера pod, которая запускает копию pod на каждом узле кластера (или подмножестве, если указано). Это наиболее полезно при развертывании pod, которые помогают выполнить обслуживание и предоставить услуги для самих узлов Kubernetes.

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

Работы и Cron-работы

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

Работа с заданиями выполняется с помощью cron заданий. Подобно обычным демонам cron в Linux и Unix-подобных системах, которые выполняют сценарии по расписанию, cron задания в Kubernetes предоставляют интерфейс для запуска заданий с компонентом планирования. Cron задания могут использоваться для запланированного выполнения задания в будущем или на регулярной, периодической основе. Cron задания Kubernetes в основном представляют собой переосмысление классического поведения cron, используя кластер как платформу вместо одной операционной системы.

Другие компоненты Kubernetes

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

Сервисы Kubernetes

До сих пор мы использовали термин “сервис” в обычном смысле, аналогичном Unix: чтобы обозначить долгоживущие процессы, часто связанные с сетью, способные отвечать на запросы. Однако в Kubernetes сервис – это компонент, который действует как основной внутренний балансировщик нагрузки и посредник для подов. Сервис группирует логические коллекции подов, выполняющих одну и ту же функцию, чтобы представить их как единое целое.

Это позволяет развертывать сервис, который может отслеживать и направлять во все контейнеры бэкенда определенного типа. Внутренним потребителям нужно знать только о стабильной конечной точке, предоставляемой сервисом. Тем временем, абстракция сервиса позволяет масштабировать или заменять рабочие блоки бэкенда по мере необходимости. IP-адрес сервиса остается неизменным независимо от изменений в подах, к которым он направляется. Развертывая сервис, вы легко достигаете обнаружимости и можете упростить проектирование ваших контейнеров.

Всякий раз, когда вам нужно предоставить доступ к одному или нескольким подам другому приложению или внешним потребителям, следует настроить сервис. Например, если у вас есть набор подов, запущенных веб-серверы, которые должны быть доступны из Интернета, сервис обеспечит необходимую абстракцию. Аналогично, если ваши веб-серверы должны хранить и извлекать данные, вы захотите настроить внутренний сервис, чтобы предоставить им доступ к вашим подам базы данных.

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

В качестве альтернативы, тип сервиса LoadBalancer создает внешний балансировщик нагрузки для маршрутизации к сервису с использованием интеграции балансировщика нагрузки Kubernetes облачного провайдера. Менеджер облачного контроллера создаст соответствующий ресурс и настроит его, используя внутренние адреса сервиса.

Объемы и постоянные объемы

Надежное обмен данных и гарантия его доступности между перезапусками контейнеров является вызовом во многих контейнеризованных средах. Часто контейнерные рантаймы предоставляют какой-то механизм для присоединения хранилища к контейнеру, который сохраняется и после завершения жизни контейнера, но реализации обычно лишены гибкости.

Для решения этой проблемы Kubernetes использует свою собственную абстракцию объемов, которая позволяет данным быть общими для всех контейнеров внутри пода и оставаться доступными до завершения пода. Это означает, что тесно связанные поды могут легко обмениваться файлами без сложных внешних механизмов. Сбои контейнеров внутри пода не повлияют на доступ к общим файлам. После завершения пода общий объем уничтожается, поэтому это не является хорошим решением для по-настоящему постоянных данных.

Постоянные объемы – это механизм для абстрагирования более надежного хранилища, которое не привязано к жизненному циклу пода. Вместо этого они позволяют администраторам настраивать ресурсы хранения для кластера, которые пользователи могут запрашивать и запрашивать для подов, которые они запускают. После того как под завершает работу с постоянным объемом, политика его восстановления определяет, сохраняется ли объем до его ручного удаления или удаляется вместе с данными немедленно. Постоянные данные могут использоваться для защиты от сбоев на уровне узла и для выделения больших объемов хранилища, чем доступно локально.

Метки и аннотации

A Kubernetes organizational abstraction related to, but outside of the other concepts, is labeling. A label in Kubernetes is a semantic tag that can be attached to Kubernetes objects to mark them as a part of a group. These can then be selected for when targeting different instances for management or routing. For instance, each of the controller-based objects use labels to identify the pods that they should operate on. Services use labels to understand the backend pods they should route requests to.

Метки представлены в виде простых пар ключ-значение. Каждая единица может иметь более одной метки, но каждая единица может иметь только одну запись для каждого ключа. Обычно ключ “имя” используется в качестве общего идентификатора, но вы также можете классифицировать объекты по другим критериям, таким как стадия разработки, общедоступность, версия приложения и т.д.

Аннотации – это аналогичный механизм, который позволяет прикреплять произвольную информацию ключ-значение к объекту. В то время как метки следует использовать для семантической информации, полезной для соответствия пода критериям выбора, аннотации являются более свободными и могут содержать менее структурированные данные. В общем, аннотации представляют собой способ добавления обширных метаданных к объекту, которые не являются полезными для целей выбора.

Заключение

Kubernetes – это захватывающий проект, который позволяет пользователям запускать масштабируемые, высокодоступные контейнеризованные рабочие нагрузки на высокоабстрагированной платформе. Хотя архитектура Kubernetes и набор внутренних компонентов могут на первый взгляд показаться сложными, их мощь, гибкость и надежный набор функций без преувеличения непревзойдены в мире открытого программного обеспечения и для разработки облачных приложений. Понимая, как базовые строительные блоки сочетаются воедино, вы можете начать проектировать системы, которые полностью используют возможности платформы для запуска и управления вашими рабочими нагрузками в масштабе, создавая потрясающие облачные приложения.

Source:
https://www.digitalocean.com/community/tutorials/an-introduction-to-kubernetes