Kernel-based Virtual Machine
Сам он является гипервизором реализованным в виде модуля ядра. Для функционирования ему требуются сторонние программные обеспечения:
libvirt - библиотека управления системами виртуализации
virsh - интерфейс управления виртуальными машинами с командной строки
virt-install - утилита для создания виртуальных машин
qemu - система эмуляции аппаратного обеспечения
libguestfs-tools - набор утилит для работы с образами дисков
Это необходимый минимум.
yum install qemu-kvm libvirt libvirt-python libguestfs-tools virt-install bridge-utils
systemctl enable libvirtd && systemctl start libvirtd
Linux
Роль сервера
Ролей у это сервера будет несколько:
1. reverse proxy
2. blog
3. crm
4. dhcp
5. dns
6. continuous integration node
7. developers test database
8. developers test backend
9. oauth2 proxy
10. crm2
11. certbot
12. subversion
13. wifi controller
14. continuous integration master
15. graylog
Список довольно внушительный, но на самом деле все эти сервисы создают небольшую нагрузку кроме continuous integration (системы непрерывной интеграции/системы автоматической сборки и тестирования). Последние могут сильно напрягать все ресурсы сервера, но в зависимости от того как и что собирают. В моем случае на нем гоняют Java и PHP так, что нагрузка идет на процессорное время и объем оперативной памяти.
В попытке более менее равномерно разделить сервисы по виртуальным машинам пришел к такому злоключению:
VM1: reverse proxy, blog, crm, dhcp, dns, oauth2 proxy, certbot. Конфигурация 4 ядра, 4 гига, 1 тб (потому, что в бложике кто то может кодировать видео и все такое).
VM2: continuous integration, developers test database, developers test backend, crm2. Конфигурация 4 ядра, 6 гига, 500 гб (потому, что как уже писал CI в моем случае жрет много памяти и проца).
VM3: continuous integration master. Конфигурация 4 ядра, 4 гига, 2тб (потому, что это мастер другой CI системы).
VM4: wifi controller. Конфигурация 2 ядра, 4 гига, 500 гб (исходя из рекомендации разработчиков).
VM5: graylog. Конфигурация 2 ядра, 4 гига, 500 гб (исходя из рекомендации разработчиков).
VM6: subversion. Конфигурация 2 ядра, 2 гига, 1 тб.
Выбор железа
Глядя на все это сразу бросается в глаза subversion, который будет потреблять много гигабайтов дискового пространства. Отсюда выбор дисков в пользу большого объема. Вообще при выборе дисков надо запомнить два простых правила:
1. мало, но быстро -> чем меньше объем диска, тем он быстрее
2. много, но медленно -> чем больше объем диска, тем он медленнее
Возможно кому то поможет в будущем с выбором дисков.
Итак, у нас получилось 6 виртуальных машин готовых употребить 19 ядер, 24 гб памяти и 5.5 тб дискового пространства.
Долго не думая берем что нибудь вроде этого ;). Далее докупаем Raiser для установки платы в 1 юнитовый корпус и SAS контроллер. Будем использовать что то в духе этого.
В итоге конфигурация сервера получается 24 ядра, 32 гб, 8 тб (лучше использовать RAID-10, что даст отказоустойчивость и прирост в производительности жестких дисков, но сокротив общее дисковое пространство в 2 раза).
Еще 1 SSD объемом где то в 256 гб под саму операционную систему.
Ставим Raiser, устанавливаем SAS контроллер, а под ним SSD. Настраиваем RAID-10, устанавливаем дистрибутив на SSD, форматируем блочное устройство полученное при сборке RAID массива в XFS и монтируем скажем в /opt. Ставим KVM и выполняем «tuned-adm profile virtual-host». Done!
Настройка сетевых мостов
Сперва настраиваем сетевой интерфейс, затем настраиваем интерфейсы виртуальных локальных сетей и сетевые мосты виртуальных машин, чтобы они могли взаимодействовать с локальной сетью. Настраиваем сетевой интерфейс /etc/sysconfig/network-scripts/ifcfg-enp1s0f0:
TYPE=Ethernet
BOOTPROTO=none
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=no
IPV6_AUTOCONF=no
IPV6_DEFROUTE=no
IPV6_PEERDNS=no
IPV6_PEERROUTES=no
IPV6_FAILURE_FATAL=no
NAME=enp1s0f0
UUID=95afb9a7-e3ef-4aff-9ff4-d505fd0ad7ed
DEVICE=enp1s0f0
ONBOOT=yes
Настраиваем VLAN /etc/sysconfig/network-scripts/ifcfg-enp1s0f0.100:
VLAN=YES
DEVICE=enp1s0f0.100
PHYSDEV=enp1s0f0
BOOTPROTO=none
IPV6INIT=no
IPV6_AUTOCONF=no
IPV6_DEFROUTE=no
IPV6_PEERDNS=no
IPV6_PEERROUTES=no
IPV6_FAILURE_FATAL=no
ONBOOT=YES
BRIDGE=virbr0.100 #здесь указываем сетевой мост, который собираемся создавать
Настраиваем BRIDGE /etc/sysconfig/network-scripts/ifcfg-virbr0.100:
VLAN=yes
DEVICE=virbr0.100
TYPE=BRIDGE
BOOTPROTO=static
IPV6INIT=no
IPV6_AUTOCONF=no
IPV6_DEFROUTE=no
IPV6_PEERDNS=no
IPV6_PEERROUTES=no
IPV6_FAILURE_FATAL=no
IPADDR=192.168.1.4 #ip-адрес виртуальной машины в VLAN100
PREFIX=24
NETWORK=192.168.1.0
GATEWAY=192.168.1.1
DNS1=8.8.8.8
ONBOOT=yes
Остальные интерфейсы добавляете аналогично, но в них лучше не указывать GATEWAY и DNS (наверное не мне рассказывать про маршрутизацию).
Развертка Linux
Создаем виртуальную машину:
virt-install -n vm1 --vcpus 4 -r 4096 -f /opt/kvm-images/vm1.img -s 500 -c /opt/distr/CentOS-7-x86_64-Minimal-1511.iso --accelerate --os-type=linux --os-variant=centos7.0 -v --graphics vnc,listen=192.168.1.3 -w bridge:virbr0.100
Разберем команду:
-n - название виртуальной машины
--vcpus - количество ядер
-r - количество оперативной памяти в мегабайтах
-f - расположение образа виртуальной машины
-s - размер образа в гигабайтах
-c - виртуальный привод и путь до образа, который будет примонтирован
--os-type - указываем семейство операционной системы (например linux или windows)
--os-variant - указываем конкретный дистрибутив
В listen указали ip-адрес хост системы, через которую будем подключаться к VNC, чтобы продолжить установку в графическом режиме. Чтобы увидеть полный список поддерживаемых дистрибутивов наберите osinfo-query os. Думаю остальные параметры не нуждаются в комментариях.
После того, как началась установка можем подключиться к 192.168.1.3 любым VNC клиентом и продолжить установку.
Далее если хотите можете в гостевой системе установить подключение к виртуальной машине через серийный порт. Вот мануал. После этого если, например потеряете доступ к виртуальной машине по ssh, то можно будет подключиться к нему командой "virsh console vm1".
Теперь, чтобы диск работал быстрее набираем "virsh edit vm1". Ищем секцию disk и значение параметра "cache" устанавливаем в "writeback". Пример:
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='writeback'/>
<source file='/opt/kvm-images/vm1.img'/>
<target dev='vda' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</disk>
Windows
Роль сервера
В этот раз сервер будет выполнять чисто роль "continuous integration" и в нем будет 3 ноды, которые будут собирать не маленькие проекты на CPP. При компиляции и сборке ноды потребляют очень много процессорного времени и памяти, но между этими двумя этапами есть этап линковки объектов, которая создает очень высокую нагрузку на жесткие диски. В первоначальном варианте ставил диски SATA-3 4TB 7200RPM в массиве RAID-10, но такая конфигурация не смогла вытянуть по IOPS’ам. SSD в нужном количестве на момент заказа не смог достать, так что пришлось брать 4 SAS диска по 600GB 15000RPM. Далее решил не поднимать RAID-10, а просто для каждого диска создать по виртуальному диску (издержки LSI MEGARAID) и примонтировать в ОС как отдельные блочные устройства, чтобы каждая виртуальная машина могла насиловать только свой хард не влияя на IOPS соседних виртуальных машин (что значит one disk per vm).
Выбор железа
Конфигурация сервера такая же, но вместо медленного SAS диска на много терабайт будет использоваться быстрый SAS диск на мало гигабайт. Значит сможем в общей сложности завести 4 виртуальные машины с конфигурацией 4 ядра, 6 гб, 500 гб.
Все этапы настройки такие же как были описаны ранее, потому сразу перейдем к развертке windows.
Развертка Windows 10
Создаем образ:
qemu-img create -f qcow2 -o preallocation=metadata /opt/vm1/vm1.qcow2 500G
где /opt/vm1 это ну скажем /dev/sdb и соответственно остальные виртуальные машины тоже должны будут заводиться на других дисках.
В моем случае точки монтирования выглядят так:
Filesystem Size Used Avail Use% Mounted on
/dev/sdb 559G 119G 441G 22% /opt/win10
/dev/sda 559G 455G 104G 82% /opt/win81
/dev/sdc 559G 86G 474G 16% /opt/win10-2
Создаем виртуальную машину:
virt-install --name vm1 --ram 6000 --cpu=core2duo --vcpus 4 --disk path=/opt/vm1/vm1.qcow2,format=qcow2,bus=virtio,cache=none --disk path=/opt/SW_DVD9_Win_Pro_10_64BIT_Russian_-3_MLF_X19-84262.ISO,device=cdrom --cdrom /opt/virtio-win.iso --network=bridge:virbr0.100,model=e1000 --graphics vnc,listen=192.168.1.18 --os-type=windows --os-variant=win10 --noautoconsole --accelerate --noapic --arch x86_64
Разберем некоторые моменты:
--cpu=core2duo - необходимый параметр поскольку windows 10 пока, что умеет только так запускаться.
--disk path=/path/to/iso,device=cdrom - сие извращение сделано по той причине, что нужно было примонтировать установочный образ и образ с драйверами VirtIO для windows…впрочем вот вырезка из мана virt-install:
If a cdrom has been specified via the "--disk" option, and neither "--cdrom" nor any other install option is specified, the "--disk" cdrom is used as the install media.
cache=none — этот вариант показывает максимальную производительность по IOPS.
Как обычно подключаемся по VNC и замечаем, что программа установки не видит диск. Нажимаем «загрузить драйвер». Кликаем по кнопке "обзор" и подгружаем эти драйверы по очереди:
Balloon\w10\amd64 #для нормальной работы с памятью
viostor\w10\amd64 #для нормальной работы с жестким диском
Тонкости настройки Windows
Загрузившись первым делом накатываем все доступные обновления.
Идем в система->дополнительные параметры->визуальные эффекты и ставим "обеспечить наилучшее быстродействие".
Идем в администрирование->планировщик заданий->microsoft->defrag и отключаем задачу на дефрагментацию.
Идем в пуск->параметры->приложения->приложения и возможности->microsoft onedrive->удалить.
Идем в win+r->gpedit.msc->конфигурация компьютера->административные шаблоны->компоненты windows->onedrive->запретить использование onedrive для хранения файлов->включить.
Идем в win+r->services.msc и отключаем следующие службы:
-центр обновления windows
-superfetch
-windows search
Идем в защитник windows->защита от вирусов и угроз и отключаем следующие пункты:
-защита в реальном времени
-облачная защита
-автоматическая отправка образцов
Все вроде работает шустро. Радуемся. Открываем диспетчер задач->производительность->открыть монитор ресурсов и видим всего 2 ядра.
Дело в том, что windows немного по другому воспринимает топологию процессоров в отличии от linux, потому надо ему конкретно указать какую топологию процессора хотим использовать. Выполняем "shutdown /s /t 0".
Правим конфиг виртуальной машины "virsh edit vm1".
В секцию CPU добавляем: <topology sockets='1' cores='2' threads='2'/>, что означает, что у процессора 1 сокет, 2 ядра и 2 потока. Пример:
<cpu mode='custom' match='exact'>
<model fallback='allow'>core2duo</model>
<topology sockets='1' cores='2' threads='2'/>
</cpu>
Стартуем "virsh start vm1". Подключаемся по RDP и любуемся на 4 ядра.
Повседневные команды virsh
virsh list - список запущенных вм
virsh list --all - список всех вм
virsh shutdown vm1 - выключает вм (не работает для windows)
virsh destroy vm1 - насильно отключает вм
virsh dumpxml vm1 > vm1.xml - бекап конфигурации вм
virsh undefine vm1 - уничтожает вм (образ диска не удаляется)
virsh define vm1.xml - импортирует вм из xml
virsh autostart vm1 - ставим вм на автозагрузку
virsh autostart vm1 --disable - убираем вм с автозагрузки