Kubernetes, Игровая Площадка, Микросервисы И Немного Волшебства

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

Как всегда он должен быть умным, шустрым и потреблять минимальное количество ресурсов.

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

kubernetes, игровая площадка, микросервисы и немного волшебства



Входящие условия и требования

Немного о том, что это за система, для которой нужно было создать игровую площадку:
  • Kubernetes, кластер без ОС;
  • Простой API-шлюз на базе nginx;
  • MongoDB как база данных;
  • Дженкинс в качестве CI-сервера;
  • Git на Bitbucket;
  • Два десятка микросервисов, которые могут общаться друг с другом (через API-шлюз), с базой данных и с пользователем.



kubernetes, игровая площадка, микросервисы и немного волшебства

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



Размышления по теме

С самого начала было ясно, что наиболее логичным способом создания параллельных пространств в k8s является использование нативного инструмента виртуальных кластеров или, в терминологии k8s, пространств имен.

Задача упрощается еще и тем, что все взаимодействия внутри кластера осуществляются с использованием коротких имен, предоставляемых kube-dns, а это означало, что структуру можно было запустить в отдельном пространстве имен без потери связности.

У этого решения есть только одна проблема — необходимость развертывания всех доступных сервисов в пространстве имен, что отнимает много времени, неудобно и потребляет большое количество ресурсов.



Пространство имен и DNS

При создании любого сервиса k8s создает DNS-запись вида .

.

svc.cluster.local .

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

В обычном состоянии это выглядит так:

  
  
   

search <namespace-name>.

svc.cluster.local svc.cluster.local cluster.local nameserver 192.168.0.2 options ndots:5

То есть к службе в том же пространстве имен можно обращаться по имени , в соседних пространствах имен по имени .



Мы обходим систему

В этот момент на ум приходит простая мысль: База общая, за маршрутизацию запросов к сервисам отвечает API-шлюз, почему бы не сделать так, чтобы он шел сначала к сервису в его неймспейсе, а если его там нет, то по умолчанию? " Да, такое решение можно было бы организовать с помощью настроек пространства имен (мы помним, что это nginx), но такое решение вызвало бы разницу в настройках на pg и на других кластерах, что неудобно и может вызвать ряд проблем.

Итак, был выбран метод замены строки

search <namespace-name>.

svc.cluster.local svc.cluster.local cluster.local

На

search <namespace-name>.

svc.cluster.local svc.cluster.local cluster.local default.svc.cluster.local

Такой подход обеспечит автоматический переход к пространству имен по умолчанию, если требуемый сервис недоступен в его пространстве имен.



kubernetes, игровая площадка, микросервисы и немного волшебства

Аналогичного результата можно добиться в кластере следующим образом.

Kubelet добавляет в контейнер параметры поиска из разрешения.

conf хост-машины, поэтому вам просто нужно добавить следующую строку в /etc/resolv.conf каждого узла:

search default.svc.cluster.local

Если вы не хотите, чтобы узлы разрешали адреса служб, вы можете использовать параметр --resolv-conf при запуске kubelet, который позволит вам указать любой другой файл вместо /etc/resolv.conf. Например, файл /etc/k8s/resolv.conf с той же строкой.



Вопрос технологии

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

  • Jenkins выполняет всю работу по развертыванию автоматически.

  • Для тестирования ветки функций доступны по адресу .

    cluster.local



настройки SSL-разгрузчика

Конфигурация Nginx для перенаправления запросов на api-gw в соответствующем пространстве имен

server_name ~^(?<namespace>.

+)\.

cluster\.

local; location / { resolver 192.168.0.2; proxy_pass http://api-gw.$namespace.svc.cluster.local ; }



Дженкинс

Плагин Jenkins используется для автоматизации процесса развертывания.

Плагин Pipeline Multibranch .

В настройках проекта указываем собирать только ветки, соответствующие шаблону play/* и добавляем Jenkinsfile в корень всех проектов, с которыми будет работать сборщик.

Для обработки используется заводной скрипт; Полностью приводить не буду, просто пара примеров.

В остальном развертывание принципиально ничем не отличается от обычного.

Получение имени ветки:

def BranchName() { def Name = "${env.BRANCH_NAME}" =~ "play[/]?(.

*)" Name ? Name[0][1] : null }

Минимальная конфигурация пространства имен требует развернутого шлюза API, поэтому мы добавляем в проект вызов, который создает пространство имен и развертывает в нем шлюз API:

def K8S_NAMESPACE = BranchName() build job: 'Create NS', parameters: [[$class: 'StringParameterValue', name: 'K8S_NAMESPACE', value: "${K8S_NAMESPACE}"]] build job: 'Create api-gw', parameters: [[$class: 'StringParameterValue', name: 'K8S_NAMESPACE', value: "${K8S_NAMESPACE}"]]



Заключение

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

Теги: #Kubernetes #DevOps #игровая площадка

Вместе с данным постом часто просматривают: