суббота, 20 апреля 2013 г.

Балансировка нагрузки с LVS

Итак, у вас есть нагруженный сервер и вам вдруг захотелось его разгрузить. Вы поставили и залили такой же (такие же), но пользователи упорно ходят на первый. В этом случае конечно же нужно задуматься о балансировке нагрузки.



DNS-RR


Первым делом напрашивается вариант с использованием Round-robin DNS. Если кто не знает, это метод позволяющий размазать запросы между n-ым количеством серверов просто отдавая на каждый DNS запрос новый IP.

Каковы минусы:
  • Сложно управлять: вы забили группу IP-адресов и все, никаких тебе управлений весами, состояние серверов не отслеживается и т.д.
  • Фактически вы размазываете запросы по диапазону IP, но не балансируете нагрузку на серверах
  • Кэширование DNS клиента может поломать всю малину


Хотя и не стоит добавлять между вводом и выводом «слишком много компьютера», хочется каких-либо методов контроля над ситуацией.

LVS


И тут на помощь к нам приходит Linux Virtual Server или LVS. Фактически, это модуль ядра (ipvs), существующий еще где-то с версии 2.0-2.2.

Что же он из себя представляет? Фактически это L4-роутер (я бы сказал что L3, но авторы настаивают на L4), позволяющий прозрачно и управляемо разруливать пакеты по заданным маршрутам.



Основная терминология следующая:
  • Director — собственно узел осуществляющий роутинг.
  • Realserver — рабочая лошадка, узел нашей фермы серверов.
  • VIP или Virtual IP — всего лишь IP нашего виртуального (собранного из кучи реальных) сервера.
  • Соответственно DIP и RIP — IP директора и реальных серверов.


На директоре включается этот самый модуль IPVS (IP Virtual Server), настраиваются правила проброса пакетов и поднимается VIP — обычно как алиас к внешнему интерфейсу. Пользователи будут ходить через VIP.

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

Правила


Правила проброса пакетов крайне просты: задаем виртуальный сервис, определяемый парой VIP:port. Сервис может быть TCP или UDP. Здесь же задаем метод ротации узлов (планировщик, scheduler). Далее задаем набор серверов из нашей фермы, также парой RIP:port, а также указываем метод проброса пакетов и вес, если того требует выбранный планировщик.

Выглядит это примерно следующим образом.

# ipvsadm -A -t 192.168.100.100:80 -s wlc
# ipvsadm -a -t 192.168.100.100:80 -r 192.168.100.2:80 -w 3
# ipvsadm -a -t 192.168.100.100:80 -r 192.168.100.3:80 -w 2
# ipvsadm -a -t 192.168.100.100:80 -r 127.0.0.1:80 -w 1


Да, не забудьте поставить пакет ipvsadmin, он должен быть в репозитории вашего дистрибутива. Во всяком случае в Debian и RedHat он есть.

В примере выше мы создаем виртуальный HTTP сервис 192.168.100.100 и включаем в него сервера 127.0.0.1, 192.168.100.2 и 192.168.100.3. Ключ "-w" задает вес сервера. Чем он выше, тем с бОльшей вероятностью он получит запрос. Если выставить вес в 0, то сервер будет исключен из всех операций. Очень удобно, если нужно вывести сервер из эксплуатации.

Пакеты по умолчанию пробрасываются методом DR. Вообще существуют следующие варианты роутинга:
  • Direct Routing (gatewaying) — пакет направляется напрямую на ферму, без изменений.
  • NAT (masquarading) — просто хитрый механизм NAT.
  • IPIP incapsulation (tunneling) — туннелирование.


DR является наиболее простым, но если вам, например, нужно поменять порт назначения, то придется рисовать правила в iptables. NAT же требует, чтобы маршрут по умолчанию у всей фермы был направлен на директора, что не всегда удобно, особенно если реальные сервера имеют и внешние адреса.

Планировщиков в комплекте поставки несколько, подробно можно почитать в инструкции. Рассмотрим лишь основные.
  • Round Robin — знакомая всем круговая порука.
  • Weighted Round Robin — тоже самое, но с использованием весов сервера.
  • Least Connection — отправляем пакет серверу с наименьшим количеством соединений.
  • Weighted Least Connection — тоже самое, но с учетом весов.


Ко всему прочему, можно сообщить, что сервис требует persistence, т.е. удерживание пользователя на одном из серверов в течении заданного промежутка времени — все новые запросы с одного и того же IP будут прокинуты на тот же сервер.

Подводные камни


Итак, согласно примеру выше, мы должны были получить виртуальный сервер на VIP 192.168.100.100, о чем нам ipvsadm и радостно сообщает:

ipvsadm -L -n
IP Virtual Server version 1.0.7 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.100.100:80 wlc
-> 192.168.100.2:80 Route 3 0 0
-> 192.168.100.3:80 Route 2 0 0
-> 127.0.0.1:80 Local 1 0 0


Однако, при попытке соединения ничего не произойдет! В чем же дело? Первым делом необходимо поднять алиас.
# ifconfig eth0:0 inet 192.168.100.100 netmask 255.255.255.255

Но и тут нас ждет неудача — пакет приходит на интерфейс реального сервера немодифицированным и следовательно тупо отпинывается ядром как не предназначающийся машине. Простейшим методом разрешения этого вопроса является поднятие VIP на loopback.

# ifconfig lo:0 inet 192.168.100.100 netmask 255.255.255.255

Ни в коем случае не поднимайте его на интерфейсе, который глядит в ту же подсеть, что и внешний интерфейс директора. В противном случае внешний роутер может закэшировать mac не той машины и весь трафик пойдет не туда.

Теперь пакетики должны побежать куда надо. Кстати, директор сам может быть реальным сервером, что мы и видим в нашем примере.

Единая точка отказа


В этом решении очевидной точкой отказа, вызывающей разрушение всего сервиса, будет сам директор.

Что ж, не беда, ipvsadm поддерживает запуск в режиме демона с возможностью синхронизации таблиц и текущих соединений между несколькими директорами. Один, очевидно, станет мастером, остальные будут слейвами.

Что остается нам? Переезжать VIP между директорами в случае отказа. Тут нам помогут HA решения вроде heartbeat.

Другой задачей будет мониторинг и своевременный вывод из эксплуатации серверов из нашей фермы. Проще всего это делать весами.

Для разруливания обоих вопросов написано множество решений, заточенных под разные типы сервисов. Мне лично больше всего понравилось решение Ultramonkey, от самих же авторов LVS.

У RedHat есть родная штука под названием Piranha, она имеет свой набор демонов для мониторинга фермы и директоров и даже некий топорненький веб-интерфейс, однако она не поддерживает более чем 2 директора в HA связке. Уж не знаю почему.

Ultramonkey


Итак, Ultramonkey состоит из 2-х основных пакетов — heartbeat и ldirectord. Первый занимается обеспечением HA для директоров, в том числе поднятие и переезд VIP (и вообще говоря может использоваться не только для директоров), а второй поддерживает конфиг ipvsadm и мониторит состояние фермы.

Для heartbeat необходимо нарисовать 3 конфига. Базовые версии снабжены подробными комментариями, поэтому просто приведу примеры.

authkeys
auth 2
#1 crc
2 sha1 mysecretpass
#3 md5 Hello!

Настраиваем авторизацию демонов на разных машинах.

haresources
Здесь у нас информация о том, для какого ресурса мы создаем HA и какие сервисы дергаем при переезде.
director1.foo.com IPaddr::192.168.100.100/24/eth0 ldirectord

Т.е. поднять на интерфейсе eth0 192.168.100.100/24 и запустить ldirectord.

ha.cf
keepalive 1
deadtime 20
udpport 694
udp eth0
node director1.foo.com # <-- должно совпадать с uname -n !
node director2.foo.com #

Говорим каким образом поддерживать HA кластер и кто собственно в него входит.

У ldirectord всего один конфиг и там в общем-то тоже все понятно.
checktimeout=10
checkinterval=2
autoreload=yes
logfile="/var/log/ldirectord.log"
# Virtual Service for HTTP
virtual=192.168.100.100:80
real=192.168.100.2:80 gate
real=192.168.100.3:80 gate
service=http
request="alive.html"
receive="I'm alive!"
scheduler=wlc
protocol=tcp
checktype=negotiate


Т.е. ldirectord будет каждые 2 секунды дергать через http файл alive.html и если в нем не будет строчки «I'm alive!» или, хуже того, сервер не ответит, демон тут же поставит ему вес 0 и он будет исключен из последующих пересылок.

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

Применимость


Хотя везде по интернету в качестве сферы применения LVS в основном рассматривается балансировка веб-серверов, на самом деле им можно балансировать великое множество сервисов. Если протокол держится на одном порте и не имеет состояний, то его можно будет балансировать без особых проблем. Сложнее дело обстоит с мультипортовыми протоколами вроде samba и ftp, но и тут есть решения.

Кстати, в качестве реальных серверов не обязательно должен выступать Linux. Это можеть быть практически любая ОС со стеком TCP/IP.

Что еще почитать?


Построение высоко доступного web кластера с балансировкой нагрузки на базе linux

1. Описание проблемы

"Мой сайт просто обязан быть доступен 24 часа в сутки, 7 дней в неделю. Система, обеспечивающая доступ к нему, должна позволять легко нарастить мощность без потери доступности." Решение - HA/LB Cluster.

Вот некоторые понятия о которых мы будем говорить в этой статье:
Cluster
некоторое количество однотипных объектов соединенных вместе, применительно к компьютерам - несколько компьютеров предоставляющих однотипные ресурсы
HA (High Availability)
система, которая при сбое одного из компонентов продолжает нормальную работу
LB (Load Balanced)
предоставляет сервис из множества точек с одинаковыми ресурсами
Значит нас интересует набор программных продуктов который позволит построить высоко доступный web сервис на кластерной основе. Но:
а) мы хотим иметь действительно балансировку нагрузки, а не просто Round Robin.
б) система должна правильно вычислять "старых" пользователей и отправлять их на "старый" сервер, если он доступен. Например мы хостим книжный интернет магазин. Приобретая книгу мы кладем ее в корзину. Сервер запомнил что находится у нас в корзине. При следующем запросе оказывается что другой сервер в этот момент времени менее загружен и LB отправляет запрос на него. Этого никак нельзя допустить. Второй сервер ничего не знает о нашей корзине.
в) web сервер должен быть доступен при крахе любой отдельной части кластера.
г) наконец, мы люди любящие халяву, а значит коммерческое решение нас не устраивает.

После всех поставленных условий выбор оказывается не велик. Я остановился на mod_backhand в качестве балансировщика нагрузки и Wackamol в качестве основы для построения отказоустойчивой системы.

2. Mod_backhand

Mod_backhand это модуль для web сервера apache 1.3.X. Он собирает информацию о загруженности каждой системы в кластере. Когда приходит запрос, mod_backhand сначала определяет какие действия он должен произвести с ним (если этот запрос попадает в так называемую зону действия). Зоны действия mod_backhand определяются директивами <Files>, <Directory> и <Location> в httpd.conf и .htaccess файлах. Если запрос входит в зону действия mod_backhand он скармливается каждой определенной для зоны функции выбора кандидата. Функция выбора кандидата может сортировать и полностью изменять список серверов-кандидатов на выполнение запроса, а так же менять способ доставки выбранному серверу запроса(HTTP Redirect или Proxy). После выполнения последней функции выбора кандидата, первый сервер в списке кандидатов получает запрос. По умолчанию он получает его методом proxy - т.е. сервер к которому пришел запрос сам просит выполнить его сервер который оказался наиболее удачным кандидатом, а потом отдает результат его выполнения клиенту. Возможен и другой метод - HTTP Redirect. Он использует стандартные средства протокола http для того чтобы сказать клиенту что ресурс нужно запросить у другого сервера.

2.1 Установка

Установить mod_backhand проще простого. Я предпочитаю делать это во время сборки apache:

# cd /var/tmp
# ls
apache_1.3.28.tar.gz
mod_backhand-1.2.2.tar.gz
# gzip -d < apache_1.3.28.tar.gz | tar xf -
# gzip -d < mod_backhand=1.2.2.tar.gz | tar xf -
# ls
apache_1.3.28
apache_1.3.28.tar.gz
mod_backhand-1.2.2
mod_backhand-1.2.2.tar.gz
# cd mod_backhand-1.2.2
# ./precompile ../apache_1.3.28/
Copying source into apache tree...
Copying sample cgi script and logo into htdocs directory...
Adding to auto mod_so inclusion to configure...
Adding libs to Apache's Configure...
Adding to Apache's Configuration.tmpl...
Nullifying extra shared libraries for Linux
Modifying httpd.conf-dist...
Updating Makefile.tmpl...

Now change to the apache source directory:
../apache_1.3.28
And do a ./configure...

Затем конфигурируем Apache с поддержкой mod_backhand, компилируем и устанавливаем. Например так:
$ cd /var/tmp/apache_1.3.28
$ ./configure --prefix=/usr/local/apache --enable-module=so \
--enable-module=rewrite --enable-shared=rewrite \
--enable-module=speling --enable-shared=speling \
--enable-module=info --enable-shared=info \
--enable-module=include --enable-shared=include \
--enable-module=status --enable-shared=status \
--enable-module=backhand --enable-shared=backhand
$ make
# make install

2.2 Информация о ресурсах

Страница на которой будет находится статистика собранная mod_backhand с других узлов кластера поределяется директивой apache SetHandler backhand-handler. Если вы устанавливали mod_backhand вкомпилированным в apache (методом описанным в этой статье), то в httpd.conf уже есть директива:
<Location "/backhand/">
    SetHandler backhand-handler
</Location>
Значит статистика будет доступна по адрессу http://имя_узла/backhand/.

mod_backhand stats

2.3 Функция выбора кандидата.

Функция выбора кандидата определяет какие серверы являются кандидатами на выполнение запроса и сортирует их в соответствии с правилами описанными в настройке mod_backhand.
Например, в файле конфигурации apache мы можем указать что все файлы заканчивающиеся на .php будут обрабатываться наиболее доступными и наименее загруженным сервером:
<Files ~ "\.php$">
    Backhand byAge
    Backhand byLoad
</Files>
Когда кто нибудь попросит apache страницу заканчивающуюся на .php, сначала функция выбора кандидата byAge отсеет все сервера которые не отвечали в течении поледних 5 секунд, затем функция byLoad отсортирует этот список от менее загруженных к более загруженным. Так как больше не определенно функций выбора кандидата, обрабатывать запрос будет доверено первому серверу из списка т.е. наименее загруженному.

Встроенные функции выбора кандидата:
off отключает использование mod_backhand для текущей "зоны покрытия"
addSelf добавляет локальный сервер в конец списка
byAge [время в секундах] выбрасывает из списка серверы, с которых мы не слышали привета в течении установленного времени. По умолчанию - 20 сек
byLoad [преимущество] сортирует список серверов от менее загруженных к более загруженным. Преимущество - величина которая позволяет завысить оценки для локального сервера. Она будет добавлена ко всем серверам кроме локального
byBusyChildren [преимущество] сортирует список кандидатов в соответствии количеством дочерних процессов Apache в состоянии SERVER_BUSY от меньшего к большему
byCPU удаляет все сервера кроме этого в соответствии с временем простоя CPU. Не используйте если вы действительно незнаете почему используете это
byLogWindow выбрасывает все сервера кроме первых log по основанию 2 от n. Если в списке 17 серверов, останется первых 4
byRandom случайно перемешивает список серверов
byCost эта функция пытается определить стоимость выполнения запроса для каждого сервера в кластере и выбирает наиболее дешевый. Метод определения стоимости обсуждается в документе "A cost-Benefit Framework for Online Managment of a Metacomputing System"
HTTPRedirectToIP заставляет mod_backhand использовать пере направление HTTP, вместо стандартного режима Proxy
bySession [идентификатор] эта функция будет пытаться найти печеньку(cookie) или переменную запроса именуемую идентификатором, декодировать первые 8 байт и получить IP адрес. Попробует найти IP адрес в списке серверов и если найдет то оставит в списке только его. Если что-то не получится список останется нетронутым. Эта функция очень полезна для скриптов исполняемых на стороне сервера и может быть использована для нормальной работы приложений использующих пользовательские сессии. По умолчанию идентификатор равен "PHPSESSID="

Можно и самому написать функцию работы с кандидатами, но здесь это обсуждать мы не будем.

2.4 Настройка mod_backhand

Все параметры настройки mod_backhand находятся в файле настроек apache httpd.conf. Их совсем немного, посему давайте остановимся на них подробней.
UnixSocketDir <dir> - директория в которой mod_backhand будет сохранять необходимую для работы информацию. Она должна быть доступна на запись для apache (nobody).
MulticastStats <IP-Addr>:<Port>[,<TTL>] - задает адрес на который сервер отправляет свое состояние. Может быть широковещательным, может уникальным. Разрешается использование нескольких адресов и/или сетей путем использования нескольких директив.
AcceptStats <IP-Addr>/<Netmask> - задает сеть из которой мы будем принимать информацию от других серверов.

2.5 Пример конфигурации

Давайте рассмотрим пример в котором у нас будет 5 серверов.
Один из них будет управляющим. Он не будет сам выполнять работу, а будет отдавать ее другим. Он будет иметь два интерфейса: eth0 - во внешний мир и eth1(ip - 195.5.3.183) - в сеть с кластером(ip - 192.168.10.1).
На остальные четыре сервера ложится основная нагрузка по обработке запросов. Они имеют ip адреса от 192.168.10.2 до 192.168.10.5.
Управляющий сервер будем называть Director, остальные www1 - www4.

cluster's schem

Все системы имеют одинаковые настройки mod_backhand.

<IfModule mod_backhand.c>
  UnixSocketDir /usr/local/apache/backhand
  MulticastStats 192.168.10.255:4445,1
  AcceptStats 192.168.10.0/24
                                                                              
  <Location "/backhand/">
    SetHandler backhand-handler
  </Location>
</IfModule>

Director помимо всего прочего имеет зону покрытия:
<Files ~ "*">
    backhand bySession
    backhand byAge
    backhand removeSelf
    backhand byLoad
</Files>

Все. Наш кластер с балансировкой нагрузки можно использовать.
Конечно если упадет Director то и весь наш кластер будет не доступен. Самое время рассмотреть Wackamole.

3. Wackamole

Wackamole позволяет сделать наш кластер высоко доступным.
Делается это за счет того что wackamole распределяет имеющийся пул виртуальных адресов между несколькими машинами. Таким образом если одна из машин "умрет" остальные тут же подхватят ее виртуальный IP, что позволяет быть каждому отдельному виртуальному IP быть доступным в любое время. Виртуальным IP называются потому что ни одна из машин не "владеют" этим адресом. Он может передоватся от одной к другой. В любой момент времени IP владеет не больше одной машины.

Это позволяет нам использовать множественные DNS RR записи, не беспокоясь о том что серверы могут быть недоступны. Если одна из машин "упадет" виртуальные IP адреса, которыми она владела, распределятся между другими машинами кластера.

3.1 Установка

Wackamole работает используя Spread toolkit. Взять его можно на http://www.pread.org/.
Собираем сначала Spread:

$ cd spread-src-3.17.1
$ ./configure --prefix=/usr/local/spread
$ make
# make install
Следует помнить, что для старта демона spread необходимо наличие пользователя и группы spread т.к. после старта он делает setuid, а также каталог /var/run/spread для chroot в целях безопасности.

А теперь wackamole:

$ cd ../wackamole-2.0.0
$ ./configure --prefix=/usr/local/wackamole --with-cppflags=-I/usr/local/spread/include \
  --with-ldflags=-L/usr/local/spread/lib
$ make all
# make install

Не забудьте, что вы должны обеспечить вызов динамических библиотек из /usr/local/spread/lib.

3.2 Настройка wackamole.conf

Spread - указывает где искать Spread демон. Значение 4803 означает что он будет искаться на локальной машине, на порту по умолчанию для spread.
SpreadRetryInterval - временной промежуток через который wackamole будет пытаться установить связь с Spread если она разорвалась.
Group - указывает Spread группу к которой wackamole присоединится. Эта группа должна быть своя для каждого кластера.
Control - указывает путь к Unix Domain сокету, используемый wackamole.
Arp-cache - указывает время через которое происходит обновление информации в ARP кэше.

Секция balance:
Interval - указывает длину раунда балансировки.
AcquisitionsPerRound - указывает количество виртуальных интерфейсов задействованных в раунде балансировки.

Секция VirtualInterfaces определяет все виртуальные интерфейсы, относящиеся к кластеру. Виртуальный интерфейс может иметь три вида:
1. ifname:ipaddr/mask
2. { ifname:ipaddr/mask }
3. {
    ifname:ipaddr/mask
    ifname:ipaddr/mask
    ...
   }
ifname - имя интерфейса из ifconfig -a, без каких либо виртуальных номеров.

Директива Prefer позволяет указать ip адреса предпочитаемые для этой машины.

Секция Notify описывает каким машинам должны посылаться arp-spoof'ы когда IP адрес передается машине. IP адреса в секции задаются подобно секции VirtualInterfaces.

3.2 Пример настройки

У нас есть четыре Linux сервера с запущенным Apache, содержащим картинки для большого web сайта. У них ip от 192.168.100.183 до 192.168.100.186. Для них выделены 4 виртуальных IP, по которым и будет происходить доступ к картинкам - 192.168.100.200 - 192.168.100.203. Все они должны откликаться на images.example.com. Spread установлен на всех машинах и висит на порту 4803. Каждая машина имеет по одному интерфейсу - eth0. Default route для всех - 192.168.100.1
Wackamole.conf на каждой машине должен выглядеть следующим образом:
Spread = 4803
SpreadRetryInterval = 5s
Group = wack1
Control = /var/run/wack.it

Mature = 5s
Balance {
    AcquisitionsPerRound = all
    Interval = 4s
}
Arp-Cache = 90s
Prefer none
VirtualInterfaces {
    { eth0:192.168.100.200/24 }
    { eth0:192.168.100.201/24 }
    { eth0:192.168.100.202/24 }
    { eth0:192.168.100.203/24 }
}

Notify {
    eth0:192.168.100.1/32
    arp-cache
}

4. А теперь все вместе

В заключение рассмотрим пример который объединяет все выше сказанное.
В нашем кластере будет участвовать 7 машин. Две из них будут:
1) распределять пул из четырех виртуальных IP (195.5.3.180 - 195.5.3.183) откликающихся на www.samplesite.com.
2) балансировать нагрузку между остальными пятью машинами, сами не выполняя запросов.
Остальные пять машин будут заниматься непосредственно предоставлением web ресурсов.

web cluster example scheme

На первых двух машинах установлен и wackamole и apache+mod_backhand, шлюз по умалчанию 192.168.100.1, постоянные IP(привязанные к интерфейсу) - 192.168.100.101, 192.168.100.102. Файлы настроек для них выглядят следующим образом:
wackamole.conf:
Spread = 4803
SpreadRetryInterval = 5s
Group = wack1
Control = /var/run/wack.it

Mature = 5s
Balance {
    AcquisitionsPerRound = all
    Interval = 4s
}
Arp-Cache = 90s
Prefer none
VirtualInterfaces {
    { eth0:195.5.3.180/24 }
    { eth0:195.5.3.181/24 }
    { eth0:195.5.3.182/24 }
    { eth0:195.5.3.183/24 }
}

Notify {
    eth0:192.168.100.1/32
    arp-cache
}

mod_backhand (httpd.conf):

<IfModule mod_backhand.c>
  UnixSocketDir /usr/local/apache/backhand
  MulticastStats 192.168.100.255:4445,1
  AcceptStats 192.168.100.0/24

  <Location "/backhand/">
    SetHandler backhand-handler
  </Location>
</IfModule>

<Files ~ "*">
    backhand bySession
    backhand byAge
    backhand removeSelf
    backhand byLoad
</Files>

Остальные пять машин умеют ip 192.168.100.50 - 192.168.100.55. На них установлен только apache+mod_backhand cо следующими настройками:

mod_backhand (httpd.conf):

<IfModule mod_backhand.c>
  UnixSocketDir /usr/local/apache/backhand
  MulticastStats 192.168.100.255:4445,1
  AcceptStats 192.168.100.0/24

  <Location "/backhand/">
    SetHandler backhand-handler
  </Location>
</IfModule>

Естественно все 5 машин должны предоставлять схожие web-ресурсы.

Все. Вам осталось, для проверки, только пощелкать кнопками выключения питания у некоторых компьютеров и посмотреть на результаты web-benchmark'а.

Балансировка нагрузки на веб-сайт

DNS

Самый простой способ балансирования нагрузки и распределения запросов между веб-серверами - использование механизма round robin DNS.
Спецификация стандарта DNS позволяет указать несколько разных IN A записей для одного имени. Например:
www  IN A  10.0.0.1 
www  IN A  10.0.0.2
В этом случае DNS-сервер в ответ на запрос разрешения имени в IP-адрес будет выдавать не один адрес, а весь список:
# host www.domain.local 
www.domain.local has address 10.0.0.1 
www.domain.local has address 10.0.0.2
При этом с каждым новым запросом последовательность адресов в списке в ответе будет меняться. Таким образом клиентские запросы будут распределяться между разными адресами и будут попадать на разные серверы.
Использование round robin DNS - самый простой способ балансировки нагрузки, не требующий никаких дополнительных средств, однако он обладает целым рядом недостатков, поэтому мы рекомендуем использовать его только в том случае, если нет возможности применить какой-либо иной балансировщик.
Минусы применения round robin DNS:
  • нет четкого критерия выбора IP из списка клиентом (может выбираться первый элемент, может кэшироваться последнее выбранное значение, возможны иные варианты): все зависит от реализации конкретного клиента;
  • нет механизмов определения доступности узлов и возможности задания их "весов": в случае аварии на одном или нескольких узлах кластера нагрузка будет продолжать распределяться между рабочими и вышедшими из строя нодами;
  • длительное время кэширования ответов DNS: в случае аварии и изменении тех или иных записей в DNS потребуется некоторое время (зависит от настроек DNS) для обновления данных на всех клиентах.

nginx

Рассмотрим пример использования в качестве балансировщика http-сервера nginx. Для этих целей используется модуль ngx_http_upstream.
При использовании "1С-Битрикс: Веб-окружения" nginx уже установлен на серверах веб-кластера. И для распределения нагрузки можно использовать непосредственно один из серверов кластера. Однако для более простого, гибкого и удобного конфигурирования лучше использовать отдельный сервер с установленным nginx в качестве балансировщика.
В простейшем примере фрагмент конфигурационного файла nginx (/etc/nginx/nginx.conf), обеспечивающего распределение нагрузки между серверами, будет выглядеть так (помимо стандартных директив, определяющих, например, пути и формат log-файлов и т.п.):
http { 
    upstream backend { 
        server node1.demo-cluster.ru; 
        server node2.demo-cluster.ru; 
    } 

    server { 
        listen   80; 
        server_name  load_balancer; 

        location / { 
            proxy_set_header X-Real-IP $remote_addr; 
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
            proxy_set_header Host $host:80; 

            proxy_pass  http://backend; 
        } 

    } 
}
В секции upstream задаются адреса серверов, между которыми будет распределяться нагрузка.
В DNS имя сайта указывается на тот IP, на котором работает сервер с nginx, распределяющем нагрузку.
Если не указаны какие-либо дополнительные параметры, запросы распределяются между серверами по принципу round robin.
Однако с помощью модуля ngx_http_upstream можно реализовать и более сложные конфигурации.
  • В некоторых случаях бывает удобно передавать все запросы от одного клиента на один и тот же сервер, а между серверами распределять только запросы разных клиентов. Для реализации подобного функционала служит директива ip_hash. Пример:
    upstream backend 
    { 
        ip_hash; 
    
        server node1.demo-cluster.ru; 
        server node2.demo-cluster.ru; 
    }
    
    В этом случае распределение запросов основано на IP-адресах клиентов.
  • Если для узлов кластера используются серверы разной конфигурации (разной мощности), бывает полезно задать "вес" для тех или иных хостов, направляя на них больше или меньше запросов. Для этого служит параметр weight директивы server. Пример:
    upstream backend 
    { 
        server node1.demo-cluster.ru weight=3; 
        server node2.demo-cluster.ru; 
        server node3.demo-cluster.ru; 
    }
    
    В такой конфигурации каждые 5 запросов будут распределяться следующим образом:
    • 3 - на node1.demo-cluster.ru;
    • 1 - на node2.demo-cluster.ru;
    • 1 - на node3.demo-cluster.ru.
    Обратите внимание: для серверов, использующих метод распределения ip_hash, нельзя задать вес.
  • Можно настроить параметры, по которым будут определяться неработающие серверы. max_fails = число - задает число неудачных запросов к серверу в течение времени, заданного параметром fail_timeout, после которых он считается неработающим также в течение времени заданного параметром fail_timeout;
    fail_timeout = время Пример:
    upstream backend 
    { 
        server node1.demo-cluster.ru max_fails=3 fail_timeout=30s; 
        server node2.demo-cluster.ru max_fails=3 fail_timeout=30s; 
    }
    
    Если при запросе к серверу произошла ошибка, запрос будет передан на следующий сервер. Если произошло 3 ошибки в течение 30 секунд, то на 30 секунд сервер будет помечен неработающим, и в течение этого времени новые запросы не будут на него отправляться.

Устновка proxmox Debian x64

Устанавливаем Proxmox VE на Debian Squeeze(amd64)


Вообще хочется отметить что Proxmox VE проще установить из специально подготовленного ISO-файла, но в некоторых случаях, например если у вас файл хранилище более 2Тб, это ограничение MBR. Если у вас диск на 3Тб либо RAID большего объёма, вам придётся использовать файловую таблицу GPT а соответственно ставить голую систему на которую придётся накатить Proxmox в ручную.

Почему именно Proxmox?
  1. Возможность использования как KVM так и OpenVZ.
  2. Web vnc-client.
  3. Возможность кластеризации.
  4. Неплохая система бэкапов виртуальных машин.

Установка



Для начала пропишем репозитарий.
cat >> /etc/apt/sources.list <<EOF
# PVE packages provided by proxmox.com
deb http://download.proxmox.com/debian squeeze pve
EOF

wget -O- "http://download.proxmox.com/debian/key.asc" | apt-key add -

apt-get update
Обновим систему.
apt-get update
apt-get autoremove
apt-get dist-upgrade -y
Теперь установим ядро Proxmox VE.
apt-get install \
 `apt-cache search pve-kernel | egrep -E \
 "^pve-kernel-|\-pve\ \-\ The\ Proxmox\ PVE\ Kernel\ Image" \
 | awk '{ print $1 }' | head -n1` -y
и если хотите так сказать опционально headers.
apt-get install \
 `apt-cache search pve-headers | egrep -E \
 "^pve-headers-|\-pve\ \-\ The\ Proxmox\ PVE\ Kernel\ Image" \
 | awk '{ print $1 }' | head -n1` -y
Теперь перезагрузимся, и удостоверимся что загрузилось нужное нам ядро.

uname -r
2.6.32-6-pve

Настало время установки самого Proxmox VE.
apt-get install \
 `apt-cache search proxmox-ve | egrep -E \
 "^proxmox-ve-|\-\ The\ Proxmox\ PVE\ Kernel\ Image" \
 | awk '{ print $1 }' | head -n1` -y
Подключим VirtualHost pve-redirect в apache2
a2ensite pve-redirect.conf
Enabling site pve-redirect.conf.
Run '/etc/init.d/apache2 reload' to activate new configuration!

И перезапустим apache2
/etc/init.d/apache2 restart
Restarting web server: apache2 ... waiting .
Установим еще несколько полезных программ и сервисов.
apt-get install ntp ssh lvm2 postfix ksm-control-daemon vzprocps -y
При установке Postfix задаст пару вопросов, я предпочёл ответить так:


По окончании операции можно подключиться к WEB интерфейсу, в моём случае http://192.168.0.109, он меня автоматом редиректит на https://192.168.0.109:8006/#v1:0:18:4:::::

Залогинимся используя root-овую учётную запись

 из новшеств, появилась консоль сервера
так же если ваше хранилище данных находится в месте отличном от /var/lib/vz советую указать его в ручную.
Теперь чтобы виртуальные машины видели локальную сеть, добавим наш сетевой интерфейс в моём случае eth0 в бридж(vmbr0), и перенесём на него ip адрес.
Эти изменения применяться после перезагрузки.

virsh

virsh(1).

Приведен вольный перевод man-страницы virsh, дополненый переводом man’а идущего в дистрибутиве libvirt-0.7.6-r1 и данные из help’а самого virsh. Утилита virsh является основным интерфейсом для управления виртуальными окружениями и сетями, пулами хранения данных, сетевыми интерфесами и различными объектами виртуальной инфраструктуры.

Общий синтаксис
virsh <subcommand> [args]
Утилита virsh является основным интерфейсом для управления гостевыми доменами. Программа может использоваться для создания, приостановки и выключения гостевых окружений. Также можно просмотреть список существующих доменов и различную статистическую информацию. Взаимодествие осуществляется через Libvirt  – набор программ и библиотек для работы с возможностями виртуализации последних версий Linux (и других ОС). Виртуализация в ОС Linux подразумевает возможность одновременного запуска нескольких независимых друг от друга инстанций различных ОС на одном аппаратном обеспечении, где основные ресурсы находятся под управлением Linux. Libvirt способен работать как с Xen так и с QEmu и KVM.
Основная структура команды выполнит следующим образом:
virsh <command> <domain-id> [OPTIONS]
где command это одна из подкоманд, domain-id это числовой идентификационный номер домена или его имя (которое может быть автоматически транслировано в id), и OPTIONS это дополнительные параметры специфичные для каждой команды. Правда есть несколько исключений из этого правила, в основном это относится к командам применительных для всех доменов, на всю машину или непосредственно на гипервизор. Virsh может быть запущена без параметров, как самостоятельная оболочка в которой можно будет выполнять встроенные команды. Все операции virsh отдаются на выполнение libvirt который в свою очередь обращается к xend/qemu или любой другой системе виртуализации (которую он поддерживает). Учитывая это, следует при загрузке запустить службу xend/qemu, обычно это делается с помощью команды service start libvirtd (для RHEL/Fedora/CentOS). Большинство команд virsh требуют прав root для общения с гипервизором, поэтому команды выполненые из под непривилегированной учетной записи завершатся с ошибкой. Также стоит отметить что выполнение некоторых команды virsh занимает некоторое время (от 30 секунд и более) такие как создание или выключение. Поэтому когда оболочка вернула приглашение для ввода следующей команды, это не значит что операция инициированая предыдущей командой уже завершилась, поэтому периодически следует выполнять ‘virsh list’ для проверки состояния системы.
1. Общие команды. Следующие команды являются базовыми.
help – вывод списка доступных команд, help <command> выведет справку по конкретной программе;
quit – выход из virsh-терминала;
version – отображает версию ПО и версию используемого гипервизора;
connect URI [––readonly] – (пере-)подключиться к гипервизору. Это команда является встроенной и запускается сразу после старта virsh-шелла. Параметр URI может принимать следующие аргументы:
xen:/// – подключиться к xen гипервизору;
qemu:///system – подключиться к службе которая управляет QEmu\KVM-доменами и запущена из под root;
qemu:///session – подключиться к службе которая управляет QEmu\KVM-доменами и запущена из под непривилегированного пользователя.
c дополнительным параметром –readonly выполняется read-only подключение.
hostname – выводит имя хост-системы;
nodeinfo – выводит основную информацию об аппаратных характеристиках хост-системы (cpu, mem, sockets);
capabilities – вывод XML-документа в котором перечислены характеристики гипервизора к которому выполнено подключение;
list [ ––inactive | ––all ] – вывод информации о гостевых доменах. Без параметров выводит информацию о запущенных доменах;
freecell [cellno] – выводит количество свободно памяти хост-системы.
2. Команды применительные к доменам. Следующие команды позволяют напрямую управлять доменами. Большинство команд требуют в качестве первого параметра id домена. ID домена может быть указан в виде имени либо в виде полного значения UUID.
autostart [––disable] <domain-id> – включить автозапуск домена при загрузке. Опция ––disable отключает автозапуск;
console <domain-id> – подключиться к консоли гостевого домена;
create <FILE> – создать домен из XML-файла. Эта команда запускает домен описаный в файле, НО не сохраняет его конфигурацию; конфигурация исчезнет после выключения домена;
define <FILE> – назначить домен из XML-файла. Будет создано описание домена, но сам домен не будет запущен;
destroy <domain-id> – немедленно завершить работу гостевого домена. Эта команда не дает никакой возможности среагировать ОС запущенной в госте, это эквивалентно выдергиванию шнура питания из физической машины. В большинстве случаев вместо нее можно использовать команду shutdown;
domblkstat <domain-name> <block-device> – получить статистику блочных устройств устройств для домена;
domifstat <domain-name> <interface-device> – получить статистику сетевого интерфейса для домена;
dominfo <domain-id> – вывод информации о домене;
domuuid <domain-name-or-id> – конвертация ID домена или его имени в полный UUID;
domid <domain-name> – конвертация доменного имени в ID;
domname <domain-id> – конвертация ID домена в имя;
domstate <domain-id> – вывод состояния указанного домена;
dump <domain-id> <corefilepath> – выполнить дамп ядра гостя в файл для последующего анализа;
dumpxml <domain-id> – вывод информации о домене в XML-формате. Этот формат должен использоваться в командах create и define;
edit <domain-id> – редактировать XML-файл с конфигурацией домена;
migrate [––live] <domain-id> <desturi> <migrateuri> – мигрировать домен на другой хост. Параметр –live применяется для живой миграции. desturi это URI хост-системы назначения, и migrateuri это URI миграции, который обычно опускают;
reboot <domain-id> – перезагрузить домен. Действие аналогичное если бы команда reboot была введена в консоли гостя;
save <domain-id> <state-file> - сохранение запущенного домена в файл, из которого он может быть восстановлен позднее. Однажды сохраненный, домен остается выключенным и высвобожденная память может быть использована для нужд других доменов. Команда virsh restore восстанавливает состояние машины. Это действие эквивалентно процессу hibernate на запущенной машине, со всеми ее ограничениями, например открытые сетевые соединения будут восстановлены, но TCP-таймауты будут истекшими;
restore <state-file> – восстанавливает домен из сохраненного в файл состояния;
schedinfo [––set <parameter=value>] [––weight <number>] [––cap <number>] <domain-id> – просмотр/установка параметров планировщика в домене;
setmem <domain-id> <kilobytes> – изменить текущее выделение памяти в гостевом домене. Действие немедленно вступает в силу. Значение указывается в килобайтах;
setmaxmem <domain-id> <kilobytes> – изменить максимальное значение выделенной памяти для гостевого домена. Это не меняет текущее использование памяти в домене. Значение указывается в килобайтах;
setvcpus <domain-id> <count> – изменить количество виртуальных процессоров в гостевом домене. Значение может быть ограничено хост-системой, гипервизором или оригинальной конфигурацией домена;
shutdown <domain-id> – выключить домен. Гостевая ОС выполняет завершение работы, однако успешное завершение не гарантируется, это зависит длины времени которое уходит на остановку служб в домене;
start <domain-name> – запустить (предварительно назначеный) неактивный домен;
suspend <domain-id> – приостановить запущенный домен. Он держится в памяти, но останавливает свою работу;
resume <domain-id> – запускает остановленный ранее домен. Позволяет передать гипервизору ранее остановленный домен для продолжения работы;
ttyconsole <domain-id> – показать устройство используемое в качестве TTY консоли домена;
undefine <domain-id> – удалить конфигурацию неактивного домена;
vcpuinfo <domain-id> – возвращает информацию о виртуальных процессорах домена, такую как количество, время работы и привязку к физическим процессорам;
vcpupin <domain-id> <vcpu> <cpulist> – назначить виртуальный процессоры к физическим процессорам. Должен быть определен параметр vcpu, cpulist это список физических процессоров перечисленных через запятую (нумерация с нуля);
vncdisplay <domain-id> – вывод информации о ip-адресе и номере VNC-дисплея.
3. Команды для работы с устройствами. Следующие команды управляют связанными с доменом устройствами. ID домена может быть указан в виде имени либо в виде полного значения UUID. Чтобы лучше понять разрешенные значения в параметрах команд, прочтите документацию о формате секции устройств.
attach-device <domain-id> <FILE> – подключить устройство к домену, используя описание устройства из XML-файла;
attach-disk <domain-id> <source> <target> [––driver <driver>] [––subdriver <subdriver>] [––type <type>] [––mode <mode>] – добавить блочное устройство в домен:
<source> и <target> определяет пути к файлам и устройствам;
––driver может быть file, tap или phy в зависимости от типа доступа;
––type может быть cdrom или floppy в отличие от значения disk по умолчанию;
––mode может быть readonly или shareable(доступное для записи).
attach-interface <domain-id> <type> <source> [––target <target>] [––mac <mac>] [––script <script>] – добавить новый сетевой интерфейс в гостевой домен:
<type> может быть network(физическое подключение к сети) или bridge(подключение к сети через мостовое соединение);
<source это само устройство;
––target это целевое устройство в гостевом домене;
––mac позволяет определить mac-адрес;
––script позволяет указать путь к скрипту вместо использующегося по умолчанию;
detach-device <domain-id> <FILE> – отключить устройство от домена. Необходимо тоже XML-описание как и при использовании attach-device;
detach-disk <domain-id> <target> – отключить диск от домена. target это устройство видимое в гостевом домене;
detach-interface <domain-id> <type> [––mac <mac>] – отключить сетевой интерфейс от домена. type может быть network(физическое подключение к сети) или bridge(подключение к сети через мостовое соединение). Если в системе несколько интерфейсов, рекомендуется использовать опцию mac чтобы отличить их.
4. Команды управления виртуальным сетевым окружением. Следующие команды позволяют управлять виртуальными сетями. Libvirt способен назначать виртуальные сетевые окружения которые могут использоваться доменами и могут быть сассоциированы с физическими интерфейсами. Для более детальной информации можно прочесть документацию. Некоторые команды для виртуальных сетей, подобны командам используемыми для доменов и соответственно в параметрах, виртуальную сеть можно также назвать по имени или по ее UUID.
net-autostart <network> [––disable] – включить автозапуск виртуальной сети в при загрузке. Параметр ––disable отключает автозапуск;
net-create <FILE> – создать виртуальную сеть из XML-файла;
net-define <FILE> – назначить сеть из XML-файла, но не запускать ее;
net-destroy <network> – удалить сеть. Действие вступает в силу незамедлительно;
net-dumpxml <network> – вывести информацию о виртуальной сети в XML-формате;
net-edit <network> – редактировать XML-файл с опсианием сети;
net-list [––inactive | ––all] – вывести список активных виртуальных сетей. ––all отображает все сети, ––inactive отображает только неактивные;
net-name <network-UUID> – конвертация UUID сети в ее имя;
net-start <network> – запустить (назначенную ранее) неактивную сеть;
net-undefine <network> – удалить конфигурацию неактивной сети;
net-uuid <network> – конвертация имени сети в ее UUID.
5. Команды управления “секретом”.  Следующие команды управляют “секретом” (пароли, секретные фразы, ключи шифрования). Libvirt может хранить секретные данные независимо от их использования и другие объекты (тома или домены) могут использовать их или ссылаться на них. Секреты индентифицируются посредством UUID. Описание XML-формата приведено здесь.
secret-define <FILE> – назначить секрет из XML-файла без ассоциации с секретным значением;
secret-dumpxml <secret> – вывод параметров секрета в XML-формате;
secret-set-value <secret> <base64> – установка значения связанного с секретом (секретную информацию предварительно нужно закодировать в base64);
secret-get-value <secret> – вывести значение секрета закодированное в base64;
secret-undefine <secret> – удалить секрет вместе с ассоциированым значением;
secret-list – вывести список секретов.
6. Команды управления сетевыми интерфейсами. Стоит отметить, чтобы эти функции исправно работали необходимо чтобы в системе был установлен пакет netcf и libvirt был собран с поддержкой netcf.
iface-list [––inactive|––all] – просмотреть список физических сетевых интерфейсов;
iface-name <interface> – конвертация mac-адреса интерфейса в его имя;
iface-mac <interface> – конвертация имени интерфейса в mac-адрес;
iface-dumpxml <interface> – вывод информации о сетевых интерфесах в XML-формате;
iface-define <FILE> – назначить (но не запускать) сетевой интерфейс из XML-файла;
iface-undefine <interface> – удалить конфигурацию сетевого интерфейса;
iface-edit <interface> – редактировать конфигурацию сетевого интерфейса;
iface-start <interface> – запустить сетевой интерфейс;
iface-destroy <interface> – остановить сетевой интерфейс.
7. Команды управления физическими устройствами. Следующие команды позволяют пробрасывать физические устройства в виртуальные окружения.
nodedev-list [––tree] [––cap <string>] – просмотреть список доступных устройств;
nodedev-dumpxml <device> – вывод информации о устройстве в XML-формате;
nodedev-dettach <device> – отключить драйвер от устройства, перед последующим включением устройства в домен;
nodedev-reattach <device> – подключить драйвер к устройству после его извлечения из домена;
nodedev-reset <device> – выполнить сброс устройства, перед его включением в домен, или наоборот после извлечения;
nodedev-create <FILE> – создать устройство из XML-файла. Эта команда включает устройство, в виртуальную машину;
nodedev-destroy <name> – удалить устройство из виртуальной машины.
8. Команды управления пулами хранения. Пулы хранения могут использоваться для хранения виртуальных дисков гостевых систем. Подробнее здесь.
pool-autostart <pool> [––disable] – запускать пул автоматически при загрузке системы. Параметр “––disable” отключает автозапуск;
pool-build <pool> – построить новый пул;
pool-create <FILE> – создать новый пул из XML-файла;
pool-create-as <name> [––print-xml] <type> [<source-host>] [<source-path>] [<source-dev>] [<source-name>] [<target>] – создать новый пул с набором параметров:
<name> – имя пула;
––print-xml - напечатать XML-формат, но не назначать и не создавать конфигурацию;
<type> – тип создаваемого пула;
<source-host> – хост-источник для создаваемого хранилища (например localhost);
<source-path> - путь-источник для хранилища;
<source-dev> – устройство-источник для хранилища;
<source-name> – имя-источника для хранилища;
<target> – путь к хранилищу.
pool-define <FILE> – назначить (но не запускать) пул из XML-файла;
pool-define-as <name> [––print-xml] <type> [<source-host>] [<source-path>] [<source-dev>] [<source-name>] [<target>] – создать пул с набором параметров:
<name> – имя пула;
––print-xml – напечатать XML-формат, но не назначать и не создавать конфигурацию;
<type> – тип создаваемого пула (dir, fs, netfs, logical, disk, scsi, iscsi, mpath);
<source-host> – хост-источник для создаваемого хранилища;
<source-path> – путь-источник для хранилища;
<source-dev> – устройство-источник для хранилища;
<source-name> - имя-источника для хранилища;
<target> – путь к хранилищу.
pool-destroy <pool> – остановить указанный пул;
pool-delete <pool> – удалить пул;
pool-dumpxml <pool> – вывести информацию о пуле в XML-формате;
pool-edit <pool> – редактировать XML-конфигурацию пула;
pool-info <pool> – вывести информацию о пуле;
pool-list [––inactive|––all] – вывести список пулов;
pool-name <uuid> – конвертация UUID пула в его имя;
pool-refresh <pool> – обновить состояние пула;
pool-start <pool> – запустить (предварительно назначеный) неактивный пул;
pool-undefine <pool> – удалить конфигурацию неактивного пула;
pool-uuid <pool> – конвертация имени пула в его UUID.
9. Команды управления томами. Тома используются в качестве виртуальных дисков в гостевых системах.
vol-create <pool> <FILE> – создать том из XML-файла в указанном пуле;
vol-create-from <pool> <FILE> [––inputpool <string>] <vol> – создать том, в указанном пуле;
vol-create-as <pool> <name> <capacity> [––allocation <string>] [––format <string>] – создать том с набором параметров, размер определяется суффиксами k, M, G, T; типы форматов:
raw – обычный файл
bochs – формат образа диска Bochs
cloop – формат сжатого loopback образа диска
cow – формат User Mode Linux
dmg – Mac формат
iso – CDROM формат
qcow – QEMU v1 формат
qcow2 – QEMU v2 формат
vmdk – VMWare формат
vpc – VirtualPC формат
vol-clone [––pool <string>] <vol> <newname> – клонировать существующий том;
vol-delete [––pool <string>] <vol> – удалить указанный том;
vol-dumpxml [––pool <string>] <vol> – вывести информацию о томе в XML-формате;
vol-info [––pool <string>] <vol> – вывести основную информацию о томе;
vol-list <pool> – вывести список томов в указанном пуле;
vol-path [––pool <string>] <vol> – показать путь к тому используя его имя;
vol-name <path> – сконвертировать путь тома в его имя (ориг.текст – convert a vol UUID to vol name);
vol-key <vol> – сконвертировать UUID тома в его имя. (не совсем понятно где взять UUID в XML-описании я его не увидел).
Авторами оригинальных текстов являются Andrew Puch, Daniel Veillard, Sean Dague (xm man page) и Daniel Stekloff.
Примеры:
назначить и запустить пул ‘test’ типа ‘dir’ размещенный в каталоге /var/pooldir (каталог находится на устройстве /dev/volgroup00/var)
virsh> pool-create-as testpool dir localhost /var/pooldir /dev/volgroup00/var testpool /var/pooldir
virsh> pool-autostart testpool
создать том c именем server01-sdb, в пуле testpool, размером 8 Гб с форматом raw
virsh> vol-create-as testpool server01-sdb 8G ––format raw
подключить файл /var/testpool/server01-sdb к гостевой машине server01, как дополнительный диск sdb
virsh> attach-disk server01 /var/testpool/server01-sdb sdb ––driver file ––type disk

Настройка NTP в Debian

Проблема: Всё вроде было хорошо, всё работало - и тут вы замечаете, что часы на разных компьютерах показывают разное время. Что делать?
Решение: ставим программу ntp, позволяющую быстро синхронизировать часы локального компьютера с серверами точного времени, подсоединёнными ко Всемирной Паутине. Теперь ваши часы в Linux будут всегда показывать точное время, синхронизированное с атомными часами.

Быстро синхронизируем время
Сначала нам бы однократно синхронизировать часы, а уж потом думать о том, как это свалить на компьютер. В Debian GNU/Linux это делается (как и всё прочее) очень просто. Ставим пакеты:

#apt-get install ntp ntpdate
Теперь выбираем сервер точного времени, поближе к вам и не очень загруженный. Список таких серверов можно посмотреть здесь. После чего сервер времени (вместо указанного сервера можно выбрать другой из списка) не мешало бы пощупать:
# ntpdate ntp.remco.org
На что он ответит примерно следующее:
18 Aug 17:32:35 ntpdate[3558]: step time server 80.127.4.179 offset -358.420872 sec
То есть насколько наши часы отстают от правильных. Это мы сейчас устраним. Теперь однократно синхронизируемся с часами на сервере точного времени:
# ntpdate -bs ntp.remco.org
Всё, ваши часы теперь идут точно.
Опять-таки, кроме этого сервера есть ещё куча других, выбирайте ближайший к вам.

Сваливаем синхронизацию времени на компьютер
В принципе, для отдельно стоящей машины можно написать простенький скрипт и запускать время от времени. Дело в том, что если ставить ntp-server на локальной машине, он будет каждый раз при загрузке пытаться связаться с сервером точного времени. Это чревато увеличением времени загрузки на минуту, а то и более. Если уж так хочется - ищем в районе прямой видимости UNIX-машину, постоянно подключенную к Интернету, и ставим сервер туда, а потом используем её как локальное зеркало точного времени.
Ставим пакет:

#apt-get install ntp-server
После этого лезем в конфиг /etc/ntp.conf и прописываем там правильное зеркало точного времени, например:
server ntplocal.example.com prefer
server timeserver.example.org
server ntp2a.example.net
А можно не лазить, настройки по умолчанию (в Debian, по крайней мере) разумны. При следующей перезагрузке / перезапуске ntp ваши часы снова синхронизируются.

Ссылки:
Краткая справка по настройке возможности получения точного времени здесь. Стоит почитать замечательную статью Линукс, Часы и Время и FreeBSD-шное руководство, в котором, в частности, сделан упор на "серверную" часть ntp.