Контейнерная виртуализация еще недавно воспринималась как некая диковинка, в лучшем случае ее рассматривали как недорогой вариант создания инфраструктуры для хостинга. Но сегодня, когда благодаря облачной революции на первый план вышли такие требования к центрам обработки данных, как эластичность, масштабируемость и высокая вычислительная плотность, контейнеры стали предметом повышенного интереса — прежде всего потому, что они как нельзя лучше подходят для решения названных задач. Почему же о них раньше забывали и почему вспомнили теперь?
В самых общих чертах виртуализация — это искусство запуска одной операционной системы поверх другой. История ее развития довольно долгая и богатая. Задолго до гипервизоров и UNIX-систем виртуализация использовалась в мейнфреймах для разделения различных операционных систем. Широкое распространение в системах UNIX и Linux она получила лишь в начале века. В 2001 году компания VMware выпустила серверный продукт для виртуализации на основе гипервизора, привлекший внимание корпоративных заказчиков. Практически в то же самое время компания Parallels представила решение для контейнерной виртуализации Virtuozzo, заслужившее признание у провайдеров услуг хостинга. Такое разделение сохранялось почти 12 лет: гипервизорной виртуализации не удавалось завоевать сколько-нибудь значимый кусок рынка хостинга, а контейнеры не могли проникнуть в корпоративный сегмент. Перелом наметился в 2013 году, когда новый разработчик Docker привлек внимание представителей бизнеса к преимуществам контейнерной технологии.
КОНТЕЙНЕРЫ ПРОТИВ ГИПЕРВИЗОРОВ — ВСЕ ДЕЛО В ПЛОТНОСТИ
Гипервизор работает следующим образом (см. Рисунок 1): операционная система хоста эмулирует аппаратное обеспечение, поверх которого уже запускаются гостевые операционные системы. Это означает, что взаимосвязь между гостевой и хостовой операционными системами следует «железной» парадигме: все, что «умеет» делать оборудование, должно быть доступно гостевой ОС со стороны хостовой. Напротив, контейнеры (см. Рисунок 2) — это виртуализация на уровне операционной системы, а не оборудования, то есть каждая гостевая ОС использует то же самое ядро (а в некоторых случаях — и другие части ОС), что и хостовая. Это дает контейнерам большое преимущество: они меньше и компактнее гипервизорных гостевых сред, поскольку у них с хостом гораздо больше общего.
Рисунок 1. Схема гипервизорной виртуализации. |
Рисунок 2. Схема контейнерной виртуализации. |
Другой большой плюс — значительно большая эффективность контейнерной виртуализации в отношении совместного использования ресурсов, так как для нее контейнеры — это всего лишь управляемые ресурсы. К примеру, когда Контейнер 1 и Контейнер 2 работают с одним и тем же файлом, ядро хоста открывает этот файл и размещает страницы из него в страничный кэш ядра, которые затем передаются Контейнеру 1 и Контейнеру 2: если оба «хотят» прочитать одни и те же данные, они получают одну и ту же страницу. Если же гипервизорным виртуальным машинам VM1 и VM2 надо выполнить такую же операцию, то сначала сам хост открывает запрашиваемый файл (создавая страницы в своем страничном кэше), а затем еще и каждое из ядер VM1 и VM2 выполняет аналогичное действие. Таким образом, в процессе чтения машинами VM1 и VM2 одного и того же файла в памяти существует целых три одинаковых страницы (по одной в страничном кэше хоста и в ядрах VM1 и VM2), потому что они не «умеют» одновременно использовать одну и ту же страницу, как это делают контейнеры.
Дело даже не столько в «чтении» файлов, сколько в возможности использовать одну копию исполняемых файлов и разделяемых библиотек (shared libs) в разных контейнерах. В обычной системе, если два или более процесса обращаются к одной и той же разделяемой библиотеке (например, libc), ее код присутствует в памяти только в одном экземпляре. Это относится и к исполняемым файлам, и к сегментам немодифицируемых данных, что позволяет существенно снизить требования к размеру оперативной памяти. Так как контейнеры используют единое ядро, вышеописанный механизм при некоторых условиях распространяется и на них, что приводит, в частности, к повышению плотности их размещения, которая и без этого механизма изначально выше, чем у виртуальных машин, поскольку отсутствуют множественные копии ядра.
В результате у контейнеров плотность (количество виртуальных сред, которые можно запустить на сервере) может быть до трех раз выше, чем у виртуальных машин, а на одном сервере вполне может размещаться несколько сотен контейнеров. Столь высокая плотность — одна из главных причин популярности контейнеров на рынке хостинга виртуальных выделенных серверов (VPS). Если на одном и том же сервере можно создать в три раза больше VPS, то в расчете на один VPS затраты снижаются на 66%, что для такого низкомаржинального бизнеса, как хостинг, иногда равно разнице между убыточностью и прибыльностью.
Конечно, не все идеально в мире контейнеров. Например, из-за совместного использования ядра на одном сервере нельзя запускать разные гостевые ОС (например, на системе с Linux-контейнерами невозможно запустить FreeBSD или Windows, но разные дистрибутивы Linux — сколько угодно). Поэтому Windows и Linux на одном и том же сервере (что для гипервизоров не проблема) не работают. Однако по крайней мере в случае Linux этот недостаток можно смягчить за счет использования интерфейсов ABI и библиотек: благодаря этому появляется возможность запускать на одном сервере контейнеры с различными дистрибутивами Linux, но одновременно сокращается общая для этих контейнеров часть ресурсов. В максимальной же степени преимущества контейнеров проявляются в однородной среде.
ИСТОРИЯ КОНТЕЙНЕРОВ
В 2005 году компания Google занялась задачей массового предоставления Web-сервисов, а именно искала способ эластичного масштабирования ресурсов в своем центре обработки данных, чтобы каждый пользователь имел возможность получить достаточный уровень сервиса в любой момент, независимо от текущей загрузки, а оставшиеся ресурсы можно было использовать для служебных фоновых задач.
Поэкспериментировав с традиционной виртуализацией, сотрудники Google сочли ее не подходящей для решения этой задачи. Главной проблемой стали слишком большие потери производительности (соответственно, плотность оказалась слишком низкой) и недостаточно эластичный отклик для динамического переконфигурирования системы под изменившуюся нагрузку для массового предоставления Web-сервисов.
Последний пункт очень важен, потому что заранее предсказать, сколько запросов — десятки, сотни тысяч или даже миллионы — будут обслуживать Web-сервисы, невозможно. Но пользователи всегда ждут немедленного отклика (а это означает, что разница между нажатием кнопки и появлением результата на экране должна быть незаметна для глаз) независимо от того, сколько именно других людей в этот же момент работают с сервисом. Среднее время загрузки гипервизорной виртуальной машины — десятки секунд, поэтому такой тип виртуализации не подходит для этой задачи.
В то же самое время одна группа разработчиков экспериментировала с Linux и концепцией, основанной на механизме cgroups — так называемые контейнеры процессов. Google наняла этих специалистов для работы над контейнеризацией своих ЦОД с целью решения проблемы эластичности при масштабировании. В январе 2008 года часть технологии cgroup, используемой Google, была перенесена в ядро Linux. Так родился проект LinuX Containers (LXC). Тем временем Parallels выпустила версию своей виртуализации Virtuozzo с открытым исходным кодом под названием OpenVZ. В 2011 году Google и Parallels пришли к соглашению о сотрудничестве в области контейнерных технологий. Результатом стал релиз ядра Linux версии 3.8, представленный в 2013 году. В нем были объединены все актуальные на тот момент контейнерные технологии для Linux, что позволило избежать повторения болезненного разделения ядер, как в случае с KVM и Xen.
КОНТЕЙНЕРЫ НА ПРЕДПРИЯТИИ: ПОЧЕМУ АЖИОТАЖ ИМЕННО СЕЙЧАС?
Для хостинг-провайдеров основное преимущество контейнерной виртуализации заключается в плотности, которая корпоративным клиентам была не очень-то нужна. Для последних виртуализация предлагалась как решение проблемы низкой загруженности серверного оборудования (чтобы не простаивало) и способ использования свободных вычислительных ресурсов. А раз необходимости увеличивать нагрузку не было, то и контейнеры практически игнорировались корпоративным сегментом, на который приходится 85% всего рынка виртуализации.
Ситуация начала меняться после 2010 года — с ростом объемов облачных вычислений. При этом компании столкнулись с такими же трудностями, что и Google, — как добиться эластичного масштабирования ресурсов в центрах обработки данных и вдобавок обеспечить хороший уровень сервиса. И в этом случае у гипервизоров время загрузки оказалось слишком медленным для обеспечения быстрого отклика системы, что приводило к неспособности оперативно выделять необходимые объемы ресурсов. В то же время контейнеры позволяют обслуживать больше (как уже говорилось — до трех раз) клиентских запросов без необходимости добавлять оборудование. В результате корпоративные заказчики наконец обратили внимание на контейнеры.
Но возникли следующие проблемы: во-первых, сотрудники многих компаний просто не знали, что возможны и другие варианты виртуализации, кроме гипервизоров, и не умели работать с другой технологией, а во-вторых, значительные бюджеты уже были потрачены на покупку и управление гипервизорными решениями. В подобных условиях полный переход на новую технологию — не лучшая идея.
Такая ситуация сохранялась до 2013 года, когда только что вышедшая на рынок компания-разработчик Docker продемонстрировала, как легко «упаковать» контейнеризованное приложение в Linux и развернуть его с возможностью масштабирования прямо в dotCloud (сервис Platform as a Service, PaaS от Docker). Предприятия заинтересовались данным подходом. Одновременно OpenStack пообещала объединить системы управления облаками (Cloud Management) в единую платформу, охватывающую обе технологии виртуализации. Когда бизнес наконец-то увидел возможность управлять своими центрами обработки данных на основе гипервизоров с помощью единого инструмента, который параллельно позволяет осуществлять масштабное развертывание контейнеризованных приложений, начался настоящий бум.
КОНТЕЙНЕРЫ И NFV
В качестве примера нестандартного подхода к решению задач виртуализации с помощью контейнеров рассмотрим виртуализацию сетевых функций (Network Function Virtualization), весьма востребованную технологию на рынке телекоммуникаций. Традиционно при NFV с использованием гипервизора сетевая функция выполняется в гостевом ядре и пропускает через себя весь сетевой трафик, для чего применяются средства виртуального драйвера. Последний, в свою очередь, извлекает этот трафик непосредственно из физического канала передачи информации (что соответствует первому уровню сетевой модели OSI). Благодаря такому подходу гостевая система может обрабатывать сетевой трафик с эффективностью физического устройства, находясь при этом в виртуальной среде под программным контролем.
Упомянутую сетевую функцию можно реализовать в гостевой системе через один или несколько стандартных сетевых интерфейсов. А вместо внедрения драйвера можно попробовать подсоединить контейнер к такой проксирующей функции с помощью средств сетевого интерфейса. Применяемая в контейнерах технология под названием «сетевое пространство имен» (network namespace) позволяет превратить сетевой интерфейс из совместно используемого в выделяемый одному контейнеру. Поэтому, если есть возможность внедрить специальный драйвер в общее ядро операционной системы, сетевой интерфейс, с которым связан этот драйвер, можно по-прежнему (как при использовании гипервизора) передать в отдельный контейнер посредством пространства имен.
С помощью такого специального драйвера контейнер получает способность обрабатывать сетевой трафик в виртуальной среде, при этом достигаются большая плотность виртуальных объектов и высокая эффективность, ведь контейнерная инфраструктура занимает меньший объем (по сравнению с виртуальными машинами). Эту концепцию можно развить: поскольку приложение в контейнере может пользоваться сервисами физической операционной системы, каждое из запущенных в ней приложений можно вынести в отдельный контейнер с собственной прокси-функцией и отдельное приложение будет запускаться в своем собственном сетевом окружении. В этом подходе, называемом контейнеризацией приложения, в контейнере размещается только приложение, без операционной системы. В результате плотность размещения приложений будет почти в 100 раз больше, чем при традиционной виртуализации.
БЛИЖАЙШЕЕ БУДУЩЕЕ: КОНТЕЙНЕРЫ РЕШАЮТ ВСЕ?
Контейнеры — это проверенная технология для достижения высокой плотности, большой гибкости и необходимого масштабирования. Они могут помочь с упаковкой и масштабным развертыванием Web-приложений, а использование их свойств в Web-приложениях и платформах способствует решению некоторых проблем, возникающих при предоставлении облачных услуг, таких, например, как многопользовательский доступ.
Однако контейнеры — не универсальное решение, тем более что бизнес уже инвестировал в такие ориентированные на гипервизоры технологии, как SR-IOV, VT-D и Network Function Virtualization. Большинство из них разработаны для осуществления прямой связи между гостевой виртуальной машиной и аппаратной или коммутационной системой с помощью специального драйвера, установленного в гостевом ядре. Так как контейнерная технология работает на уровне операционной системы, она не может «говорить» на языке «железа», но почти для каждой корпоративной аппаратной гипервизорной технологии (например, SR-IOV или NFV) есть решение, которое может быть использовано в контейнере.
Однако реальность такова, что контейнерный подход не будет работать, если рассуждать о нем в парадигме гипервизора. Вместо этого стоит подумать, как сделать одну из упомянутых выше технологий доступной для контейнеров. Или просто оценить потребности своего бизнеса и современные возможности виртуализации и спросить себя, а что будет, если выбрать контейнеры. Результаты могут вас удивить.
Джеймс Боттомли — технический директор продуктов серверной виртуализации Parallels, член совета Linux Foundation (Technical Advisory Board Member of Linux Foundation).