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 !

Внимание! Данные страницы описывают CBSD версии 13.0.x. Если вы используете более раннюю версию, рекомендуется сначала обновиться.

Кластеризация FreeBSD: VPC с CBSD

Вступление

Проект CBSD - это попытка объединить доступные в ОС FreeBSD самые различные технологии вокруг виртуализации и контейниризации для получения гибритной платформы для запуска изолированных окружений (проще говоря: создавайте свой self-hosted маленькие или не очень AWS, не прибегая к услугам Amazon ;-). Мы уже демонстрировали такие технологии FreeBSD как jail, гипервизоры XEN и bhyve. CBSD связывает их с такими компонентами, как RACCT, RCTL, возможностью использования сетевых файловых систем NFSv4/GlusterFS и P9, SR-IOV, CARP, PXE Boot, cloud-init support, etcupdate, vale(4) виртуальных свичей и так далее.

Проект развивает не только user-frendly UI в виде bsdconfig/dialog-based интерфейсов и командной строчки, но и WEB интерфейс и API. Все эти объемы работ в свою очередь помогают другим людям сэкономить время и быстро реализовать различные проекты, такие как BITBSD и BitCloud.sh: programmable VPS platform for blockchain. Начавшись как классические скрипты-обертки для создания примитивных действий над контейнерами, CBSD со временем получала все новые и новые слои абстракций и расширяла возможности.

В этой статье речь пойдет о следующем большом слое в CBSD, который объединяет в себе создание приватных сетей с использованием технологии vxlan для создания full-mesh сети между множественными физическими хостами в разных частях земного шара. Эта одна из больших задач в нашем амбициозном RoadMap под названием Stretched virtual L2 network (vxlan, qinq) for mutliple DataCenter. В свою очередь, этот шаг открывает двери для решения следующих больших задач как распределенный VALE-свич/MAC Learning (компоненты SDN), Shared-nothing clusters и реализации полноценной DRS/HA, влотную приближая пользователей к SDDC. Об этом мы расскажем позже, тем самым начиная цикл статей, посвященных кластеризации FreeBSD.

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

Реализация Virtual eXtensible Local Area Network (VXLAN) была добавлена в FreeBSD более 6 лет назад (на момент написания этой статьи) и доступна с версий 8.x-CURRENT. С помощью нее вы можете создавать большое количество ( 16 миллионов ) виртуальных Ethernet сегментов через UDP/IP транспорт или мультикаст. В режиме point-to-point, настройка и работа системы напоминает gif/gre туннели.

Build the VXLAN network

В нашем примере у нас есть три сервера с прямым доступом друг на друга через сеть интернет. Это количество - только ограничение автора статьи. Каждый сервер имеет только один внешний IP адрес. Наша задача - объеденить все три сервера в единый кластер, на котором мы сможем создавать изолированные виртуальные сети и окружения в них.

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

В первой реализации VPC (v12.1.10) CBSD может использовать только технологию виртуализации сети на базе VXLAN, однако в перспективе планируется расширение технологий. Пример vxlan мультикаст оставим для другой более подходящей статьи, в этой мы будет продемонстрирован более сложный вариант, поскольку в нашем случае ноды изначально находятся друг от друга в разных датацентрах и по сути, будут строить full mesh сеть, топологию сети, когда каждая нода имеет соединение со всеми одновременно.

Хосты в нашем примере и их адреса, это (IPv4 тоже годится):

  • jhoster1 ( IPv6: 2a05:3580:d800:20f7::1, SkyNET ISP )
  • gold-hoster-01 ( 2a01:4f8:241:500c::1, Hetzner DC )
  • gold-hoster-02 ( 2a01:4f8:241:500b::1, Hetzner DC )

Мы можете создавать именованные VPC ( Virtual Private/Personal Cloud/Container ) изолированные секции, каждое из которых будет иметь свою собственную независимую сеть, свою квоту на количество контейнеров или виртуальных машин или на количество дозволенных для потребления CPU ядер, оперативной памяти или дискового пространства в ней.

Cоздадим VPC с именем vpc1 и сетью рабочей 10.10.11.0/24 (вы можете использовать любую) в ней - эта сеть ваших виртуальных окружений. Для построения VXLAN туннелей, нам также понадобиться отдельная приватная сеть для установления peer-to-peer связей, virtual tunnel endpoint (VTEPs). CBSD может управлять инициализацией и назначением этих адреса автоматически. По мере добавления или удаления нод, туннели будут устанавливаться или сниматься динамически.

Создание кластера в CBSD начинается с добавления и обмена SSH ключами между всеми участниками. До инициализации мультинодового кластера, каждая нода видит только свои локальные окружения. Сбросим пароль пользователя cbsd - мы должны его знать для первоначальной инициализации кластера. После того как все ноды добавлены, пароль можно изменить или заблокировать - кластер не пострадает от этого, поскольку дальнейшие операции будут выполнятся на удаленных нодах с использованием сгенерированного SSH ED25519 ключа.

Выполним на каждой ноде команду cbsd node mode=add, добавляющую членов кластера:

jhoster1:

% cbsd node mode=add node=2a01:4f8:241:500c::1
% cbsd node mode=add node=2a01:4f8:241:500b::1

gold-hoster1:

% cbsd node mode=add node=2a05:3580:d800:20f7::1
% cbsd node mode=add node=2a01:4f8:241:500b::1

gold-hoster:

% cbsd node mode=add node=2a01:4f8:241:500c::1
% cbsd node mode=add node=2a05:3580:d800:20f7::1

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

Инициализацию VPC для всего кластера вы можете провести через команду vpc mode=deploy, однако, мы с вами выполним все составные операции последовательно на каждой ноде, чтобы вы имели представление что происходит. Исключением будет лишь команда mode=sync, которая массово синхронизирует настройки VPC на нодах

Создание VPC начинается с придумывания имени, например пусть он называется vpc1. Кроме имени, для инициализации нам необходимо указать peer сеть, а также определить участников VPC. Список нод можно указывать через запятую в аргументе node_member=. Если VPC дожна быть инициализирована на всех хостах CBSD кластера, вы можете использовать зарерервированное значение 'all' в качестве node_member. Сделаем это на всех трех нодах:

jhoster1:

% cbsd vpc mode=init node_member=all peer_network=10.100.0.0/24 vpc_name=vpc1

gold-hoster1:

% cbsd vpc mode=init node_member=all peer_network=10.100.0.0/24 vpc_name=vpc1

gold-hoster:

% cbsd vpc mode=init node_member=all peer_network=10.100.0.0/24 vpc_name=vpc1

Следующая команда mode=init_peers инициализирует конфигурацию и последовательно выбирает для каждой ноды-пира IP адрес для туннеля (VTEPs). Эту инициализацию необходимо выполнить только на одной ноде, после чего командой cbsd vpc mode=sync передать результат инициализации всему остальному кластеру:

jhoster1:

% cbsd vpc vpc_name=vpc1 mode=init_peers
% cbsd vpc vpc_name=vpc1 mode=sync

В выводе init_peers мы видим предварительную карту распределения IP адресов между участниками пиров. Именно эту карту мы должны увидеть через несколько мгновений в виде инициализированных vxlan интерфейсов по команде ifconfig.

Следующая команда применяет конфигурацию, создавая на той ноде, где она выполняется, создание и настройку vxlan интерфейсов:

jhoster1:

% cbsd vpc vpc_name=vpc1 mode=init_vxlan

gold-hoster1:

% cbsd vpc vpc_name=vpc1 mode=init_vxlan

gold-hoster:

% cbsd vpc vpc_name=vpc1 mode=init_vxlan

Запустим команду ifconfig и убедимся, что на каждом сервере мы имеем N-1 количество туннелей и удаленные хосты нам отвечают, выполнив команду ping:

В выводе мы можем заметить пониженный MTU на vxlan интерфейса - инкапсуляция добавляет 50 байт на каждый пакет. В поле description каждого интерфейса сохраняется информация, куда ведет этот туннель. И наконец, после инициализации vxlan мы сразу можем начать обмен трафиком с удаленной точкой

Последний кирпичик строительства нашей изолированной сети - это создание и объединение в нем VPC-бридж из получившихся vxlan-туннелей:

jhoster1:

% cbsd vpc vpc_name=vpc1 mode=init_bridge

gold-hoster1:

% cbsd vpc vpc_name=vpc1 mode=init_bridge

gold-hoster:

% cbsd vpc vpc_name=vpc1 mode=init_bridge

Обратите внимание, что если вы хотите использовать IP адрес на бридже для маршрутизации через него контейнеров и виртуальных машин, адрес может быть проинициализирова дополнительным параметром bridge_ips, например: cbsd vpc vpc_name=vpc1 mode=init_bridge bridge_ips=10.0.1.1/24

Это все! Теперь vpc1 с одинаковыми настройками существует и доступен для использования в качестве parent-интерфейса для vnet/VIMAGE-based контейнеров и виртуальных сетевых карт для виртуальных машин bhyve. Нам лишь осталось это проверить:

% cbsd jcreate jname=jail1 ip4_addr=0 interface=vpc1 vnet=1 runasap=1

или пользуясь cbsd bsdconfig-tui:

В меню нам понадобятся пункт для указывания имени контейнера, установка ip4_addr в значение 0, активация vnet (виртуализированный стек) и выбор vpc1 в качестве интерфейса для epair(4):

При старте контейнеров мы можем видеть инициализацию epair(4) интерфейсов и назначение их к нашему vpc1. С этого момента они изолированы в сетевом сегменте от любых других устройств и сетей.

В настоящее время, на трех физических серверах мы создали по одному контейнеру, вы можете использовать jwhereis и jls команды для локализации размещения контейнеров:

Проинициализируем внутри каждого контейнера IP адреса классическим способом через ifconfig. Поскольку контейнера объеденены в единую L2 сеть, мы вольны назначать им любую сеть в рамках L2. В примере мы используем 10.10.11.0/24 сеть. Убедимся, что все контейнера видят друг друга:

Инициализация на VPC на старте

Для того, чтобы интерфейсы vxlan/bridge и настройки инициализировались при перезагрузке хоста, вы можете воспользоваться генерацией FreeBSD rc.d скриптов, которые нужно активировать через /etc/rc.conf:

% cbsd vpc mode=init_rc vpc_name=vpc1

С этой командой, в /usr/local/etc/rc.d/ будет создан скрипт cbsd-vpc-vpc1, который будет поднимать всю конфнигурацию при запуске сервера.

заключение

Использование распределенной L2 сети между независимыми датацентрами и серверами, открывает новые возможности по созданию распределенных, масштабируемых и отказоустойчивых на уровне ДЦ и региона сервисов. Если один один регион по различным причинам выходит из строя, благодаря единой сети вы можете деплоить сервисы в любом другом месте, не беспокоясь о смене адресов, внутренней сети и смене ендпоинтов приложений. В виртуальной сети вы можете иметь не только vnet-based контейнера, но также и виртуальные машины с любыми ОС, которые поддерживает bhyve.

Смотрите эту ссылку на youtube, где демонстрируется VPC с jail и bhyve на практическом примере.