-Поиск по дневнику

Поиск сообщений в rss_rss_hh_new

 -Подписка по e-mail

 

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 17.03.2011
Записей:
Комментариев:
Написано: 51


kubernetes, playground, микросервисы и немного магии

Среда, 20 Сентября 2017 г. 10:06 + в цитатник
demonight сегодня в 10:06 Администрирование

kubernetes, playground, микросервисы и немного магии

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



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


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


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


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


    С самого начала было ясно, что наиболее логичным для создания параллельных пространств в k8s логичнее всего использовать родной инструмент виртуальных кластеров, или в терминологии k8s — namespaces. Задачу, так же, упрощает тот факт, что все взаимодействия внутри кластера производятся по коротким именам предоставляемым kube-dns, что означало, что запуск структуры можно произвести в отдельном namespace без потери связности.
    У данного решения есть только одна проблема — необходимость разворачивать в namespace все имеющиеся сервисы, что долго, неудобно и потребляет большое количество ресурсов.

    Namespace и DNS


    При создании любого сервиса k8s создаёт DNS-запись вида ..svc.cluster.local. Данный механизм позволяет общение через короткие имена внутри одного namespace благодаря изменениям вносимым в resolv.conf каждого запускаемого контейнера.
    В обычном состоянии он выглядит вот так:
    search .svc.cluster.local svc.cluster.local cluster.local
    nameserver 192.168.0.2
    options ndots:5

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

    Обходим систему


    В этот момент в голову приходит простая мысль "База общая, маршрутизацией запросов к сервисам занимается api-шлюз, почему бы не заставить его ходить сначала к сервису в своём namespace, а в случае его отсутствия в default?"
    Да, подобное решение можно было организовать настройками namespace (мы же помним, что это nginx), но подобное решение вызовет разницу в настройках на pg и на прочих кластерах, что неудобно и может вызвать ряд проблем.
    Так что, был выбран метод замены строки
    search .svc.cluster.local svc.cluster.local cluster.local
    На
    search .svc.cluster.local svc.cluster.local cluster.local default.svc.cluster.local
    Такой подход обеспечит автоматический переход в namespace default при отсутствии необходимого сервиса в своём namespace.

    Подобного результата можно добиться в кластере следующим образом. Kubelet добавляет параметры search в контейнер из resolve.conf хост-машины, так что достаточно просто дописать в /etc/resolv.conf каждой ноды строку:
    search default.svc.cluster.local
    Если же вы не желаете, чтобы ноды ресолвили адреса сервисов, то можно использовать параметр --resolv-conf при запуске kubelet, что позволит указать любой другой файл вместо /etc/resolv.conf. Например файл /etc/k8s/resolv.conf с той же строкой.

    Дело техники


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

    Настройки ssl-offloader


    Конфиг nginx для перенаправления запросов к api-gw в соответствующих namespace
     server_name ~^(?.+)\.cluster\.local;
    location / {
      resolver 192.168.0.2;
      proxy_pass http://api-gw.$namespace.svc.cluster.local;
    }

    Jenkins


    Для автоматизации процесса развёртывания используется плагин Jenkins Pipeline Multibranch Plugin.
    В настройках проекта указываем собирать только ветки соответствующие шаблону play/* И добавляем Jenkinsfile в корень всех проектов, с которыми будет работать сборщик.
    Для обработки используется groovy-скрипт, целиком приводить его не буду, только пара примеров. Остальной деплой принципиально ничем не отличается от обычного.
    Получение имени ветки:
    def BranchName() {
        def Name = "${env.BRANCH_NAME}" =~ "play[/]?(.*)"
        Name ? Name[0][1] : null
    }

    Минимальная конфигурация namespace требует развёрнутого api-шлюза, поэтому добавляем вызов проекта создающего namespace и разворачивающего в него 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}"]]
    

    Заключение


    Серебряной пули не существует, но мне так и не удалось найти не только best practices, но и описаний того, как организованы песочницы у других, поэтому решил поделиться методом, который использовал при создании песочницы на базе k8s. Возможно это не идеальный способ, так что с радостью приму замечания или рассказы о том, как данная проблема решена у вас.
    Original source: habrahabr.ru (comments, light).

    https://habrahabr.ru/post/338158/

    Метки:  

     

    Добавить комментарий:
    Текст комментария: смайлики

    Проверка орфографии: (найти ошибки)

    Прикрепить картинку:

     Переводить URL в ссылку
     Подписаться на комментарии
     Подписать картинку