УДК 004.451
А. Л. Миркин, В. А. Петров
Московский физико-технический институт (государственный университет) Институтский пер., 9, Долгопрудный, Московская обл., 141700, Россия Email: [email protected], [email protected]
СИСТЕМА МИГРАЦИИ ВИРТУАЛЬНЫХ СЕРВЕРОВ В РЕЖИМЕ РЕАЛЬНОГО ВРЕМЕНИ
Виртуализация на уровне операционной системы - это расширение функциональности ядра ОС, которое дает возможность запускать несколько изолированных друг от друга групп процессов, известных как виртуальные серверы (virtual servers) или контейнеры (containers), не требуя при этом загружать еще одно ядро. Подобная изоляция позволяет сохранять полное состояние (checkpoint) контейнера, чтобы в дальнейшем его можно было восстановить (restart) в такое же состояние. Процедуры сохранения и восстановления используются для реализации миграции в режиме реального времени. В этой статье мы рассматриваем реализацию системы сохранения, восстановления и миграции в проекте OpenVZ.
Ключевые слова: виртуализация, операционная система, сохранение и восстановление состояния, миграция.
Введение
Современные компьютеры достаточно производительны для того, чтобы запускать на них одновременно несколько виртуальных машин, каждая из которых будет работать независимо от других, а для пользователей выглядеть обычным сервером. Существует несколько систем, которые позволяют создавать такие виртуальные машины. Проект OpenVZ 1 представляет собой один из подходов к виртуализации на уровне операционной системы (ОС) для Linux. Отличительной особенностью этого подхода является то, что создание и управление контейнерами, а также выполнение процессов внутри осуществляется при помощи одного и того же ядра операционной системы. С точки зрения ядра каждый такой виртуальный сервер - это группа процессов полностью изолированных от остальных контейнеров и основной управляющей системы.
Подобные виртуальные серверы, не привязанные к конкретному оборудованию, делают возможной миграцию таких контейнеров с одного реального сервера на другой. Самый простой способ миграции осуществляется следующим образом: остановка виртуального сервера, перенос его файловой системы на другой компьютер и последующий его старт. Такой способ миграции очень неудобен, так как он требует остановки виртуального сервера, а значит, миграция должна быть заранее запланирована.
Полная изолированность контейнера от других контейнеров дает возможность сохранять его состояние в файл на диске (процедура, известная как checkpointing). Используя это сохраненное состояние, контейнер можно восстановить позже, и он продолжит работать так, как будто работа не прерывалась вообще.
Система сохранения и последующего восстановления контейнеров помогает решить несколько очень важных задач: перезагрузка серверов, их обслуживание и обновление ядра операционной системы. Также этот механизм можно использовать для миграции контейнера с одного сервера на другой без его остановки, подобная процедура называется миграцией в режиме реального времени (live migration).
Существующие системы
Существует несколько систем, которые предлагают механизм сохранения и восстановления:
• CHPOX (Checkpointing for Linux) [Sudakov et al., 2003];
• EPCKPT (Eduardo Pinheiro checkpointing project) [Pinheiro, 1997];
1 См.: http://openvz.org
ISSN 1818-7900. Вестник НГУ. Серия: Информационные технологии. 2008. Том 6, выпуск 3 © А. Л. Миркин, В. А. Петров, 2008
• TCPCP (TCP connection passing) [Almesberger, 2004];
• CRAK (Checkpointing/restart as a kernel module) [Zhong et al., 2001];
• ZAP [Osman et al., 2002];
• BLCR (Berkeley lab checkpointing/restart) [Duell et al., 2002];
• Sprite 2 ;
• Xen 3;
• VMware 4;
• OpenSolaris 5;
• OpenVZ 6.
Все основанные на ОС Linux системы с открытым исходным кодом и доступные для изучения имеют один из следующих недостатков:
1) не все ресурсы, используемые процессами, могут быть сохранены и восстановлены позже;
2) не гарантируется успешное восстановление процессов из-за возможных ресурсных конфликтов (например, процесс и до и после восстановления должен иметь один и тот же идентификатор PID, но после того, как процесс был сохранен, такой идентификатор может быть занят другим процессом).
Первая проблема может быть решена при помощи самой системы сохранения и восстановления, а вот для решения второй требуется модификация операционной системы. Необходимо предоставление виртуальных идентификаторов, уникальность которых всегда может быть обеспечена. В системе OpenVZ эта проблема уже решена: созданный контейнер будет иметь свои собственные и уникальные только внутри данного контейнера идентификаторы.
Системы VMware и Xen относятся к другим типам виртуализации, поэтому были рассмотрены только общие характеристики этих систем. Основной акцент при изучении существующих систем сохранения и восстановления состояния процессов делался на системы, основанные на ОС Linux, поэтому система OpenSolaris, являющаяся UNIX-подобной виртуализацией на уровне операционной системы, была рассмотрена только поверхностно.
Процесс сохранения контейнера
Рассмотрим более подробно процесс сохранения состояния виртуального сервера. Он состоит из трех фаз. Первая - замораживание процессов. Для того чтобы начать сохранение процессов, необходимо перевести их в специальное состояние, которое будет нам известно и из которого процесс не сможет выйти. В нашем случае это осуществляется следующим образом: на всех процессах и нитях исполнения (thread) выставляется специальный флаг TIF_FREEZE, а планировщик задач, видя этот флаг у процесса, переводит его в специальное состояние, с которым в дальнейшем легко работать. Этот способ заморозки процессов отличается от уже существующих тем, что он не требует посылки процессам специальных сигналов. Также в этот момент необходимо отключить сетевой интерфейс виртуального сервера, для того чтобы сетевые структуры оставались неизменными в процессе сохранения.
Оценим время, которое тратится на заморозку процессов. Пусть n - количество процессов, которое надо заморозить, t - квант времени, который выдается процессам планировщиком задач, tmem - время обращения скорость обращения к памяти, Ecpu - производительность процессора. Так как после выставления специального флага процессы еще могут находиться в состоянии исполнения в течение выделенного им кванта времени, то общее время заморозки можно оценить следующей формулой:
freeze
n • t
V V
cpu m
2 The Sprite Operating System (http://www.eecs.berkeley.edu/Research/Projects/CS/sprite/sprite.html).
3 См.: http://www.xen.org
4 VMware, Inc. (http://www.vmware.com).
5 См.: http://opensolaris.org
6 См.: http://openvz.org
Вторая фаза - сохранение состояния виртуального сервера в файл. На этом этапе происходит сохранение состояний процессов и виртуального сервера: сохраняется информация о процессах, о сетевом интерфейсе, об открытых файлах, о сигналах, о виртуальной памяти, о структурах System V IPC, о сетевых соединениях. В отличие от других подобных систем в нашей системе реализована поддержка почти всех структур данных, что позволяет сохранять состояние любых приложений.
Этап сохранения состояния занимает гораздо больше времени, так как в этот момент происходит запись данных на диск, а скорость записи на жесткий диск в несколько раз меньше скорости записи в память. Пусть каждый процесс имеет k страниц памяти, которые надо сохранить, trmem - время, которое требуется, чтобы считать страницу данных из оперативной памяти, trswap - время, которое требуется, чтобы считать страницу данных из файла подкачки, U - загруженность оперативной памяти компьютера, f(U, k) - функция распределения количества страниц, находящихся в файле подкачки, twd,sk - время, которое тратится на запись
одной страницы данных на диск. Тогда общее время сохранения состояния будет оцениваться следующей формулой:
T„„,~I(f (и,к,)-( + (к, - f (U,k,))-t„
k t
wdisk
).
(2)
После небольшого преобразования оценочную формулу можно упростить до следующего вида:
~ Ъ(/ (,)•(
t -1
rswap rmem
) + k- * (t + t d- k
J , V rmem wdisk
))< )(ki ' (rswap +t wdisk )).
(3)
1 1 Третья фаза - либо остановка, либо продолжение работы виртуального сервера. Остановка делается в том случае, если необходимо осуществить перезагрузку сервера. Продолжение работы - если сохранение состояния процессов было сделано с целью резервирования.
При сохранении состояния процессов, необходимо также сохранять характеристики процессора. Это нужно для того, чтобы гарантировать, что процесс будет правильно выполняться на новой машине. Например, если приложение было запущено на Pentium4 и использует возможности технологии sse2, то это приложение не сможет правильно продолжить работу после миграции на машину с процессором без sse2.
Процесс восстановления контейнера
Более интересным для рассмотрения является процесс восстановления виртуального сервера. Он состоит из двух фаз. Первая - восстановление данных и перевод всех процессов в специальное состояние. Вторая - перевод процессов из специального состояния в состояние исполнения. Остановимся на первой фазе более подробно.
Некоторые операции по восстановлению состояния нельзя производить, когда процессы находятся не в состоянии исполнения. Например, нельзя включить сетевой интерфейс, поскольку в этом случае пользовательское приложение на другом конце соединения может оборвать связь, поэтому сетевой интерфейс включается в самом конце этой процедуры.
В самом начале восстанавливается дерево процессов. После этого каждому процессу изменяется точка возврата на функцию из нашего модуля. Таким образом, после запуска процесс сначала выполнит необходимые действия для восстановления (восстановит идентификаторы, регистры, сигналы, память, откроет необходимые файлы, сетевые соединения), а затем выйдет из этой функции и перейдет в замороженное состояние, а после разморозки продолжит свою работу.
Пусть ttask - время, которое тратит операционная система на создание одного процесса, trdisk - время, которое тратится на чтение одной страницы данных с диска, twmem - время, которое тратится на запись одной страницы данных в память. Тогда общее время восстановления всего сервера можно оценить следующей формулой:
Т
К
k -t
task ^i 1 rdisk
k-t )
, wmem / .
(4)
После небольшого упрощения оценочная формула принимает следующий вид
T ~V(t ■
restart \ task
ki •(
rdisk lwmem
))
(5)
1
При восстановлении существует несколько моментов, на которые стоит обратить внимание. Например, сетевые соединения (сокеты) используют системную переменную jiffies, чтобы создавать временные метки, поэтому необходимо сохранять эту переменную тоже. Однако просто восстановить это значение мы не имеем права, поскольку это системная переменная, от которой зависит работа всей системы. Поэтому приходится добавлять, некоторую новую системную переменную, в которой будет учтена разница между старым и новым значением.
Миграция контейнера
Используя механизм сохранения и восстановления можно реализовать систему миграции контейнеров в режиме реального времени. Алгоритм, не требующий дополнительного оборудования (например, сетевое хранилище SAN или iSCSI), выглядит следующим образом.
1. Перенос файловой системы контейнера. Это может быть сделано при помощи обычной утилиты rsync.
2. Заморозка виртуального сервера - все процессы в контейнере переводятся в замороженное состояние и отключается сеть.
3. Сохранение состояния контейнера в файл.
4. Вторая синхронизация файловой системы контейнера. Во время первого переноса файловой системы контейнер продолжает работу, поэтому некоторые файлы, которые уже переданы, могут измениться. Поэтому, после того как контейнер заморожен и файлы больше не изменяются, необходимо сделать повторную синхронизацию файловой системы.
5. Перенос файла с состоянием контейнера на сервер назначения.
6. Восстановление контейнера на сервере назначения. На этой стадии создаются все процессы и их ресурсы, используя файл с состоянием. После завершения этого этапа все процессы остаются в замороженном состоянии.
7. Разморозка контейнера и включение внутри него сетевого интерфейса на сервере назначения.
8. Остановка контейнера на исходном сервере.
9. Удаление файловой системы и конфигурационных файлов контейнера на исходном сервере.
Если во время миграции одна из стадий завершится с ошибкой, то можно осуществить откат в исходное состояние и контейнер продолжит свою работу на исходном сервере.
Для пользователей, подключенных к виртуальному серверу по сети, процесс миграции будет выглядеть как временная сетевая проблема, но спустя несколько секунд контейнер продолжит свою работу, находясь уже на другом сервере.
В предложенной схеме миграции в течение нескольких стадий контейнер находится в замороженном состоянии, именно эти стадии определяют продолжительность паузы в обслуживании: сохранение состояния контейнера, вторая синхронизация файловой системы, копирование файла с состоянием на сервер назначения, восстановление контейнера.
Оценим время, которое тратится на вторую синхронизацию файловой системы и копирование файла с состоянием на компьютер назначения. Пусть Vnet - пропускная способность сетевого интерфейса, Unet - загруженность сетевого канала, Sdisk - размер файловой системы контейнера. Размер файла с состоянием контейнера может быть оценен следующей формулой:
S.
dump
У к ■ S.
(6)
где Spage - размер одной страницы данных.
Тогда время необходимое на вторую синхронизацию можно оценить следующей формулой:
Т.
S -U
, u disk ^ net
V
Время необходимое на копирование файла с состоянием:
Т
copy
S • U
и dump net
V
(7)
(8)
или
Z kt • S page -Un
Т
Vne
(9)
Обозначив через tnet - время передачи одной страницы данных по сети получим следующую оценку:
n П
Tcopy ~Z ki ' tnet ' Unet — Z ki ' tnet , (10)
1 1
так как Unet > 1.
Оптимизация процесса миграции
Если сравнить оценки полученные для времени сохранения состояния и времени передачи файла с состоянием контейнера, то мы увидим что сравнение этих времен сводится к сравнению tnet и (trswap + twdisk). Время передачи страницы данных по сети гораздо больше времени, которое тратится на чтение и запись одной страницы данных с жесткого диска. Поэтому время, которое тратится на заморозку, сохранение состояния и восстановление контейнера, можно не учитывать при рассмотрении общей паузы в обслуживании.
Опытным путем было подтверждено, что вторая синхронизация файловой системы и перенос файла с состоянием контейнера занимают около 95% всей паузы. Именно поэтому рассматриваются варианты оптимизации этих стадий.
1. Оптимизация второй синхронизации файловой системы. Это может быть сделано путем уменьшения количества файлов, которые необходимо сравнить во время второй синхронизации. Для этого предлагается добавить в ядро операционной системы подсистему контроля изменяемых файлов.
2. Уменьшение размера файла с состоянием:
а) Сетевой файл подкачки - страницы, используемые процессами, передаются после процедуры миграции
б) Итеративная миграция - страницы, используемые процессами, в основном передаются до миграции.
Подсистема контроля изменяемых файлов. Задача данной подсистемы заключается в том, чтобы сохранять имена изменяемых за время ее работы файлов. Эта подсистема должна включаться перед первым переносом файловой системы контейнера и выключаться после его заморозки. Список измененных файлов будет использоваться во время второй синхронизации файловой системы, что значительно ускорит этот этап. Основная проблема состоит в реализации подобной подсистемы, так как для этого потребуются большие изменения в самом ядре операционной системы.
Миграция с использованием сетевого файла подкачки. Во время миграции, все данные процессов сохраняются в файл, который затем передается на сервер назначения. В случае использования контейнером большого объема памяти размер файла с состоянием может быть очень большим, в результате чего увеличится время передачи этого файла, а значит и пауза в обслуживании. Для того, чтобы решить эту проблему предлагается использовать миграцию с использованием сетевого свопинга. Основная идея этого метода заключается в следующем: до заморозки контейнера все его страницы памяти помечаются при помощи специального флага, который убирается, если страница изменена, после этого виртуальный сервер замораживается и его состояние сохраняется в файл, но в этом случае в файл попадают толь-
ко недавно измененные страницы памяти, у которых нет специального флага. Таким образом, размер файла с состоянием контейнера значительно уменьшается.
Основная задача, которую необходимо решить при использовании данного метода миграции, заключается в передаче не попавших в файл с состоянием страниц памяти на сервер назначения. Это делается при помощи создания специального «page-in» файла подкачки на сервере назначения и «page-out» приложения на исходном сервере.
1. Запрос страницы из файла подкачки.
2. Пересылка запроса па исходный сервер.
3. Поиск нужной страницы.
4. Передача страницы на сервер назначения.
5. 3aj рузка страницы в намять.
Рис. 1. Сетевой файл подкачки
Во время восстановления контейнера на сервере назначения все не сохраненные в файле с состоянием страницы памяти помечаются как страницы находящиеся в файле подкачки. Если после разморозки контейнера процессы попытаются обратиться к такой странице памяти, то будет создан специальный запрос к нашему файлу подкачки. Этот «page-in» файл представляет собой не обычный файл на диске, а специальную программу, которая может принимать запросы на страницы от процессов и пересылать их на исходный сервер. Приложение «page-out», находящееся на исходном сервере, принимает запросы и отправляет в ответ страницы памяти. После этого страница поступает на сервер назначения и возвращается процессу, который ее запросил (рис. 1). В течение нескольких первых минут после разморозки контейнера страницы передаются с исходного сервера по запросу процессов. После этого активируется принудительная перекачка страниц, и вся оставшаяся память контейнера передается на сервер назначения.
Итеративная миграция. Другой способ уменьшения размера файла с состоянием контейнера заключается в том, чтобы передавать страницы памяти заранее до заморозки виртуального сервера. Во время передачи страниц контейнер продолжает свою работу и некоторые страницы памяти могут измениться, поэтому страницы памяти должны передаваться в несколько итераций (отсюда и название этого метода). На первом шаге все страницы помечаются специальным флагом и передаются на сервер назначения. За время передачи некоторые страницы могут измениться, тогда специальный флаг на этих страницах удаляется. На следующем шаге передаются страницы, измененные во время первой итерации (рис. 2). Итеративный процесс останавливается, если не остается измененных страниц или если количество измененных страниц становится больше чем N/2, где N - это количество всех страниц в контейнере, i - это номер итерации.
Рис. 2. Итеративная миграция памяти контейнера
Передаваемые страницы сохраняются на сервере назначения и затем используются во время восстановления контейнера. Все страницы, измененные во время последней итерации, сохраняются в файл с состоянием контейнера и при восстановлении контейнера берутся из этого файла.
Заключение
В данной работе была рассмотрена система сохранения и восстановления виртуальных серверов. Был предложен и реализован механизм сохранения состояния процессов в виде компоненты системы OpenVZ. Были рассмотрены особенности восстановления процессов. На основе системы сохранения и восстановления была реализована система миграции контейнеров в режиме реального времени. Также были предложены возможные способы оптимизации процесса миграции с целью уменьшения паузы в обслуживании. В настоящее время предложенные оптимизирующие алгоритмы уже реализованы и находятся в тестировании. Исследования в данном направлении будут продолжаться.
Список литературы
Sudakov O. O., Boyko Yu. V., Tretyak O. V., Korotkova T. P., Meshcheryakov E. S. Process checkpointing and restart system for Linux // Mathematical Machines and Systems. 2003.
Pinheiro E. Truly-Transparent Checkpointing of Parallel Applications // Federal University of Rio de Janeiro UFRJ, December 1997.
Almesberger W. TCP Connection Passing // Proceedings of the Linux Symposium (Ottawa, Ontario, Canada), July 2004.
Zhong H., Nieh J. CRAK: Linux Checkpoint/Restart As a Kernel Module // Department of Computer Science, Columbia University, Technical Report CUCS-014-01, November 2001.
Osman S., Subhraveti D., Su G., Nieh J. The Design and Implementation of Zap: A System for Migrating Computing Environments // Proceedings of the Fifth Symposium on Operating Systems Design and Implementation (OSDI 2002), Boston, MA, December 9-11, 2002.
Duell J., Hargrove P. and Roman. E. The Design and Implementation of Berkeley Lab's Linux Checkpoint/Restart // Berkeley Lab Technical Report (publication LBNL-54941), December 2002.
Материал поступил в редколлегию 07.08.2008
A. L. Mirkin, V. A. Petrov
Containers Live Migration
Container-type virtualization is an ability to run multiple isolated sets of processes, known as containers, under a single kernel instance. Having such an isolation opens the possibility to save the complete state of (in other words, to checkpoint) a container and later to restart it. Checkpoint itself is used for live migration, in particular for implementing high-availability solutions. In this paper, we present the checkpoint and restart and live migration feature for containers as implemented in OpenVZ.
Keywords: virtualization, operating system, checkpoint, restart, migration.