Как стать автором
Обновить

Виртуализация с OpenVZ

Время на прочтение 9 мин
Количество просмотров 90K


На Хабре есть много статей о том, что контейнерная виртуализация — это плохо или хорошо, но пошаговой интструкции по ее установке и настройке мне найти не удалось. Постараюсь заполнить этот пробел.

Виртуализация — очень актуальная тема, так как позволяет более рационально использовать ресурсы сервера. И, признаюсь, мне было очень приятно познакомиться с OpenVZ.

OpenVZ — это реализация технологии виртуализации на уровне операционной системы, которая базируется на ядре Linux. OpenVZ позволяет на одном физическом сервере запускать множество изолированных копий операционной системы, так называемых контейнеров (Virtual Environments, VE).

Поскольку OpenVZ базируется на ядре Linux, в роли «гостевых» систем могут выступать только дистрибутивы GNU/Linux. Однако виртуализация на уровне операционной системы в OpenVZ дает также и многие преимущества, а именно: удобство в администрировании, плотное размещения виртуальных контейнеров в хост-системе (это обычно положительно отражается на стоимости VPS-хостинга) и несколько лучшую производительность по сравнению с технологиями полной виртуализации.

Конечно, и недостатков достаточно. Главный из них, что в отличие от KVM, модули OpenVZ не входят в ванильное ядро, поэтому для фунционування последнего необходимо отдельное ядро и версия его далеко не последняя. На момент публикации этой статьи последняя стабильная версия — 2.6.32-042stab084.14. Из этого по сути следует, что хост-системой на OpenVZ может выступать не каждый дистрибутив, а только с ядром 2.6.32 и около версии. Поэтому, скажем, OpenVZ — ядро под Ubuntu 12.04 LTS вряд ли заведется (что я уже попробовал), ведь ядро здесь версии 3.8. Но не все так плохо, так как для RedHat 6 (CentOS 6, Scientific Linux 6) и Debian 7 все просто устанавливается и эти дистрибутивы официально поддеживаются Parallels.

Следующий недостаток в том, что все контейнеры работают под одним ядром (ядром хост-системы) и добавить необходимый модуль ядра уже будет не так просто, как в случае с технологиями полной виртуализации. В результате на OpenVZ-контейнерах не сможет работать NFS-сервер или другие сервисы, которым необходима тесная интегрирация с ядром. О некоторых других недостатках и преимуществах систем виртуализации можно почитать например здесь.

Теория без практики — мертва, поэтому самое время описать установку и настройку хост-системы для OpenVZ. В качестве хост-системы я выбрал CentOS 6.5. Добавляем репозитории для установки ядра OpenVZ и утилит для работы с контейнерами:

# wget -P /etc/yum.repos.d/  http://ftp.openvz.org/openvz.repo
# rpm --import http://ftp.openvz.org/RPM-GPG-Key-OpenVZ

Устанавливаем ядро и утилиты:

# yum install vzctl vzquota ploop

Официальный мануал говорит, что с vzctl от версии 4.4 настройки параметров ядра ( /etc/sysctl.conf ) не обязательно.

Перегружаемся и проверяем версию ядра:

# uname -a
Linux centos 2.6.32-042stab084.14 # 1 SMP Mon Dec 16 18:16:56 MSK 2013 x86_64 x86_64 x86_64 GNU/Linux

Если версия такая же — то все сделано верно, иначе следует проверить какое именно ядро загружает GRUB. Переходим к созданию контейнера:

# vzctl create 103 --ostemplate debian-7.0-x86_64 --config vswap-2g

- 2014-01-14 16:54:54 - http://download.openvz.org/template/precreated/debian-7.0-x86_64.tar.gz
Resolving download.openvz.org ... 199.115.104.11 , 2620 : e6 :: 104:11
Connecting to download.openvz.org | 199.115.104.11 | 80 ... connected .
HTTP request sent , awaiting response ... 200 OK
Length: 303736979 ( 290M ) [ application / x - gzip ]
Saving to : ` /vz/template/cache/debian-7.0-x86_64.tar.gz '

43 % [ =========================== >] 132,616,648 2.17M / s eta 2m 1s

Темплейт для создания контейнера с Debian 7 будет загружен с сайта OpenVZ и установлен.

# vzlist -a
      CTID NPROC STATUS IP_ADDR HOSTNAME
       103      -        stopped        -

Зададим конфигурацию новому контейнеру:

# vzctl set 103 --onboot yes --save # добавляем контейнер в автозагрузку после старта хост-системы
# vzctl set 103 --hostname debian7.example.com - save # задаем хостнейм
# vzctl set 103 --save --ipadd 192.168.1.31 # назначаем IP , установка VENET - соединения
# vzctl set 103 --save --nameserver 8.8.8.8 -nameserver 8.8.4.4 # описываем DNS - сервера
# vzctl set 103 --save --cpus 4 # кол-во cpu-ядер
# vzctl set 103 --save --ram 8G # RAM
# vzctl set 103 --save --swap 4G # swap
# vzctl set 103 --save --diskspace 100G # задание размера диска
# vzctl start 103 # запускаем контейнер
# vzctl exec 103 passwd # устанавливаем пароль root-пользователю

Таким образом был создан контейнер на Debian 7. Для связи с внешним миром было настроено VENET-соединения.

В дальнейшем можно несколько исправить конфигурацию контейнера, отредактировав конфигурационный файл:

# vim /etc/vz/conf/103.conf

# RAM
PHYSPAGES = " 0:2097152 "

# Swap
SWAPPAGES = " 0:1048576 "

# Disk quota parameters ( in form of softlimit : hardlimit )
DISKSPACE = " 104857600:104857600 "
DISKINODES = " 200000:220000 "
QUOTATIME = "0"

# CPU fair scheduler parameter
CPUUNITS = "1000"
VE_ROOT = "/vz/root/$VEID"
VE_PRIVATE = "/vz/private/$VEID"
OSTEMPLATE = "debian-7.0-x86_64"
ORIGIN_SAMPLE = "vswap-2g"
ONBOOT = "yes"
HOSTNAME = "debian7.example.com"
NETIF = "ifname = eth0 , mac = 00:18:51:CF:E9:09 host_ifname = veth104.0 , host_mac = FE:FF:FF:FF:FF:FF"
NAMESERVER = "8.8.8.8 8.8.4.4"
CPUS = " 4"

Физически контейнер находится по адресу /vz/private/103:

# cd /vz/private/103
# ls
bin dev home lib64 media opt root sbin srv tmp var
boot etc lib lost + found mnt proc run selinux sys usr

Если контейнер работает, то все изменения лучше добавлять используя путь /vz/root/103, который синхронизируется с /vz/private/103.

OpenVZ имеет возможность настройки VETH (Virtual ETHernet) или VENET (Virtual NETwork) сетевого девайса внутри контейнера. VETH позволяет broadcasts-сообщения внутри контейнера и имеет MAC — адрес на интерфейсе, поэтому можно настроить автоматическое получение адреса с помощью DHCP или настроить Samba — сервер, который также требует broadcasts-сообщений. VETH-интерфейс только задается с помощью vzctl, все дальнейшее настройки интерфейса ( задания IP, gateway и др.) необходимо проводить в самом контейнере. Однако, скорее всего, VENET-соединения будет более чем достаточно. К преимуществам последнего можно отнести высокую скорость работы по сравнению с VETH и быструю его настройку ресурсами хост-машины.

image

Несколько больше о сетевых соединениях контейнеров можно почитать на официальном wiki OpenVZ.

Теперь приведу процесс создания контейнера с VETH-соединением. Для этого сначала необходимо создать vmbr0 bridge. Установим пакет bridge-utils и после настроим интерфейс vmbr0:

# vim /etc/sysconfig/network-scripts/ifcfg-vmbr0
DEVICE = "vmbr0"
BOOTPROTO = "static"
IPV6INIT = "no"
ONBOOT = "yes"
TYPE = "Bridge"
DELAY = 0
IPADDR = 192.168.1.30
NETMASK = 255.255.255.0
GATEWAY = 192.168.1.1

А eth0 перенастраиваем следующим образом:

# vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE = "eth0"
ONBOOT = "yes"
IPV6INIT = "no"
TYPE = "Ethernet"
BRIDGE = "vmbr0"

Предварительно eth0 в этом примере имел статический IP 192.168.1.30.

Создаем /etc/vz/vznet.conf с таким содержанием:

# vim /etc/vz/vznet.conf

#! /bin/bash
EXTERNAL_SCRIPT = "/usr/sbin/vznetaddbr"

Перезапускаем хост-машину.

На этот раз, в качестве примера, выберем другой дистрибутив для создания контейнера с VETH сетевым соединением:

# vzctl create 102 --ostemplate centos-6-x86_64 --config vswap-1g

И соответственно настроим:

# vzctl set 102 --save --onboot yes
# vzctl set 102 --save --hostname centos6.example.com
# vzctl set 102 --save --netif_add eth0,,,FE:FF:FF:FF:FF:FF # задание VETH-соединения
# vzctl set 102 --save --nameserver 8.8.8.8 --nameserver 8.8.4.4
# vzctl set 102 --save --cpus 4
# vzctl set 102 --save --ram 8G
# vzctl set 102 --save --swap 4G
# vzctl set 102 --save --diskspace 100G
# vzctl start 102
# vzctl exec 102 passwd

Зададим конфигурацию сети нового контейнера и перезапустим сеть:

# cat << _EOF_ > /vz/root/102/etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE = "eth0"
HOSTNAME = "centos6"
IPV6INIT = "no"
MTU = "1500"
TYPE = "Ethernet"
ONBOOT = yes
BOOTPROTO = static
IPADDR = 192.168.1.32
NETMASK = 255.255.255.0
GATEWAY = 192.168.1.1
_EOF_

# vzctl exec 102 /etc/init.d/network restart

Для Ubuntu/Debian настройки сети находятся в /etc/network/interfaces:

# cat << _EOF_ > /vz/root/102/etc/network/interfaces
auto lo eth0
iface lo inet loopback
iface eth0 inet static
 address 192.168.1.32
 netmask 255.255.255.0
 gateway 192.168.1.1
_EOF_


# vzctl exec 102 /etc/init.d/networking restart

В результате сетевое соединение ( VETH ) должно выглядеть следующим образом:

# ip a
1: lo : <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link / loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1 / 8 scope host lo
    inet6 :: 1 /128 scope host
       valid_lft forever preferred_lft forever
2: venet0 : <BROADCAST,POINTOPOINT,NOARP> mtu 1500 qdisc noop state DOWN
    link / void
3: eth0 : <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link / ether 00:18:51 : c0 : eb : 63 brd ff : ff : ff : ff : ff : ff
    inet 192.168.1.35/24 brd 192.168.1.255 scope global eth0
    inet6 fe80 :: 218:51 ff : fec0 : eb63/64 scope link
       valid_lft forever preferred_lft forever

Когда VENET так:

# ip a
1: lo : <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link / loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1 / 8 scope host lo
    inet6 :: 1 /128 scope host
       valid_lft forever preferred_lft forever
2: venet0 : <BROADCAST,POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link / void
    inet 127.0.0.2/32 scope host venet0
    inet 192.168.1.31/32 brd 192.168.1.31 scope global venet0 : 0
3: eth0 : <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN
    link / ether 00:18:51 : a6 : 29: b0 brd ff : ff : ff : ff : ff : ff

Управление контейнерами или их квотами производится через утилиту vzctl. Опишу наиболее популярные команды:

# vzctl start $CTID # старт контейнера с номером $CTID
# vzctl stop $CTID # остановка контейнера
# vzctl restart $CTID # перегрузки
# vzctl destroy $CTID # удаления контейнера, предварительно необходимо его остановить
# vzctl exec $CTID command # запуск команды в контейнере
# vzctl enter $CTID # логин в консоль контейнера $CTID через хост - машину
# vzctl set $CTID different_options - save # настройки опций для виртуальной машины

Конечно, также есть возможность настройки квот для каждого из контейнеров без их перегрузки.
Ограничение обьема диска и количества инод происходит следующим образом (синтаксис задания такой software_limit:hardware_limit ):

# vzctl set 101 --diskspace 1000000:1100000 --save # 1000000 - это примерно 1GB
# vzctl set 101 --diskinodes 90000:91000 --save # задание к-ва дисковых инод .
# vzctl set 101 --quotatime 600 --save # время на которое можно увеличить квоты до hardware limit

Также можно настроить приоритет дискового ввода/вывода ( disk I/O). Высокий уровень 7, самый низкий — 0. По умолчанию disk I/O устанавливается в 4, однако это можно изменить:

# vzctl set 101 --ioprio 6 --save

И проверить:

# grep IOPRIO /etc/vz/conf/101.conf
IOPRIO = " 6"

Так можно увеличить/уменьшить кол-во ядер до 3, что будет использовать контейнер:

# vzctl set 101 --cpus 3 --save

Если хост-система имеет меньше ядер — то конечно желаемые изменения не произойдут.
Установка количества оперативной и swap-памяти происходит таким образом:

# vzctl set 101 --physpages 512M --save
# vzctl set 101 --swappages 512M --save

Подробнее о квотах можно почитать по адресу openvz.org/User_Guide/Managing_Resources
Для просмотра всех контейнеров и их состояний можно воспользоваться утилитой vzlist:

# vzlist -a
      CTID NPROC STATUS IP_ADDR HOSTNAME
       101 42 running 192.168.1.31 ubuntu1310.example.com
       102 17 running - centos6.example.com
       103 20 running - debian7.example.com
       104 20 running - debian72.example.com

Очень важно вспомнить о дампах контейнеров. Для этого есть посторонняя утилита, которая имеет имя vzdump. С ее помощью можно почти без остановки работы удобно скопировать/мигрировать/забекапить контейнер. Сначала ее необходимо установить:

# rpm -ivh "http://ftp.openvz.org/contrib/utils/vzdump/vzdump-1.2-4.noarch.rpm"

А пользоваться ею можно так:

# vzdump --suspend 102
INFO: starting new backup job : vzdump --suspend 102
...
INFO: backup mode : suspend
INFO: starting first sync /vz/private/102/ to /vz/dump/vzdump-openvz-102-2014_02_02-14_05_46.tmp
INFO: Finished Backup of VM 102 ( 00:02:14 )
INFO: Backup job finished successfuly

И сразу есть возможность отресторить дамп в новую машину с новым CTID:

# vzrestore /vz/dump/vzdump-openvz-102-2014_02_02-14_05_46.tar 201
INFO: restore openvz backup '/vz/dump/vzdump-openvz-102-2014_02_02-14_05_46.tar ' using ID 201
INFO: extracting archive '/vz/dump/vzdump-openvz-102-2014_02_02-14_05_46.tar '
INFO: Total bytes read : 649799680 ( 620MiB , 62MiB / s )
INFO: extracting configuration to '/etc/vz/conf/201.conf '
INFO: restore openvz backup '/vz/dump/vzdump-openvz-102-2014_02_02-14_05_46.tar ' successful

Для удобного управления виртуальными машинами могу посоветовать Proxmox или OpenVZ Web Panel
Кажется, что это все о чем хотел написать. Не стесняйтесь писать комментарии, если возникли какие-то вопросы.

Полезные ресурсы:
www.ibm.com/developerworks/ru/library/l-openvz_1/index.html
blog.shaggy-cat.ru/2010/03/openvz_25.html
openvz.org/Quick_installation
openvz.org/Installation_on_Debian
openvz.org/Quick_Installation_CentOS_6
openvz.org/User_Guide/Managing_Resources
www.altlinux.org/OpenVZ
openvz.org/Cloning_VE
openvz.org/Backup_of_a_running_container_with_vzdump
www.howtoforge.com/clone-back-up-restore-openvz-vms-with-vzdump
owp.softunity.com.ru
www.janoszen.com/2013/01/22/lxc-vs-openvz
Теги:
Хабы:
+24
Комментарии 9
Комментарии Комментарии 9

Публикации

Истории

Работа

DevOps инженер
39 вакансий

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн