company_banner

Представляем Kubernetes CCM (Cloud Controller Manager) для Яндекс.Облака



    В продолжение к недавнему релизу CSI-драйвера для Яндекс.Облака мы публикуем ещё один Open Source-проект для этого облака — Cloud Controller Manager. CCM необходим не только для кластера в целом, но и собственно CSI-драйвера. Подробности о его предназначении и некоторые особенности реализации — под катом.

    Введение


    Зачем это?


    Мотивы, побудившие нас к разработке CCM для Яндекс.Облака, полностью совпадают с уже описанными в анонсе CSI-драйвера. Мы обслуживаем множество Kubernetes-кластеров у разных облачных провайдеров, для чего используем единый инструмент. Он реализует многочисленные удобства «в обход» managed-решений этих провайдеров. Да, у нас довольно специфичный случай и потребности, однако созданные из-за них наработки могут пригодиться и другим пользователям.

    Что вообще такое CCM?


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

    В частности, Cloud Controller Manager обеспечивает пять основных типов взаимодействия:

    1. Instances – реализует связь 1:1 между объектом узла в Kubernetes (Node) и виртуальной машиной в облачном провайдере. Для этого мы:
      • заполняем поле spec.providerID в объекте Node. К примеру, для OpenStack CCM это поле имеет следующий формат: openstack:///d58a78bf-21b0-4682-9dc6-2132406d2bb0. Можно видеть имя облачного провайдера и уникальный UUID server’а (виртуальная машина в OpenStack) объекта;
      • дополняем nodeInfo в объекте Node информацией о виртуальной машине. Например, указываем instance type в AWS;
      • проверяем наличие виртуальной машины в облаке. К примеру, если объект Node перешёл в состояние NotReady, можно проверить, существует ли вообще виртуальная машина в облачном провайдере по providerID. Если её нет — удаляем объект Node, который в противном случае остался бы в кластере навечно;
    2. Zones – задаёт failure domain для объекта Node, чтобы планировщик мог выбрать узел для Pod’а согласно регионам и зонам в облачном провайдере;
    3. LoadBalancer – при создании объекта Service с типом LoadBalancer создаёт некий балансировщик, который направит трафик извне к узлам кластера. Например, в Yandex.Cloud можно использовать NetworkLoadBalancer и TargetGroup для этих целей;
    4. Route – строит сеть между узлами, т.к. по требованиям Kubernetes каждый pod должен иметь свой IP-адрес и иметь возможность достучаться до любого другого pod’а. Для этих целей можно использовать оверлейную сеть (VXLAN, GENEVE) или задать таблицу маршрутизации прямо в виртуальной сети облачного провайдера:

    5. Volume – позволяет динамически заказывать PV, используя PVC и SC. Изначально этот функционал являлся частью CCM, но ввиду большой сложности был вынесен в отдельный проект Container Storage Interface (CSI). Про CSI мы не раз писали и, как уже говорилось, даже выпустили CSI-драйвер.

    Ранее весь код, взаимодействующий с облаком, лежал в основном Git-репозитории проекта Kubernetes по адресу k8s.io/kubernetes/pkg/cloudprovider/providers, но от этого решили отказаться из-за неудобства работы с большой кодовой базой. Все старые реализации были вынесены в отдельный репозиторий. Для удобства дальнейшей поддержки и разработки все общие компоненты тоже были вынесены в отдельный репозиторий.

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

    Чтобы написать свою реализацию CCM, достаточно реализовать нужные Go-интерфейсы.

    И вот что у нас получилось.

    Реализация


    Как пришли к этому


    Разработку (а точнее — даже использование) мы начали с готового(!) CCM для Yandex.Cloud годовой давности.

    Однако в этой реализации нам не хватало:

    • аутентификации через JWT IAM-токен;
    • поддержки Service controller’а.

    По согласованию с автором (dlisin) в Telegram, мы форкнули yandex-cloud-controller-manager и дописали недостающие функции.

    Основные возможности


    На текущий момент CCM поддерживает следующие интерфейсы:

    • Instances;
    • Zones;
    • LoadBalancer.

    В будущем, когда Yandex.Cloud начнёт работать с продвинутыми возможностями VPC, мы добавим и интерфейс Routes.

    LoadBalanacer как главный вызов


    Изначально мы пробовали, как у других реализаций CCM, создавать пару из LoadBalancer и TargetGroup для каждого Service с типом LoadBalancer. Однако у Yandex.Cloud обнаружилось одно интересное ограничение: нельзя использовать TargetGroups с пересекающимися Targets (пара SubnetIDIpAddress).



    Поэтому внутри созданного CCM запускается контроллер, который при изменении объектов Node собирает информацию обо всех интерфейсах на каждой виртуальной машине, группирует их по принадлежности к определённым NetworkID, создаёт по TargetGroup на NetworkID, а также следит за актуальностью. Впоследствии, при создании объекта Service с типом LoadBalanacer мы просто прикрепляем заранее созданную TargetGroup к новым NetworkLoadBalanacer'ам.

    Как начать пользоваться?


    CCM поддерживает Kubernetes версии 1.15 и выше. В кластере для его работы требуется, чтобы флаг --cloud-provider=external был установлен в значение true для kube-apiserver, kube-controller-manager, kube-scheduler и всех kubelet’ов.

    Все необходимые шаги по самой установке описаны в README. Инсталляция сводится к созданию объектов в Kubernetes из манифестов.

    Для использования CCM также понадобится:

    • указать в манифесте идентификатор каталога (folder-id) Яндекс.Облака;
    • сервисный аккаунт для взаимодействия с API Яндекс.Облака. В манифесте Secret необходимо передать авторизованные ключи от сервисного аккаунта. В документации описано, как создать сервисный аккаунт и получить ключи.

    Будем рады обратной связи и новым issues, если столкнетесь с какими-то проблемами!

    Итоги


    Реализованный CCM мы используем в пяти Kubernetes-кластерах на протяжении двух последних недель и планируем расширить их число до 20 в ближайший месяц. Использовать CCM для больших и критических инсталляций K8s в настоящий момент не рекомендуем.

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

    P.S.


    Читайте также в нашем блоге:

    Флант
    Специалисты по DevOps и Kubernetes

    Комментарии 2

      0
      Надеюсь следующим открытым проектом для Яндекс.Облака будет cluster autoscaller :)
        +2
        Спасибо, как раз интеграции с LoadBalancer и не хватало, открывал запрос в яндексе на реализацию ccm )
        cloud.yandex.ru/features/221

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

        Самое читаемое