Всем привет! Меня зовут Ярослав Покрепов, я DevOps-инженер в Авито

Виртуализация — это технология создания изолированных и независимых виртуальных сред на базе физических ресурсов. Виртуализация в Авито — это неотъемлемая часть технического стека, как и во многих других IT-компаниях. На этапе основания Авито виртуализация уже была широко распространённой технологией. Проект нуждался в эффективных и гибких решениях для управления ресурсами, в возможности масштабироваться в будущем и в обеспечении стабильной работы при растущей нагрузке.

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

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

Содержание

Эпоха Bare-Metal: когда всё держалось на железе

В 2007-м году, у своих истоков, Авито было развёрнуто на одном, а затем на нескольких железных серверах. В первые месяцы жизни Авито физически было разделено на prod и dev среды. Ежемесячно, по грубым оценкам, прирост уникальных пользователей составлял порядка 130 000. С течением времени и ростом компании необходимость виртуализации и потребность в разделении ресурсов стала очевидной. Разворачивать всё бо́льшие и бо́льшие мощности на физических серверах без виртуализации стало невозможным по понятным причинам — отсутствие возможности на железных серверах разграничивать среды влекло за собой проблемы с контролем ресурсов, а также риски со стороны безопасности проекта.

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

На этом этапе инфраструктура строилась максимально просто: без сложной виртуализации, без абстракций и без долгосрочного планирования. Подход был утилитарный — использовать доступные ресурсы как есть, а при росте просто добавлять новые. Разделение окружений (production, staging) либо отсутствовало, либо реализовывалось физически, на уровне отдельных машин. Это был нормальный этап для раннего проекта: скорость была важнее архитектурной строгости.

Тут еще больше контента

OpenVz: первый шаг к изоляции

К началу 2010 года рост проекта начал ускоряться, и прежний подход перестал справляться с нагрузкой. Это был момент, когда стало понятно: дальше без изоляции и более гибкого управления ресурсами двигаться нельзя.Так взор Авито упал на OpenVz. 

Сделаем небольшое отступление. Говоря об OpenVz и вообще разных решениях, важно учитывать контекст того времени: это не был рынок с десятками зрелых продуктов. Выбор был ограничен, а многие альтернативы либо находились в зачаточном состоянии, либо не подходили для production. Поэтому решение выбиралось не из лучших, а из достаточно стабильных и уже проверенных.

Сам процесс выбора выглядел довольно просто: инициатива шла от отдельных инженеров, которые приносили идею → обсуждали её внутри команды → быстро принимали решение и переходили к внедрению. Формальных исследований или длительных сравнений практически не было — скорость принятия решений была важнее.

OpenVz привлёк простотой внедрения, минимальными затратами и очевидными плюсами использования контейнерной виртуализации на базе ядра Linux. Тогда это были порядка 20–30 контейнеров VPS с основным кодом, вспомогательными приложениями и 3–4 балансировщика над ними. Это позволяло запускать множество изолированных VPS на одном физическом хосте без эмуляции оборудования, что идеально подходило для ограниченного бюджета и необходимости быстрого масштабирования под растущую нагрузку площадки.

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

Но OpenVz имел и ряд недостатков, таких как слабая изоляция контейнеров (общее ядро, уязвимое для сбоев), медленная работа с диском и более худшая совместимость с low-level инструментами. К 2010 году рост Авито потребовал лучшей безопасности и гибкости, что привело к логичному решению команды. 

LXC: больше гибкости, меньше ограничений

К 2013-му году проблемы с изоляцией и поддержкой новых дистрибутивов стали очевидными, а рост Авито требовал большей гибкости и безопасности, чем просто ±30 VPS. Эти ограничения долгое время можно было обходить, но с ростом инфраструктуры это становилось всё дороже и сложнее. В какой-то момент стало проще перейти на новую технологию, чем продолжать поддерживать старую.

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

В тот момент в противовес OpenVZ нативная контейнерная виртуализация LXC предлагала улучшенную изоляцию на уровне cgroups и namespaces, лучшую совместимость с современными ядрами и меньшие накладные расходы без патченного ядра, что сделало её логичным шагом эволюции.

Не обошлось и без автоматизации того времени — vz2lxc скрипт, который автоматизировал перенос контейнеров из OpenVZ в LXC: останавливал vz-контейнер, создавал архив rootfs, переносил на LXC-хост, распаковывал в новую структуру, адаптировал сеть (venet → eth0), правил resolv.conf, fstab и отключал ненужные сервисы через chroot. Это минимизировало ручной труд, обеспечивало консистентность конфигураций и позволяло мигрировать десятки контейнеров без длительных простоев.

К 2016-му году парк LXC вырос до сотен инсталляций, а количество строк кода в монолите приблизилось к миллиону. Спустя десятилетие мы так же пользуемся функционалом LXC, но в куда меньших масштабах, чем в то время.

Жми сюда!

QEMU+libvirt, фермы LXC и Vmware: переход к полноценной виртуализации

К 2017 году контейнерные технологии OpenVZ и LXC в некоторой мере исчерпали потенциал для задач, требующих полной изоляции и поддержки разных ОС. Также архитекторы столкнулись с аппаратным ограничением — максимум 64 LXC на одном железном сервере на тот момент.

Некоторые решения, разворачиваемые на базе LXC, стали требовательны к отказоустойчивости (не только горячему резервированию) и к гибкому live-мигрированию. Существует и по сей день автоматизация переноса LXC между DC, и в тот момент взор был обращён в сторону виртуализации. Появление на рынке всё большего разнообразия продуктов на разных ОС и потребность в полностью изолированной среде привели к необходимости виртуализации, возможности деплоя Windows, live-миграции VM и лучшей безопасности, что способствовало частичному переходу к аппаратному гипервизору.

В офисах и датацентрах было развёрнуто множество решений для реализации мониторинга, внутреннего учёта и других жизненно важных сервисов для компании. В датацентрах стали появляться одиночные гипервизоры Libvirt для создания изолированных сред по некоторым enterprise-сценариям. Основной код оставался на LXC-контейнерах — это порядка 300–500+ контейнеров на 50+ серверах.

Параллельно развивалось молодое на тот момент направление Kubernetes в IaaS-инфраструктуре, и было принято решение о постепенном распиле монолита, о чём коллеги подробно рассказывают в этой статье.

Proxmox: централизация и контроль

В последнем, или текущем периоде переход на Proxmox VE произошёл благодаря потребности в централизованном управлении огромным количеством сред для виртуализации под внутренние задачи и некоторые enterprise-решения. Libvirt со временем начал уступать набирающему популярность PVE в удобстве оркестрации HA-кластеров, нативной поддержке Ceph, интеграции с LDAP и постоянным обновлениям с новыми фичами от большого сообщества.

В 14-х годах решение кластеризации средствами PVE выглядело как один продуктовый кластер на ±16 гипервизоров с подключённым Ceph-хранилищем в качестве RBD. Но время шло, и вместе с этим росла инфраструктура виртуализации. Мы начали выделять отдельные кластеры PVE и не забывали допускать ошибок. Так, например, мы сами того не подозревая вырастили нежизнеспособного гиганта — кластер на 32+ гипервизора с одним сетевым интерфейсом, состоящим из двух каналов, объединённых в бондинг.

Самым правильным решением было бы выделить для corosync отдельный сетевой интерфейс, но, увы, такой технической возможности не представилось. С этого момента началось переосмысление и переход к горизонтальной политике масштабирования кластеров, разнесение крупных на более мелкие и коррекционные меры, которые мы могли себе позволить, а именно корректирование конфигурации corosync с подгоном параметров под наши условия и пересборка watchdog-mux для увеличения времени ожидания отклика от pve-ha-[crm|lrm] и снижение трафика на коросинке путём описания pmxcfs в Puppet.

Мощное REST API и работа коллег из IaaS позволили автоматизировать большинство операционных процессов, таких как создание, удаление и изменение VM, и упакованы в user-friendly web-панель (об этом я напишу отдельную статью чуть позже).

На данный момент виртуализация выглядит как 20+ PVE-кластеров, в каждом из которых по 15 гипервизоров, по 5 на каждый датацентр, распределённые Ceph-хранилища, разбитые по целевым пулам и подключённые к кластерам, подключённая LDAP-аутентификация, самописный модуль от коллег из IaaS, который позволяет эффективно управлять этой инфраструктурой, а также PDM, который мы активно обкатываем, и IaC.

В датацентрах также крутится 10–15 серверов в качестве LXC-ферм под различные задачи и VMware-гипервизоры в офисах и DC для поддержки некоторых legacy-решений. Ну и, конечно же, Kubernetes, куда же без него, приютивший у себя микросервисную архитектуру.

Заключение

За время с 2007 года инфраструктура Авито прошла путь от простой и почти ручной до сложной, распределённой и автоматизированной системы. При этом ни одно решение не было окончательным — каждая технология со временем упиралась в ограничения и требовала следующего шага. И это, пожалуй, главный вывод: инфраструктура — это непрерывная эволюция, а не конечное состояние.

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

Пишите мысли и вопросы в комментариях — буду рад пообщаться!

Кликни здесь и узнаешь