Переместите свои сервисы из файлов docker-compose в ресурсы Kubernetes и разверните их

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

С другой стороны, оркестраторы контейнеров, такие как Marathon, Nomad, Docker Swarm и Kubernetes, созданы для управления развертыванием контейнеров в производственных средах. Эти системы предназначены для обработки:

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

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

В этой статье будет поэтапно описан процесс миграции с Docker Compose на Kubernetes.

Файл Docker Compose

Суть ниже содержит определение трех служб (MySQL, серверная часть Rails и службы обратного прокси-сервера Nginx), которые можно развернуть, просто используя следующую команду:

$> docker-compose up -d

Мы воспользуемся приведенным выше файлом Compose и попытаемся перенести определенные службы в объекты Kubernetes и развернуть их в кластере Kubernetes.

Обзор Kubernetes

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

Kubernetes поддерживает широкий спектр функций, связанных с управлением жизненным циклом контейнера, а также поддерживается огромным сообществом, в которое входят как отдельные лица, так и крупные компании, такие как IBM, Google, Microsoft и Red Hat.

В отличие от Docker Compose, Kubernetes более гибкий и сложный (в то же время). Например, Kubernetes предоставляет несколько объектов, ресурсов и решений для обработки развертывания контейнера, тогда как Compose предлагает только определения сервисов (как показано в файле выше). Кроме того, у них разная терминология. Например, service означает совершенно разные вещи для этих инструментов.

Ресурсы Kubernetes

Как упоминалось выше, Kubernetes предоставляет широкий список ресурсов. Полный список этих ресурсов можно просмотреть, используя команду ниже:

$>  kubectl api-resources

В зависимости от стеков, которые необходимо развернуть, эти ресурсы могут быть использованы и созданы. Ниже приведен список основных ресурсов, которые необходимы в большинстве случаев, с кратким описанием каждого из них:

  • PersistenntVolume - выделенная часть хранилища в кластере (например, может быть локальной или удаленной на AWS).
  • PersistenntVolumeClaim - запрос на PersistentVolume пользователем или службой.
  • Pod - Kubernetes не поддерживает создание контейнеров напрямую, и основным исполняемым объектом в Kubernetes является Pod, который может содержать один или несколько контейнеров.
  • ReplicaSet - ресурс, который отвечает за поддержание стабильного состояния реплик данного приложения.
  • Deployment - управляет событиями цикла развертывания контейнера, такими как чередование обновлений, отмена изменений, приостановка и возобновление изменений.
  • Service - отвечает за обеспечение связи между развернутыми приложениями.
  • Ingress - Предоставляет внутренние сервисы внешнему миру.

Определение каждого из этих ресурсов состоит из четырех основных разделов, перечисленных ниже:

  • apiVersion - версии API ресурса.
  • Kind - Тип ресурса.
  • Метаданные - метаданные, которые должны быть прикреплены к ресурсу, например метки и имя.
  • Spec - Определите спецификацию и конфигурации определенного ресурса.

Развернуть MySQL

Чтобы иметь возможность развернуть приложение MySQL в Kubernetes, нам необходимо создать следующие ресурсы Kubernetes:

  • PersistentVolume: Поскольку службе MySQL необходимо сохранять данные на диске, мы должны использовать те же тома, которые использовались с Compose. В противном случае данные будут храниться в контейнере и будут потеряны после воссоздания контейнера. В файлах YAML ниже определены ресурсы hostPath и PersistentVolume с емкостью 1 Ги. Том данных будет создан на хост-машине. Хранить данные непосредственно на хостах не рекомендуется, особенно если модули настроены для планирования на разных узлах кластера. В таких случаях следует использовать другие плагины громкости.
  • PersistentVolumeClaim: Создание PersistentVolume недостаточно, чтобы иметь возможность его использовать. Также требуется запрос использования созданного тома, и этот запрос можно выполнить с помощью PersistentVolumeClaim. В приведенном ниже файле мы запрашиваем использование 500 МБ емкости PersistentVolume.
  • Deployment: ресурс Deployment позаботится о создании Replicaset приложений, а модули приложений будут управляться созданным объектом ReplicaSet. Определение ресурса Deployment должно содержать следующие разделы:
  1. Реплики: количество реплик, которые должны быть созданы из приложения.
  2. Селекторы: условия, используемые для выбора модулей, управляемых развертыванием. Как показано во фрагменте ниже, развертывание будет управлять всеми модулями с меткой app=mysqldb-pod.
  3. Шаблон: шаблон пакета, который будет использоваться для создания и управления пакетами. Как показано ниже, в шаблоне представлены этикетки для контейнеров, спецификации контейнеров, прикрепленные тома и многое другое.
  • Service: ресурс Service необходим для связи с модулями MySQL. Можно получить доступ к модулям напрямую по их IP-адресам, но в случае репликации проще иметь IP-адрес службы, который будет балансировать нагрузку между модулями службы. Спецификации сервисного ресурса должны включать следующие разделы:
  1. Тип: тип услуги. Kubernetes поддерживает несколько типов сервисов для управления внутренними и внешними коммуникациями. Служба MySQL не должна быть доступна внешним службам. Следовательно, мы будем использовать тип ClusterIP. Сервис будет доступен на уровне кластера, и к нему может получить доступ любой модуль в кластере.
  2. Селектор: условия выбора модулей, управляемых службами.
  3. Порты: отображение портов, определяющее порт на стороне службы и на стороне контейнера.

Разверните серверное приложение

Развертывание приложения Rails может быть выполнено так же, как и с приложением MySQL, за исключением того, что нам не нужны PersistentVolume ресурсы, поскольку оно не сохраняет никаких данных. Ниже приведены ресурсы, необходимые для развертывания приложения Rails:

  • Deployment: объект Deployment будет определять шаблон контейнера внутреннего приложения, а также передавать необходимые переменные среды для подключения приложений к базе данных MySQL. Обратите внимание, что мы использовали имя службы MySQL, определенное выше, для подключения внутреннего приложения к базе данных. Служба обнаружения служб в Kubernetes позаботится о переводе этого имени в IP-адрес службы.
  • Служба: можно открыть службу Rails непосредственно на хост-машинах (например, на порту 80) с помощью служб NodePort или Loadbalancer. Однако при таком подходе невозможно использовать другие службы на одном и том же порте, и при таком подходе будет сложно управлять множеством служб. В результате рекомендуется использовать ClusterIP для управления службами и Ingress контроллеры для управления внешней связью. Ниже приведен файл определения службы Rails:

Разверните Ingress Controller

Построение Ingress контроллера и предоставление внутренних сервисов внешнему миру включает следующие шаги:

  • Создайте внутреннюю службу по умолчанию: внутренняя служба по умолчанию будет использоваться контроллером Ingress в тех случаях, когда запрошенные URL-адреса не могут быть сопоставлены ни с одной из определенных служб. Внутренняя служба по умолчанию может быть любой службой, если она отвечает ошибкой 404 на корневом маршруте и 200 для конечной точки healthz.
  • Контроллер Ingress - это приложение, отвечающее за обработку входящих запросов и их проксирование в соответствующие службы. Как показано в приведенном ниже фрагменте, контроллер Ingress настроен на использование службы, определенной выше, в качестве внутренней службы по умолчанию:
  • Ingress служба: важно выставить Ingress контроллер на хост-машинах с помощью службы LoadBalancer (это также можно сделать с помощью NodePort). Приведенное ниже определение службы предоставляет контроллер Ingress как для порта 80, так и для порта 443:
  • Ingress правило: этот ресурс необходим для настройки Ingress контроллера с необходимой информацией для проксирования запросов к приложению Rails. Из определения Ingress ниже мы видим, что запросы с хостом rails.lvh.me будут перенаправлены в службы Rails на порт 8080:

Развертывание созданного выше ресурса в кластере Kubernetes можно выполнить с помощью одной из следующих команд:

$>  kubectl apply -f ${filename}
$>  kubectl create -f ${filename}

Заключение

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

Полную реализацию развертывания, представленного в этой статье, можно найти на GitHub.