FreeBSD virtual environment management and repository

2020-10 upd: we reached the first fundraising goal and rented a server in Hetzner for development! Thank you for donating !

Деплой kubernetes кластера на FreeBSD/bhyve (CBSD)

Вступление

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

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

Существует достаточно много решений для оркестрации контейнерами, но наиболее популярный (или наиболее известный и разрекламированный, наверное - это кубернетис). Поскольку я планирую провести много эксперементов с инсталляциями и конфигурацией k8s, мне потребуется лаборатория, в которой я могу быстро и легким для себя образом разворачивать кластер в любых количествах. В своей работе и повседневной жизни, я очень плотно использую две ОС - Linux и FreeBSD. Кубер и докер - это Linux-центричные проекты и на первый вгляд, какого-то полезного участия и помощи от FreeBSD здесь ждать не приходится. Как говорится, из мухи можно сделать слона, но летать он уже не будет. Однако на ум приходят две соблазнительные вещи - это очень хорошая интеграция и работа в FreeBSD файловой системы ZFS, от которой было бы неплохо использовать механизм снапшотов, COW и надежности. Второе - гипервизор bhyve, поскольку нам все таки нужен загрузчик докеров и кубера в виде Linux ядра. Таким образом, нам необходимо различными способами связать воедино определенное количество действий, большинство из которых связано с запуском и предварительной конфигурацией виртуальных машин. Это характерно как для сервера на базе Linux, так и FreeBSD - что будет работать под капотом для запуска виртуальных машин - большой роли и разницы нет. Давайте возьмем FreeBSD!

В свободное время я являюсь участником CBSD, проекта, который одной части конечным пользователям может предоставлять более дружелюбный интерфейс по управлению контейнерами и виртуальными машинами на платформе FreeBSD. Вторая часть пользователей знает CBSD как фреймворк, который благодаря API очень легко встраивать в любые собственные сценарии по автоматическому управлению виртуальной инфраструктурой, отдав большинство низкоуровневых операций по работе с ВМ на совесть скриптов CBSD. Таким образом, наша задача сводится к построению некоторо моста между операциями над k8s кластером и задами, относящимся к деплою виртуальных машин. Работа заняла у меня около 4 часов и превратилась в рабочий k8s модуль CBSD, который доступен в паблике, как и все остальное, связанное с проектом CBSD.

Итак, посмотрим что получилось!

Спойлер: если вы предпочитаете смотреть видео, небольше демо на Ютубе: https://youtu.be/ADBuUCtOF1w

Что у нас есть

Я преследую цель поднять небольшую локальную лабораторию с рабочим k8s кластером и в моем распоряжении есть сервер со следующими характеристиками:

  • 1 жесткий диск объемом 3 Tb, на который и установлена FreeBSD 13-CURRENT ( ZFS-on-root )
  • RAM: 256 GB
  • CPU: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz (56 core)

Те, дефицита в ресурсах нет. Используя cloud-образ Ubuntu 18, я сгенерировал cloud-образ kubernetes, который отличается от Ubuntu образа лишь тем, что в нем было выполнено подключение репозитория kubernetes и выполнена команда apt install kubeadm, чтобы при разворачивании образа можно было сразу приступать к работе с утилитой kubectl.

Эксперементальный образ k8s я закачал на зеркала CBSD проекта. Запустить виртуальную машину из этого образа вы можете через стандартный диалог CBSD и команду bconstruct-tui:

Сначала нам необходимо выбрать тип гостя - в случае с k8s наш гость - это Linux:

Далее, выберем в списке готовых профилей Linux название, содержащее kubernetes - это cloud образ, поэтому ищите его внизу списка:

Редактируем остальные параметры, если настройки по-умолчанию вас не устраивают:

Мы можем изменить, например, сетевые настройки хелпера cloud-init:

После редактирования параметров, отправляем виртуальную машину создаваться:

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

Впрочем, это уже хорошо - благодаря cloud-init вам ненужно устанавливать каждый раз ОС используя инсталлятор, а также не требуется каждый раз после установки ОС выполнять установку kubernetes - вам только нужно запустить ВМ из gold-образа. Если вы любите в некоторых случаях выполнять ручную работу - 20 секунд запуска виртуальной машины в любой конфигурации - и можете приступать.

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

Эти операции вы можете запускать в строгой очередности одну за другим, либо можете скормить все необходимые аргументы за 1 раз - модуль сам разберет когда и что сделать. Например, давая команду:
cbsd k8s bootstrap=1 join=1 token=1 setup="master node"
мы просим модуль провестю весь цикл по инициализации одного кластера, с экспортом токена для работы с kubectl используя CLI через удаленный машину:

Модуль CBSD выполняет свою работу в различных местах - параллельно, в некоторых - последовательно.

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

Рано или поздно ( в моем случае - через 20 секунд ) модуль перешел от стадии bootstrap к стадии конфигурирования, когда одной ноде поручается роль master, все остальные - становятся worker. Цель k8s bootstrap - запустить из gold образа виртуальную машину с kubernetes - то, что выше мы сделали через cbsd bconstruct-tui, запустив одну виртуальную машину из диалогового интерфейса. Сейчас же, за 20 секунд мы запустили 10 виртуальных машин и их можно увидеть через стандартный вывод cbsd bls:

Надо сказать, что роль CBSD здесь - это не только запуск виртуальных машин и работа с cloud-init, но также автоматический поиск свободных имен для новых контейнеров (в данном случае используется маска kube в качестве начала имени контейнера) и поиск и автоматические назначение свободных IP адресов, которые система берет из настройки CBSD node ip pool. На скриншоте видно, что IP адреса 10.0.0.XX которые выданы виртуальным машинам, не всегда идут последовательно - некоторые из них уже заняты в сети.

Стадия конфигурирования master/worker самая долгая и проходит за 3 минуты:

После чего наступает стадия join, отнимающая 42 секунды нашей жизни. И наконец скрипт, экспортировав токен, завершается успехом:

Поскольку мы экспортировали (token=1) токен для работы с k8s на локальную машину, мы можем работать с кластером непосредственно с FreeBSD хоста. Мы можем сразу выполнить команду 'kubectl get nodes' и убедится, что все на месте.

Итак, кластер готов к работе. Для проверки работоспособности, вы можете применить семпл с официальной документации k8s и запустить в новом кластере ваш первый контейнер:

Для удаления есть аргумент destroy=1 ( либо удаляйте стандарной командой cbsd bremove ). Также, вы можете сбросить настройки кластера не уничтожая виртуальные машины ( reset=1 ). Энжой!

Небольшой подкаст с демо материалами этой статьи на Youtube: https://youtu.be/ADBuUCtOF1w


Выводы и дальнейшие планы

В условиях энергично развивающейся IT отрасли, крайне важно автоматизировать все возможные операции и получать результат ASAP - цените свое время и нервы и используйте эти ограниченные и самые ценные ресурсы на то, чтобы выполнять свои собственные задачи. В этой статье был продемонстрировано сотрудничество ряда технологий: FreeBSD. Linux, ZFS, cloud-init, bhyve, CBSD, которые призваны сделать одно - поднять готовый к использованию кластер kubernetes любой конфигурации настолько быстро, насколько это возможно.

Очевидно, что наиболее длительный шаг (configure/setup) здесь также можно оптимизировать, поскольку данный шаг выполняет различные действия, работающие с удаленными ресурсами (wget .yaml конфигураций для calico и т.д) - это можно также включить в cloud образ kubernetes в дальнейшем.

Также, из планов достаточно интересной кажется идея объединить на счет VXLAN несколько физических серверов с FreeBSD/CBSD, создав единый L2 сегмент для всех контейнеров. Использование p9fs, Ceph, NFS или S3 объектного хранилища здесь также имеет право на существование, для организации единого дискового пространства для контейнеров на разных физических нодах

. А также, при должной доработке, на базе FreeBSD и ZFS, мы можем получить отказоустойчивый масштабируемый кластер кубернетес в виде черного ящика - имеется ввиду не закрытость продукта, а самодостаточный и самостоятельный фреймворк, который не требует IT специалиста погружаться в технологии FreeBSD, bhyve и CBSD, а получает универсальный API для контроля и управления K8S кластерами.

Кому интересны FreeBSD/bhyve + kubernetes и есть желание запустить собственный SaaS K8S сервис на своих ресурсах с использованием CBSD - пишите идеи и комментарии. Было бы интересно предоставить публике легкий и дешевый способ для этих операций.