Pull to refresh
11.07

DIY: Ваше собственное облако на базе Kubernetes (часть 2)

Level of difficultyMedium
Reading time7 min
Views7.6K

Продолжаем серию постов про то как построить своё собственное облако в экосистеме Kubernetes. В прошлой статье мы разобрали как можно подготовить базовый дистрибутив Kubernetes на базе Talos Linux и Flux CD. Теперь нам предстоит обсудить возможность запуска виртуальных машин и всего что для этого необходимо, в первую очередь хранилище и сеть.

Мы поговорим про такие технологии как KubeVirt, LINSTOR и Kube-OVN

Но для начала нам стоит рассказать зачем вообще нужны виртуальные машины, почему бы нам не ограничиться только-лишь контейнерами?

Всё дело в том, что контейнеры в ядре Linux не дают должного уровня изоляции. Несмотря на то, что с каждым годом ситуация становится всё лучше, довольно часто мы сталкиваемся с уязвимостями, позволяющими покинуть песочницу контейнера и повысить свои привилегии в системе.

С другой стороны и сам Kubernetes изначально не разрабатывался для того чтобы быть мультитенантным, то есть основной паттерн использования всё-таки подразумевает что вы будете создавать отдельный Kubernetes-кластер на каждый независимый проект и команду разработки.

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

Технологии виртуализации в Kubernetes

Есть несколько различных технологий приносящих виртуализацию в мир Kubernetes: в первую очередь это KubeVirt и Kata Containers, но работают они по разному.

Когда Kata Containers имплементирует интерфейс CRI и с помощью гипервизора позволяет организовать дополнительный уровень изоляции для контейнеров запускаемых в едином кластере.

Упрощенная схема Kata-Containers
Упрощенная схема Kata-Containers

Основная миссия KubeVirt - это позволить запускать традиционные виртуальные машины используя  стандартный интерфейс Kubernetes. Виртуальные машины KubeVirt запускаются как обычные процессы прямо в контейнерах. Другими словами, контейнер в Kubernetes - используется всего-лишь как необходимая сущность для запуска процесса виртуальной машины. Это можно хорошо видеть посмотрев на то как реализована живая миграция виртуальных машин в KubeVirt. При необходимости миграции виртуальная машина просто “перетекает” из одного контейнера в другой:

Live-миграция виртуальной машины в KubeVirt
Live-миграция виртуальной машины в KubeVirt

Есть ещё и альтернативный проект - Virtink, который имплементирует легковесную виртуализацию используя Cloud-Hypervisor и изначально ориентирован на запуск виртуальных кластеров Kubernetes используя Cluster API.

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

KubeVirt легко устанавливается и практически сразу позволяет вам запускать виртуальные машины из containerDisk - это когда образ для ВМ хранится и распространяется прямо в докер-образе.

Виртуальные машины, запускаемые с containerDisk хорошо подходят для создания воркеров Kubernetes и других ВМ которым не нужно сохранение состояния.

Для расширения возможностей управления персистентными данными, KubeVirt предлагает отдельный инструмент Containerized Data Importer (CDI). Он, в свою очередь, позволяет клонировать PVC и заполнять их данными из базовых образов. Использование CDI необходимо если вы хотите автоматически провиженить персистентные тома для ваших виртуальных машин, а так же потребуется вам в дальнейшем для использования KubeVirt CSI Driver.

Но прежде всего вам придется решить, где и как вы будете хранить эти данные.

Реализация хранилища под данные ВМ

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

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

Использование блочных устройств для виртуальных машин уберёт лишний уровень абстракции и в большинстве случаев позволит вам использовать режим ReadWriteMany для организации доступа с нескольких нод одновременно. Использование ReadWriteMany томов - это необходимое требование чтобы работала live-миграция виртуальных машин в KubeVirt.

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

внешнее хранилище данных
внешнее хранилище данных

Подход с внешними хранилищами часто используется в крупных энтерпрайз-системах, потому что такое хранилище часто предоставляет внешний вендор, а за интеграцию с Kubernetes ответственна лишь малая часть - CSI-драйвер, который устанавливается в кластер и ответственен за заказ томов в этом хранилище и подключение их к подам, запускаемым Kubernetes. Хотя такое хранилище так же может быть реализовано и используя лишь свободные технологии. Наиболее популярное решение такого рода - TrueNAS, расширяемый драйвером democratic-csi

локальное хранилище данных
локальное хранилище данных

Гиперконвергентные системы часто реализуются с помощью локальных решений (когда вам не нужна репликация) и более умными программными кластерными хранилищами, часто устанавливаемых прямо в Kubernetes: Rook/Ceph, OpenEBS, Longhorn, LINSTOR и другими.

кластерное хранилище данных
кластерное хранилище данных

Гиперконвергентная система имеет как плюсы, это например data locality - что означает ваши данные могут быть доступны локально, а значит быстрее и скорость доступа к ним, но так же и минусы - такой системой сложнее управлять и обслуживать.

Мы в Ænix хотели предоставить наиболее готовое решение, которые вы могли бы использовать без необходимости покупать и устанавливать отдельное внешнее хранилище, а также было бы оптимально по скорости и использованию ресурсов. Таким решением стал LINSTOR.

Использование проверенных временем и популярных в индустрии технологий вроде LVM и ZFS в качестве бэкенда позволяют быть уверенными в том что данные надёжно сохранены. А репликация на основе DRBD работает быстро, и не требовательна к ресурсам ноды.

Для установки LINSTOR в Kubernetes существует проект Piraeus, который имеет уже всё необходимое для того чтобы использовать его с KubeVirt.

В случае если вы используете Talos Linux, как мы описывали в прошлой статье, вам потребуется включить необходимые модули ядра заранее, как описано в инструкции.

Сеть для виртуальных машин

Несмотря на наличие похожего интерфейса CNI - в действительности сеть в Kubernetes несколько сложнее и как правило состоит из нескольких не связанных друг с другом частей. Давайте разберём каждую из них:

Сеть нод (сеть датацентра)

Сеть с помощью которой ноды связаны между собой обычно никак не управляется Kubernetes, но является важной частью, так как без неё ничего работать не будет. На практике, в bare metal инфраструктуре на данном уровне может вполне существовать и несколько подобных сетей: для коммуникации нод между собой, для репликации хранилища, для доступа извне и т.п.:

сеть нод (сеть датацентра)
сеть нод (сеть датацентра)

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

Сеть подов

Это сеть, которую предоставляет вам CNI-плагин. Задача CNI-плагина обеспечить прозрачную связность между всеми контейнерами и нодами в кластере. При этом большинство CNI-плагинов реализуют плоскую сеть из которой выделяются отдельные блоки IP-адресов для использования на каждой ноде.

сеть подов (CNI-plugin)
сеть подов (CNI-plugin)

На деле у вас в кластере может быть и несколько CNI-плагинов, управляемых Multus. И этот подход часто используется в решениях основаных на KubeVirt - Rancher и OpenShift. Основной CNI-плагин используется для интеграции с сервисами Kubernetes, а дополнительные CNI-плагины для реализации приватных сетей (VPC) и интеграции с физическими сетями вашего дата центра.

В качестве дополнительных CNI-плагинов могут использоваться как простые плагины из стандартного инструментария CNI, так и более специализированные вроде macvtap-cni.

В отличие от контейнеров вам также придётся побеспокоиться об IPAM (IP Address Management), в виртуальных средах эту задачу часто решает DHCP, а также о выделении MAC-адресов для виртуальных машин.

В Cozystack мы решили положиться на Kube-OVN, который полностью закрывает вопрос предоставления сети для виртуальных машин, имеет сущности для управления IP- и MAC-адресами, поддерживает live-миграцию виртуальных машин с переносом IP-адреса с ноды на ноду и создания VPC для физического разделения сетей между тенантами.

Используя Kube-OVN вы можете назначать отдельные подсети на целый неймспейс, или подключать их как дополнительные через Multus.

Сеть сервисов

Помимо CNI-плагина, в Kubernetes есть также сеть сервисов, она нужна в первую очередь для service discovery. Дело в том, что изначально Kubernetes был спроектирован так, чтобы запускать поды со случайным адресом. А сеть сервисов используется для того чтобы предоставлять удобную абстракцию (стабильные IP-адреса и DNS-имя), которые всегда направят трафик в нужный под.

сеть сервисов (services plugin)
сеть сервисов (services plugin)

За реализацию сети сервисов в Kubernetes отвечает services plugin, и несмотря на то, что в наше время он всё чаще поставляется в составе CNI-плагина, его стоит рассматривать как отдельную сущность. Стандартная реализация называется kube-proxy и используется в большинстве кластеров. Наиболее продвинутую реализацию предлагает проект Cilium, который можно запустить в режиме kube-proxy replacement.

Cilium разработан на основе технологии eBPF, которая позволяет эффективно оффлоадить сетевой стек Linux, улучшая тем самым производительность и безопасность по сравнению с классическими методами основанными на iptables.

На деле Cilium довольно легко интегрируется с kube-ovn, предоставляя в связке удобную мультитенантную сеть для виртуальных машин, а так же расширенные сетевые политики и функциональность сети сервисов.

Балансировщик внешнего трафика 

На данном этапе у вас уже есть всё необходимое для запуска виртуалок в Kubernetes. Но на самом деле это ещё не всё. Вам необходим надёжный способ доступа снаружи вашего кластера к вашим сервисам и внешний балансировщик - это как раз та сущность которая вам поможет в организации этого.

Для Kubernetes на bare-metal существует несколько балансировщиков: MetalLB, kube-vip, LoxiLB, а так же встроенные реализации анонса сервисов в Cilium и Kube-OVN.

Основная задача балансировщика - это предоставить стабильный внешний адрес и направить трафик в сеть сервисов, тогда services plugin направит его уже к вашим подам и виртуалкам.

внешний балансировщик
внешний балансировщик

В большинстве случаев создание балансировщика на bare metal осуществляется через назначение плавающего IP-адреса внутри кластера, который анонсятся наружу с помощью протоколов ARP/NDP или BGP.

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

В режиме L2 спикеры MetalLB постоянно обмениваются своим состоянием друг с другом с помощью протокола memberlist, что позволяет не зависеть от Kubernetes control-plane для реализации отказоустойчивости.


На этом про виртуализацию, хранилище и сети в Kubernetes у меня всё.

Перечисленные в статье решения полностью настроены и доступны для использования в платформе Cozystack, вы можете попробовать их совершенно бесплатно.

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

Tags:
Hubs:
Total votes 13: ↑12 and ↓1+11
Comments6

Articles

Information

Website
aenix.io
Registered
Employees
2–10 employees
Location
Чехия
Representative
Andrei Kvapil