# Руководство по созданию и управлению контейнерами и виртуальными машинами на базе OpenVZ 7 ## Содержание 1. [Введение в виртуализацию](#intro) - [Эмуляция оборудования](#emulation) - [Полная виртуализация](#full-virt) - [Паравиртуализация](#paravirt) - [Контейнерная виртуализация (виртуализация уровня ОС)](#cont-virt) - [OpenVZ — объединение технологий виртуализации уровня ОС и полной виртуализации](#vz7) - [Сравнение производительности гипервизоров](#tests) 2. [Краткая история проектов Virtuozzo/OpenVZ](#history) 3. [Что нового в OpenVZ 7](#changes) 4. [Установка и подготовительные действия](#install) - [Установка OpenVZ с помощью ISO-образа (bare-metal installation)](#bare-metal) - [Подготовительные действия](#prepare) 5. [Управление шаблонами](#templates) - [Шаблоны гостевых ОС](#guest-os) - [Шаблоны приложений](#app-templates) - [Шаблоны контейнеров и виртуальных машин](#templates-сt-vm) 6. [Создание и настройка контейнеров](#ct) - [Конфигурационные файлы](#configs) - [Создание контейнера](#create-ct) - [Настройка контейнера](#setup-ct) - [Запуск и вход](#run-enter) 7. [Управление контейнерами](#management-ct) - [Управление состоянием контейнера](#status-ct) - [Переустановка контейнера](#reinstall-ct) - [Клонирование контейнера](#clone-ct) - [Запуск команд в контейнере с хост-ноды](#run-commands) 8. [Управление ресурсами контейнеров](#resources-ct) - [Дисковые квоты](#quota) - [Процессор](#cpu) - [Операции ввода/вывода](#io) - [Память](#memory) - [Мониторинг ресурсов](#monitoring) 9. [Проброс устройств в контейнеры](#forward-dev-ct) - [TUN/TAP](#tun-tap) - [FUSE](#fuse) - [NFS](#nfs) - [PPTP](#pptp) - [Netfilter/IPTables](#netfilter) 10. [SimFS и ploop](#simfs-ploop) 11. [Управление снапшотами](#snapshots) 12. [Работа с виртуальными машинами](#vm) - [Создание и запуск ВМ](#create-vm) - [VNC](#vnc) - [Дополнения гостевой ОС](#guest-tools) - [Приостановка виртуальных машин](#pause-vm) - [Шаблоны конфигураций](#templates-vm) - [Добавление и удаление устройств в ВМ](#devices-vm) - [Горячее подключение CPU и RAM](#hotplug-vm) - [Оптимизация виртуальных машин с помощью KSM](#ksm) 13. [Миграция контейнеров и виртуальных машин](#migration) 14. [Расширенная информация о контейнерах и ВМ](#extra-info) 15. [Рекомендации системному администратору](#recommendations) 16. [Ссылки](#links) 17. [Лицензия](#license) ## [⬆](#toc) Введение в виртуализацию Виртуализация — предоставление наборов вычислительных ресурсов или их логического объединения, абстрагированных от аппаратной реализации, и обеспечивающих изоляцию вычислительных процессов. Виртуализацию можно использовать в: - консолидации серверов (возможность мигрировать с физических серверов на виртуальные, тем самым увеличивая коэффициент использования аппаратуры, что позволяет существенно сэкономить на аппаратуре, электроэнергии и обслуживании) - разработке и тестировании приложений (возможность одновременно запускать несколько различных операционных систем (ОС), это удобно при разработке кроссплатформенного программного обеспечения (ПО), таким образом значительно повышается качество, скорость разработки и тестирования приложений) - бизнесе (использование виртуализации в бизнесе растет с каждым днем и постоянно находятся новые способы применения этой технологии, например, возможность безболезненно сделать снапшот) - организации виртуальных рабочих станций (так называемых "тонких клиентов") *Общая схема взаимодействия виртуализации с аппаратным и программным обеспечением* ![Общая схема взаимодействия виртуализации с аппаратным и программным обеспечением](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/virt-scheme.png) Понятие виртуализации можно условно разделить на две категории: - виртуализация платформ (продуктом этого вида виртуализации являются виртуальные машины) - виртуализация ресурсов (преследует целью комбинирование или упрощение представления аппаратных ресурсов для пользователя и получение неких пользовательских абстракций оборудования, пространств имен, сетей) Взаимодействие приложений и операционной системы с аппаратным обеспечением осуществляется через абстрагированный слой виртуализации. Существует несколько подходов организации виртуализации: - эмуляция оборудования (QEMU, Bochs, Dynamips) - полная виртуализация (KVM, Microsoft Hyper-V, Oracle VM VirtualBox, VMware ESXi) - паравиртуализация (Xen, L4, Trango Virtual Processors) - виртуализация уровня ОС (LXC, OpenVZ, FreeBSD jail, Solaris Zone) ### Эмуляция оборудования Эмуляция аппаратных средств является одним из самых сложных методов виртуализации. В то же время главной проблемой при эмуляции аппаратных средств является низкая скорость работы, в связи с тем, что каждая команда моделируется на основных аппаратных средствах. В процессе эмуляции оборудования используется механизм динамической трансляции, то есть каждая из инструкций эмулируемой платформы заменяется на заранее подготовленный фрагмент инструкций физического процессора. *Эмуляция оборудования моделирует аппаратные средства* ![Схема эмуляции оборудования](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/emulation.png) Динамический транслятор позволяет во время исполнения переводит инструкции целевого (гостевого) процессора в инструкции центрального процессора хоста для обеспечения эмуляции. QEMU обеспечивает динамическую трансляцию преобразованием целевой инструкции в микрооперации, эти микрооперации представляют собой элементы C-кода, которые компилируются в объекты. Затем запускается основной транслятор, который отображает целевые инструкции на микрооперации для динамической трансляции. Такой подход не только эффективен, но и обеспечивает переносимость. ### Полная виртуализация Полная виртуализация использует гипервизор, который осуществляет связь между гостевой ОС и аппаратными средствами физического сервера. В связи с тем, что вся работа с гостевой операционной системой проходит через гипервизор, скорость работы данного типа виртуализации ниже чем в случае прямого взаимодействия с аппаратурой. Основным преимуществом полной виртуализации является то, что в ОС не вносится никаких изменений, единственное ограничение — операционная система должна поддерживать основные аппаратные средства (AMD SVM или Intel VT). *Полная виртуализация использует гипервизор* ![Схема полной виртуализации](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/full-virt.png) В архитектуре KVM виртуальная машина выполняется как обычный Linux-процесс, запланированный стандартным планировщиком Linux. На самом деле, виртуальный процессор представляется как обычный Linux-процесс, это позволяет KVM пользоваться всеми возможностями ядра Linux. Эмуляцией устройств управляет модифицированная версия QEMU, которая обеспечивает эмуляцию BIOS, шины PCI, шины USB, а также стандартный набор устройств, таких как дисковые контроллеры IDE и SCSI, сетевые карты и другие. ### Паравиртуализация Паравиртуализация имеет некоторые сходства с полной виртуализацией. Этот метод использует гипервизор для разделения доступа к основным аппаратным средствам, но объединяет код, касающийся виртуализации, в непосредственно операционную систему, поэтому недостатком метода является то, что гостевая ОС должна быть изменена для гипервизора. Но паравиртуализация существенно быстрее полной виртуализации, скорость работы виртуальной машины приближена к скорости реальной, это осуществляется за счет отсутствия эмуляции аппаратуры и учета существования гипервизора при выполнении системных вызовов в коде ядра. Вместо привилегированных операций совершаются гипервызовы обращения ядра гостевой ОС к гипервизору с просьбой о выполнении операции. *Паравиртуализация разделяет процесс с гостевой ОС* ![Схема паравиртуализации](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/paravirt.png) В паравиртуальном режиме (PV) оборудование не эмулируется, и гостевая операционная система должна быть специальным образом модифицирована для работы в таком окружении. Начиная с версии 3.0, ядро Linux поддерживает запуск в паравиртуальном режиме без перекомпиляции со сторонними патчами. Преимущество режима паравиртуализации состоит в том, что он не требует поддержки аппаратной виртуализации со стороны процессора, а также не тратит вычислительные ресурсы для эмуляции оборудования на шине PCI. Режим аппаратной виртуализации (HVM), который появился в Xen, начиная с версии 3.0 гипервизора требует поддержки со стороны оборудования. В этом режиме для эмуляции виртуальных устройств используется QEMU, который весьма медлителен несмотря на паравиртуальные драйвера. Однако со временем поддержка аппаратной виртуализации в оборудовании получила настолько широкое распространение, что используется даже в современных процессорах лэптопов. ### Контейнерная виртуализация (виртуализация уровня ОС) Виртуализация уровня операционной системы отличается от других. Она использует технику, при которой серверы виртуализируются непосредственно над ОС. Недостатком метода является то, что поддерживается одна единственная операционная система на физическом сервере, которая изолирует контейнеры друг от друга. Преимуществом виртуализации уровня ОС является "родная" производительность. *Виртуализация уровня ОС изолирует серверы* ![Схема виртуализации уровня ОС](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/cont-virt.png) Виртуализация уровня ОС — метод виртуализации, при котором ядро операционной системы поддерживает несколько изолированных экземпляров пространства пользователя (контейнеров) вместо одного. С точки зрения пользователя эти экземпляры полностью идентичны реальному серверу. Для систем на базе UNIX эта технология может рассматриваться как улучшенная реализация механизма chroot. Ядро обеспечивает полную изолированность контейнеров, поэтому программы из разных контейнеров не могут воздействовать друг на друга. ### OpenVZ — объединение технологий виртуализации уровня ОС и полной виртуализации OpenVZ позволяет создавать множество защищенных, изолированных друг от друга контейнеров на одном узле. Помимо этого существует возможность создания виртуальных машин на базе QEMU/KVM. Управление контейнерами и виртуальными машинами происходит с помощью специализированных утилит. *Архитектура OpenVZ 7* ![Архитектура OpenVZ 7](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/vz7-architect.png) Каждый контейнер ведет себя так же, как автономный сервер и имеет собственные файлы, процессы, сеть (IP-адреса, правила маршрутизации). В отличие от KVM или Xen, OpenVZ использует одно ядро, которое является общим для всех виртуальных сред. Контейнеры можно разделить на две составляющие: - ядро (namespaces, cgroups, CRIU, ploop, vcmmd, ...) - пользовательские утилиты (prlctl, vzctl, vzpkg, vzlist, ...) Namespaces — пространства имен. Это механизм ядра, который позволяет изолировать процессы друг от друга. Изоляция может быть выполнена в шести контекстах (пространствах имен): - mount — предоставляет процессам собственную иерархию файловой системы и изолирует ее от других таких же иерархий по аналогии с chroot - PID — изолирует идентификаторы процессов (PID) одного пространства имен от процессов с такими же идентификаторами другого пространства - network — предоставляет отдельным процессам логически изолированный от других стек сетевых протоколов, сетевой интерфейс, IP-адрес, таблицу маршрутизации, ARP и прочие реквизиты - IPC — обеспечивает разделяемую память и взаимодействие между процессами - UTS — изоляция идентификаторов узла, таких как имя хоста (hostname) и домена (domain) - user — позволяет иметь один и тот же набор пользователей и групп в рамках разных пространств имен, в каждом контейнере может быть свой root и любые другие пользователи и группы CGroups (Control Groups) — позволяет ограничить аппаратные ресурсы некоторого набора процессов. Под аппаратными ресурсами подразумеваются: процессорное время, память, дисковая и сетевая подсистемы. Набор или группа процессов могут быть определены различными критериями. Например, это может быть целая иерархия процессов, получающая все лимиты родительского процесса. Кроме этого возможен подсчет расходуемых группой ресурсов, заморозка (freezing) групп, создание контрольных точек (checkpointing) и их перезагрузка. Для управления этим полезным механизмом существует специальная библиотека libcgroups, в состав которой входят такие утилиты, как cgcreate, cgexec и некоторые другие. CRIU (Checkpoint/Restore In Userspace) — обеспечивает создание контрольной точки для произвольного приложения, а также возобновления работы приложения с этой точки. Основной целью CRIU является поддержка миграции контейнеров. Уже поддерживаются такие объекты как процессы, память приложений, открытые файлы, конвейеры, IPC сокеты, TCP/IP и UDP сокеты, таймеры, сигналы, терминалы, файловые дескрипторы. В разработке также находится миграция TCP соединений. VCMM (Virtuozzo containers memory management) — сервис управления механизмом memory cgroups в пространстве пользователя. Менеджер памяти 4 поколения управляет memory cgroups, который присутствует в ванильном ядре, поэтому не требует сторонних патчей со стороны OpenVZ. Проведенные тестирования показывают, что OpenVZ является одним из наиболее актуальных решений на рынке виртуализации, так как показывает внушительные результаты в различных тестированиях. *График времени отклика системы* ![Время отклика системы](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/response-time.png) На графике времени отклика системы можно наблюдать результаты трех тестов — с нагрузкой на систему и виртуальную машину, без нагрузки, нагрузкой только на ВМ. Во всех тестах OpenVZ показал результаты наименьшего времени отклика, в то время, когда ESXi и Hyper-V показывают оверхед 700-3000%, когда у OpenVZ всего 1-3%. *График пропускной способности сети* ![Пропускная способность сети](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/network.png) На втором графике — результаты тестирования пропускной способности сети. На графике можно наблюдать, что OpenVZ обеспечивает практическую нативную пропускную способность 10Gb сети (9.7Gbit/s отправка и 9.87Gbit/s прием). ### Сравнение производительности гипервизоров Тест используемый для оценки производительности называется DVD Store. Он использует классический набор серверного ПО: Linux, Apache, MySQL, PHP (LAMP). Внутри каждой ВМ эмулируется работа онлайн-магазина по продаже DVD. Результат теста — количество транзакций совершенных суммарно во всех ВМ (ось ординат). Количество ВМ в тесте увеличивается последовательно от 1 до 100 (ось абсцисс). *LAMP: OpenSource QEMU KVM vs Virtuozzo @ CentOS 7.4 (ВМ)* ![LAMP VM test](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/lamp-test.jpeg) Как видно на графиках выше, производительность виртуальных машин с CentOS Linux 7.4 работающих на гипервизоре Virtuozzo 7 оказывается до 30% выше, чем при запуске аналогичной нагрузки на KVM. Наибольшая разница наблюдается в точке CPU-оверкоммита, где суммарное количество ядер процессоров, выделенных всем ВМ, достигает количества физических ядер CPU сервера. Для данного сервера эта точка соответствует 20 ВМ. Другое сравнение было проведено между Virtuozzo 7 и Hyper-V 3.0. Здесь производительность оценивалась с помощью теста vConsolidate, гостевая ОС — Windows Server 2012 R2. *vConsolidate: Hyper-V vs Virtuozzo @ Windows 2012 R2 (ВМ)* ![vConsolidate test](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/vconsolidate.jpeg) В отличие от DVD Store, в vConsolidate нагрузка не одинакова для всех ВМ. В этом тесте они разделены на так называемые CSU (Consolidation Stack Units). Каждая CSU — это группа из четырех ВМ, нагрузку в которых создают SPECjbb, WebBench и SysBench (OLTP). Четвертая ВМ в каждой CSU – idle, то есть без нагрузки. Количественный результат — среднее геометрическое от результатов трех вышеупомянутых тестов, полученных суммарно из всех виртуальных машин (ось ординат). Количество CSU в тесте увеличивается последовательно от 1 до 24 (ось абсцисс). ## [⬆](#toc) Краткая история проектов Virtuozzo/OpenVZ В 1999 году возникла идея создания Linux-контейнеров, а уже в 2002 году компания SWsoft представила первый релиз коммерческой версии Virtuozzo. В том же 2002 году появились первые клиенты в Кремниевой долине. В 2004 году — выпуск Virtuozzo для Windows. В 2005 году было принято решение о разделении Virtuozzo на два отдельных проекта, свободный OpenVZ (под лицензией GNU GPL) и проприетарный Virtuozzo. В 2006 году OpenVZ стал доступен для Debian Linux, переход к ядру RHEL 4. В 2007 году — портирован на RHEL 5. В 2011 году появилась идея создания проекта CRIU, OpenVZ портирован на RHEL 6. В 2012 году стала доступна CRIU v0.1. В конце 2014 года компания Odin анонсировала открытие кодовой базы Parallels Cloud Server и объединение ее с открытым кодом OpenVZ. В апреле 2015 года открыт репозиторий с ядром RHEL 7 (3.10), в мае были открыты исходные коды пользовательских утилит, а в июне выложены тестовые сборки ISO-образов и RPM-пакеты. В марте 2016 года анонсирован выход Virtuozzo 7.0 Beta, с измененной архитектурой, а также с такими нововведениями, как дополнения гостевых ОС для Linux и Windows. Также представлена "живая" миграция для контейнеров, реализованная с помощью инструментария CRIU и P.Haul. 25 июля 2016 года [анонсирован](https://lists.openvz.org/pipermail/announce/2016-July/000664.html) окончательный релиз продукта под именем OpenVZ 7.0. В релизе объявлены такие события как отказ от развития SimFS, также объявлено что со следующей версии OpenVZ утилита vzctl будет объявлена устаревшей, рекомендуется вместо нее использовать prlctl или virsh. ## [⬆](#toc) Что нового в OpenVZ 7 Основные изменения по сравнению с OpenVZ 6 (2.6.32): - OpenVZ 7 базируется на ядре RHEL 7 (3.10) - благодаря большой интеграции кода в ванильное ядро, количество патчей значительно сократилось, для сравнения число коммитов в 2.6.18 (RHEL 5) равно 264000, для 2.6.32 (RHEL 6) — 202000, для 3.10 (RHEL 7) — 66000 коммитов - реализация живой миграции с помощью P.Haul и CRIU - возможность создания виртуальных машин на базе KVM - отказ от управления контейнерами с помощью vzctl в пользу prlctl и virsh - использование механизма VCMM для управления памятью - отказ от развития SimFS в пользу ploop - унифицированное управление контейнерами и виртуальными машинами с помощью libvirt - гарантированные лимиты памяти - горячее подключение CPU/RAM для виртуальных машин, поддержка KSM - обновленная документация с 2005 года - интеграция работы с Docker и OpenStack ## [⬆](#toc) Установка и подготовительные действия Начиная с версии OpenVZ 7.0 доступен только один вариант установки, с помощью ISO-образа дистрибутива. Установка OpenVZ с помощью PXE (Preboot Execution Environment) подробно описана в [документации](https://docs.openvz.org/virtuozzo_7_installation_using_pxe_guide.webhelp/). ### Установка OpenVZ с помощью ISO-образа (bare-metal installation) Дистрибутив Virtuozzo Linux (VzLinux) с патчами для ядра RHEL 7, утилитами управления и модифицированным установщиком доступен для скачивания в виде стандартного ISO-образа и в виде netinstall-образа. Текущие последние версии ISO-образов доступны по адресу: После записи дистрибутива на носитель, можно приступать к установке OpenVZ. Для этого необходимо загрузиться с носителя. *Экран установки OpenVZ после загрузки с носителя* ![Экран установки OpenVZ](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/install-vz.png) Установка OpenVZ ничем не отличается от установки обычного Linux-дистрибутива. Установщик Anaconda предложит установить дату и время, раскладку клавиатуры, языковые параметры. Также необходимо будет произвести разметку диска и настроить сеть. По умолчанию включен kdump, который позволяет в будущем выяснить причины сбоев в ядре, поэтому рекомендуется его не отключать. *Экран установки параметров системы* ![Настройки системы](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/anaconda.png) *Пример разметки для 30GB диска* ![Разметка диска](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/partitioning.png) Необходимо для раздела `/` выделить не менее 8GB доступного дискового пространства. Размер раздела `swap` равен примерно половине объема оперативной памяти. Все остальное дисковое пространство (рекомендуется не менее 30GB) выделяется под раздел `/vz` с файловой системой ext4. *Настройки сетевого интерфейса и имени хоста* ![Настройки сети](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/network-install.png) Также необходимо задать пароль пользователя `root` и создать локального пользователя, например `vzuser`. *Установка пароля суперпользователя и создание локального пользователя* ![Настройки пользователей](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/user.png) После установки необходимо перезагрузиться. На этом установка OpenVZ с помощью ISO-образа завершена. *Меню загрузчика GRUB после установки OpenVZ* ![GRUB](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/grub.png) Первый вход в систему осуществляется от пользователя `vzuser`, по SSH. Пример получения прав суперпользователя на сервере: ``` user@localhost ~ $ ssh vzuser@192.168.0.150 vzuser@192.168.0.150's password: пароль_пользователя_vzuser [vzuser@vz ~]$ su - Password: пароль_пользователя_root [root@vz ~]# ``` ### Подготовительные действия На сервере важно всегда обновлять программное обеспечение, так как в новых версиях не только могут добавлять новые возможности, но и исправлять уязвимости. Указанная ниже команда обновляет все существующие в системе пакеты: ``` [root@vz ~]# yum update ``` Для сервера важно, чтобы было установлено правильное время. Чтобы синхронизировать время с интернетом необходимо настроить сервер синхронизации времени ntp. Если во время установки ОС, была установлена некорректная временная зона, то можно это сделать позже: ``` [root@vz ~]# timedatectl set-timezone Europe/Moscow ``` Установка `ntp` и синхронизация времени с удаленными серверами: ``` [root@vz ~]# yum install ntp [root@vz ~]# systemctl start ntpd [root@vz ~]# systemctl enable ntpd [root@vz ~]# ntpdate -q 0.ru.pool.ntp.org 1.ru.pool.ntp.org ``` ## [⬆](#toc) Управление шаблонами ### Шаблоны гостевых ОС Шаблоны гостевых ОС используются для создания контейнеров. Просмотр списка уже имеющихся локальных шаблонов гостевых ОС: ``` [root@vz ~]# vzpkg list -O --with-summary ubuntu-14.04-x86_64 :Ubuntu 14.04 (for AMD64/Intel EM64T) Virtuozzo Template ubuntu-16.04-x86_64 :Ubuntu 16.04 (for AMD64/Intel EM64T) Virtuozzo Template vzlinux-7-x86_64 :VzLinux 7 (for AMD64/Intel EM64T) Virtuozzo Template centos-7-x86_64 :Centos 7 (for AMD64/Intel EM64T) Virtuozzo Template centos-6-x86_64 :Centos 6 (for AMD64/Intel EM64T) Virtuozzo Template debian-8.0-x86_64 :Debian 8.0 (for AMD64/Intel EM64T) Virtuozzo Template debian-8.0-x86_64-minimal :Debian 8.0 minimal (for AMD64/Intel EM64T) Virtuozzo Template ``` Удаленно доступные шаблоны: ``` [root@vz ~]# vzpkg list --available --with-summary debian-7.0-x86_64 fedora-22-x86_64 fedora-23-x86_64 suse-42.1-x86_64 ubuntu-14.10-x86_64 ubuntu-15.04-x86_64 ubuntu-15.10-x86_64 vzlinux-6-x86_64 ``` Установка шаблона: ``` [root@vz ~]# vzpkg install template ubuntu-16.04-x86_64 ``` Альтернативный вариант установки шаблона: ``` [root@vz ~]# yum install ubuntu-16.04-x86_64-ez ``` Установка и обновление кэша шаблона: ``` [root@vz ~]# vzpkg create cache ubuntu-16.04-x86_64 [root@vz ~]# vzpkg update cache ubuntu-16.04-x86_64 ``` Если не указывать имя шаблона, то установка или обновление кэша произойдет для всех имеющихся шаблонов. Просмотр даты последнего обновления кэша: ``` [root@vz ~]# vzpkg list -O ubuntu-14.04-x86_64 ubuntu-16.04-x86_64 2016-05-14 02:10:18 vzlinux-7-x86_64 centos-7-x86_64 centos-6-x86_64 debian-8.0-x86_64 debian-8.0-x86_64-minimal ``` ### Шаблоны приложений Существует возможность установки шаблонов приложений для контейнеров. Основное отличие между шаблонами гостевых ОС и шаблонами приложений в том, что шаблоны гостевых ОС используются для создания контейнеров, а шаблоны приложений, обеспечивают установку дополнительного ПО для уже имеющихся контейнеров. Просмотр списка шаблонов приложений для `centos-7-x86_64`: ``` [root@vz ~]# vzpkg list centos-7-x86_64 centos-7-x86_64 2016-02-09 17:01:05 centos-7-x86_64 cyrus-imap centos-7-x86_64 tomcat centos-7-x86_64 php centos-7-x86_64 docker centos-7-x86_64 mailman centos-7-x86_64 spamassassin centos-7-x86_64 devel centos-7-x86_64 mod_ssl centos-7-x86_64 jre centos-7-x86_64 vzftpd centos-7-x86_64 postgresql centos-7-x86_64 mysql centos-7-x86_64 jsdk ``` Пример установки шаблона приложений `tomcat` и `jre`: ``` [root@vz ~]# vzpkg list ct5 centos-7-x86_64 2016-02-09 17:00:57 [root@vz ~]# vzpkg install ct5 tomcat jre [root@vz ~]# prlctl exec ct5 systemctl start tomcat [root@vz ~]# prlctl exec ct5 systemctl is-active tomcat active ``` После установки можно проверить список установленных шаблонов для контейнера: ``` [root@vz ~]# vzpkg list ct5 centos-7-x86_64 2016-02-09 17:00:57 centos-7-x86_64 tomcat 2016-02-09 19:56:03 centos-7-x86_64 jre 2016-02-09 20:03:50 ``` Удаление шаблона приложения из контейнера: ``` [root@vz ~]# vzpkg remove ct5 tomcat Removed: tomcat noarch 0:7.0.54-2.el7_1 tomcat-admin-webapps noarch 0:7.0.54-2.el7_1 tomcat-webapps noarch 0:7.0.54-2.el7_1 tomcat-lib noarch 0:7.0.54-2.el7_1 tomcat-el-2.2-api noarch 0:7.0.54-2.el7_1 [root@vz ~]# vzpkg list ct5 centos-7-x86_64 2016-02-09 17:00:57 centos-7-x86_64 jre 2016-02-09 20:03:50 ``` Создадим конфиг, на основе которого будет создаваться контейнер с CentOS 7 с предустановленным Apache Tomcat: ``` [root@vz ~]# cd /etc/vz/conf/ [root@vz conf]# cp ve-basic.conf-sample ve-centos-7-x86_64-tomcat.conf-sample [root@vz conf]# echo OSTEMPLATE=".centos-7" >> ve-centos-7-x86_64-tomcat.conf-sample [root@vz conf]# echo TEMPLATES=".tomcat" >> ve-centos-7-x86_64-tomcat.conf-sample ``` Создадим кэш для этого приложения: ``` [root@vz ~]# vzpkg create appcache --config centos-7-x86_64-tomcat [root@vz ~]# vzpkg list appcache centos-7-x86_64 2016-07-31 03:12:28 tomcat ``` На основе нового конфигурационного файла создадим и запустим контейнер: ``` [root@vz ~]# prlctl create ct5 --config centos-7-x86_64-tomcat --vmtype=ct Creating the Virtuozzo Container... The Container has been successfully created. [root@vz ~]# prlctl start ct5 Starting the CT... The CT has been successfully started. ``` Проверка предустановки Apache Tomcat в составе шаблона: ``` [root@vz ~]# prlctl exec ct5 rpm -q tomcat tomcat-7.0.54-2.el7_1.noarch ``` ### Шаблоны контейнеров и виртуальных машин Помимо шаблонов гостевых ОС и шаблонов приложений, существует также возможность создания контейнера или виртуальной машины на основе других контейнеров или ВМ. Пример создания шаблона на основе контейнера `ct2` с установленным веб-сервером nginx: ``` [root@vz ~]# prlctl clone ct2 --name CentOS7+nginx --template Clone the ct2 CT to template CentOS7+nginx... The CT has been successfully cloned. ``` Просмотр списка доступных шаблонов: ``` [root@vz ~]# prlctl list -t UUID DIST T NAME {c28c09dd-a379-43dd-aae9-3e62f972476a} centos7 CT CentOS7+nginx ``` Создадим новый контейнер на основе шаблона `CentOS7+nginx`: ``` [root@vz ~]# prlctl create ct3 --ostemplate CentOS7+nginx Creating the VM on the basis of the CentOS7+nginx template... Clone the CentOS7+nginx CT to CT ct3... The CT has been successfully cloned. ``` Удаление шаблона: ``` [root@vz ~]# prlctl delete CentOS7+nginx Removing the CT... The CT has been successfully removed. ``` ## [⬆](#toc) Создание и настройка контейнеров ### Конфигурационные файлы В старых версиях OpenVZ основным идентификатором контейнера является CTID, который вручную указывался при создании контейнера. Сейчас в этом нет необходимости, на смену CTID пришел UUID, который создается автоматически. Каждый контейнер имеет свой конфигурационный файл `/vz/private/$UUID/ve.conf`. Именуются конфиги по UUID контейнера. Например, для контейнера с `UUID = {3d32522a-80af-4773-b9fa-ea4915dee4b3}`, конфиг будет называться `/vz/private/3d32522a-80af-4773-b9fa-ea4915dee4b3/ve.conf`. Для удобства использования конфигов, для них созданы символические ссылки вида `/etc/vz/conf/$UUID.conf`. Для большего удобства использования конфигов, также существуют символические ссылки вида `/etc/vz/names/$NAME`. При создании контейнера можно использовать типовую конфигурацию. Типовые файлы конфигураций находятся в каталоге `/etc/vz/conf/`: ``` [root@vz ~]# ls /etc/vz/conf/ | grep sample ve-basic.conf-sample ve-confixx.conf-sample ve-vswap.1024MB.conf-sample ve-vswap.2048MB.conf-sample ve-vswap.256MB.conf-sample ve-vswap.512MB.conf-sample ve-vswap.plesk.conf-sample vps.vzpkgtools.conf-sample ``` В этих конфигурационных файлах описаны контрольные параметры ресурсов, выделенное дисковое пространство, оперативная память и т.д. Например, при использовании конфига `ve-vswap.512MB.conf-sample`, создается контейнер с дисковым пространством 10GB, оперативной памятью 512MB и swap 512MB: ``` [root@vz ~]# egrep "DISKSPACE|PHYSPAGES|SWAPPAGES|DISKINODES" /etc/vz/conf/ve-vswap.512MB.conf-sample PHYSPAGES="131072:131072" SWAPPAGES="131072" DISKSPACE="10485760:10485760" DISKINODES="655360:655360" ``` Это удобно, так как существует возможность создавать свои конфигурационные файлы для различных вариаций контейнеров. Создадим свой конфигурационный файл, на базе уже существующего `vswap.512MB`. Исправим в нем только значения `PHYSPAGES`, `SWAPPAGES`, `DISKSPACE`, `DISKINODES`: ``` [root@vz ~]# cp /etc/vz/conf/ve-vswap.512MB.conf-sample /etc/vz/conf/ve-vswap.1GB.conf-sample [root@vz ~]# vim /etc/vz/conf/ve-vswap.1GB.conf-sample PHYSPAGES="262144:262144" SWAPPAGES="262144" DISKSPACE="20971520:20971520" DISKINODES="1310720:1310720" ``` Таким образом, при использовании этого конфигурационного файла, будет создаваться контейнер, которому будет доступно 20GB выделенного дискового пространства, 1GB оперативной памяти и 1GB swap. Установка конфигурационного файла шаблона на примере `vswap.1GB` (контейнер должен быть создан): ``` [root@vz ~]# prlctl set ct1 --applyconfig vswap.1GB The CT has been successfully configured. ``` ### Создание контейнера В качестве параметра к идентификатору контейнера может использоваться любое имя: ``` [root@vz ~]# prlctl create ct1 --ostemplate debian-8.0-x86_64 --vmtype=ct Creating the Virtuozzo Container... The Container has been successfully created. ``` Таким образом был создан контейнер с именем `ct1` на базе шаблона `debian-8.0-x86_64`. Теперь можно просмотреть список имеющихся в системе контейнеров: ``` [root@vz ~]# prlctl list -a UUID STATUS IP_ADDR T NAME {3d32522a-80af-4773-b9fa-ea4915dee4b3} stopped - CT ct1 ``` Если же при создании контейнера не указывать желаемый шаблон, то OpenVZ будет использовать шаблон по умолчанию. Конфигурационный файл, в котором указаны директивы по умолчанию `/etc/vz/vz.conf`. По умолчанию, используется шаблон `centos-7` и конфигурационный файл `basic`: ``` [root@vz ~]# egrep "CONFIGFILE|DEF_OSTEMPLATE" /etc/vz/vz.conf CONFIGFILE="basic" DEF_OSTEMPLATE=".centos-7" ``` Если планируется создание большого количества однотипных контейнеров, основываясь на одном и том же конфиге, то значения можно исправить на нужные. ### Настройка контейнера Контейнер создан, его можно запускать. Но перед первым запуском необходимо установить его IP-адреса, hostname, указать DNS сервера и задать пароль суперпользователя. Добавление IP-адресов: ``` [root@vz ~]# prlctl set ct1 --ipadd 192.168.0.161/24 [root@vz ~]# prlctl set ct1 --ipadd fe80::20c:29ff:fe01:fb08 ``` Установка DNS серверов и hostname: ``` [root@vz ~]# prlctl set ct1 --nameserver 192.168.0.1,192.168.0.2 [root@vz ~]# prlctl set ct1 --hostname ct1.vz.localhost ``` Установка поискового домена: ``` [root@vz ~]# prlctl set ct1 --searchdomain vz.localhost ``` Установка пароля суперпользователя: ``` [root@vz ~]# prlctl set ct1 --userpasswd root:eVjfsDkTE63s5Nw ``` Сгенерировать пароль можно штатными средствами Linux: ``` [root@vz ~]# cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 15 | head -1 BC4Ce984DBWVcXc ``` Или воспользоваться утилитой `pwgen`: ``` [root@vz ~]# yum localinstall https://dl.fedoraproject.org/pub/epel/7/x86_64/p/pwgen-2.07-1.el7.x86_64.rpm [root@vz ~]# pwgen -s 15 1 esxrcH7dyoA46LY ``` Пароль будет установлен в контейнер, в файл `/etc/shadow` и не будет сохранен в конфигурационный файл контейнера. Если же пароль будет утерян или забыт, то можно будет просто задать новый. Для запуска контейнера при старте хост-ноды добавляем: ``` [root@vz ~]# prlctl set ct1 --onboot yes ``` Также можно добавить краткое описание контейнера: ``` [root@vz ~]# prlctl set ct1 --description "This is my first container" ``` ### Запуск и вход Запуск контейнера: ``` [root@vz ~]# prlctl start ct1 Starting the CT... The CT has been successfully started. ``` Проверка сетевых интерфейсов внутри гостевой ОС: ``` [root@vz ~]# prlctl exec ct1 ip addr show venet0 2: venet0: mtu 1500 qdisc noqueue state UNKNOWN group default link/void inet 127.0.0.1/32 scope host venet0 valid_lft forever preferred_lft forever inet 192.168.0.161/24 brd 192.168.0.255 scope global venet0:0 valid_lft forever preferred_lft forever inet6 ::2/128 scope global valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe01:fb08/64 scope link valid_lft forever preferred_lft forever ``` Проверка корректности hostname: ``` [root@vz ~]# prlctl exec ct1 hostname ct1.vz.localhost ``` Проверка доступности контейнера в сети и корректность пароля суперпользователя: ``` [root@vz ~]# ssh root@192.168.0.161 root@192.168.0.161's password: eVjfsDkTE63s5Nw root@ct1:~# ``` Вход в контейнер напрямую с хост-ноды: ``` [root@vz ~]# prlctl enter ct1 entered into CT root@ct1:/# exit logout [root@vz ~]# ``` Переход в консоль контейнера: ``` [root@vz ~]# prlctl console ct2 Attached to CT 9d921e42-1087-45e6-bea0-3d706b2d1862 tty2 (type ESC . to detach) CentOS Linux 7 (Core) Kernel 3.10.0-327.3.1.vz7.10.11 on an x86_64 ct2 login: root Password: veig7Ei1iedeVa8 [root@ct2 ~]# ``` Для выхода из консоли необходимо использовать комбинацию клавиш `ESC` + `.` ## [⬆](#toc) Управление контейнерами ### Управление состоянием контейнера Статус контейнера: ``` [root@vz ~]# prlctl status ct1 CT ct1 exist running [root@vz ~]# prlctl status ct2 CT ct2 exist stopped ``` По выводу команды можно увидеть, что контейнер `ct1` запущен, а контейнер `ct2` остановлен. Остановка контейнера: ``` [root@vz ~]# prlctl stop ct1 Stopping the CT... The CT has been successfully stopped. ``` Иногда нужно выключить контейнер как можно быстрее, например если он был подвержен взлому или создает критическую нагрузку на хост-ноду. Для того чтобы срочно выключить контейнер, нужно использовать ключ `--kill`: ``` [root@vz ~]# prlctl stop ct1 --kill Stopping the CT... The CT has been forcibly stopped ``` Перезапуск контейнера: ``` [root@vz ~]# prlctl restart ct1 Restarting the CT... The CT has been successfully restarted. ``` Приостановка контейнера сохраняет текущее состояние контейнера в файл, позволяя восстановить контейнер в то же состояние, в котором он был приостановлен, это может быть полезно, к примеру если перезагружается хост-нода и нужно сохранить состояние процессов в контейнере. Параметр `suspend` приостанавливает контейнер, а `resume` — восстанавливает: ``` [root@vz ~]# prlctl suspend ct1 Suspending the CT... The CT has been successfully suspended. [root@vz ~]# prlctl status ct1 CT ct1 exist suspended [root@vz ~]# prlctl resume ct1 Resuming the CT... The CT has been successfully resumed. ``` Для удаления контейнера существует параметр `delete` (перед удалением, контейнер нужно сначала остановить): ``` [root@vz ~]# prlctl stop ct1 [root@vz ~]# prlctl delete ct1 Removing the CT... The CT has been successfully removed. ``` Команда выполняет удаление частной области сервера (`/vz/private/$UUID`). Для того чтобы смонтировать содержимое контейнера без его запуска существует опция `mount`, для размонтирования — `umount`. Это может пригодиться например для того, чтобы поправить конфигурационные файлы контейнера с хост-ноды, если контейнер не стартует: ``` [root@vz ~]# prlctl mount ct6 Mounting the CT... The CT has been successfully mounted. [root@vz ~]# ls /vz/root/8de0101f-c166-42ce-ad53-a7900b223d46/ bin boot dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var [root@vz ~]# prlctl status ct6 CT ct6 exist mounted [root@vz ~]# prlctl umount ct6 Unmounting the CT... The CT has been successfully unmounted. [root@vz ~]# ls /vz/root/8de0101f-c166-42ce-ad53-a7900b223d46/ [root@vz ~]# ``` Переместить частную область контейнера в другую область можно с помощью параметра `move`: ``` [root@vz ~]# mkdir /home/private [root@vz ~]# prlctl move ct6 --dst /home/private Move the ct6 CT to /home/private... The CT has been successfully moved. [root@vz ~]# ls /home/private/8de0101f-c166-42ce-ad53-a7900b223d46/ dump/ fs/ .lck .owner root.hdd/ scripts/ templates/ .uptime ve.conf .ve.layout .ve.xml ``` Сброс аптайма (времени создания и работы) контейнера: ``` [root@vz ~]# prlctl list -i ct1 | grep Uptime Uptime: 01:15:57 (since 2016-07-31 01:18:41) [root@vz ~]# prlctl reset-uptime ct1 Performing reset uptime operation to the CT... The CT uptime has been successfully reset. [root@vz ~]# prlctl list -i ct1 | grep Uptime Uptime: 00:00:00 (since 2016-08-17 23:18:22) ``` ### Переустановка контейнера Для переустановки ОС в контейнере, существует команда `vzctl reinstall`. Переустановка и старт контейнера (для переустановки нужно сначала остановить контейнер): ``` [root@vz ~]# prlctl stop ct1 [root@vz ~]# vzctl reinstall ct1 --skipbackup ... Container was successfully reinstalled [root@vz ~]# prlctl start ct1 ``` По умолчанию, `vzctl reinstall` без дополнительных параметров, сохраняет все файлы (частную область) прошлого контейнера в каталог `/old` нового контейнера. Для того, чтобы не копировать частную область предыдущего контейнера, необходимо использовать ключ `--skipbackup`. ### Клонирование контейнера OpenVZ позволяет клонировать контейнеры: ``` [root@vz ~]# prlctl clone ct1 --name ct2 Clone the ct1 CT to CT ct2... The CT has been successfully cloned. [root@vz ~]# prlctl list -a UUID STATUS IP_ADDR T NAME {3d32522a-80af-4773-b9fa-ea4915dee4b3} running 192.168.0.161 CT ct1 {54bc2ba6-b040-469e-9fda-b0eabda822d4} stopped 192.168.0.161 CT ct2 ``` При клонировании контейнера необходимо помнить о смене IP-адреса, иначе при попытке запуска будет наблюдаться ошибка: ``` [root@vz ~]# prlctl start ct2 Starting the CT... Failed to start the CT: PRL_ERR_VZCTL_OPERATION_FAILED Unable to add ip 192.168.0.161: Address already in use Failed to start the Container ``` Сначала нужно удалить старые IP-адреса: ``` [root@vz ~]# prlctl set ct2 --ipdel 192.168.0.161/24 [root@vz ~]# prlctl set ct2 --ipdel fe80::20c:29ff:fe01:fb08 ``` Затем добавить новые: ``` [root@vz ~]# prlctl set ct2 --ipadd 192.168.0.162/24 [root@vz ~]# prlctl set ct2 --ipadd fe80::20c:29ff:fe01:fb09 ``` Смена hostname: ``` [root@vz ~]# prlctl set ct2 --hostname ct2.vz.localhost ``` После этого контейнер можно запустить: ``` [root@vz ~]# prlctl start ct2 ``` ### Запуск команд в контейнере с хост-ноды Пример запуска команды в контейнере: ``` [root@vz ~]# prlctl exec ct1 cat /etc/issue Debian GNU/Linux 8 \n \l ``` Иногда бывает нужно выполнить команду на нескольких контейнерах. Для этого можно использовать конструкцию: ``` [root@vz ~]# CMD="cat /etc/issue" [root@vz ~]# for i in `prlctl list -o name -H`; do echo "CT $i"; prlctl exec $i $CMD; done CT ct1 Debian GNU/Linux 8 \n \l CT ct2 Debian GNU/Linux 8 \n \l ``` ## [⬆](#toc) Управление ресурсами контейнеров Доступные контейнеру ресурсы контролируются с помощью набора параметров управления ресурсами. Все эти параметры можно редактировать в файлах шаблонов, в каталоге `/etc/vz/conf/`. Их можно установить вручную, редактируя соответствующие конфиги или используя утилиты OpenVZ. Параметры контроля ресурсов контейнеров условно разделяют на группы: - дисковые квоты - процессор - операции ввода/вывода - память - сеть ### Дисковые квоты Администратор сервера OpenVZ может устанавливать дисковые квоты, в терминах дискового пространства и количества inodes, число которых примерно равно количеству файлов. Это первый уровень дисковой квоты. В дополнение к этому, администратор может использовать обычные утилиты внутри окружения, для настроек стандартных дисковых квот UNIX для пользователей и групп. Для использования дисковых квот, соответствующая директива должна присутствовать в конфигурационном файле OpenVZ: ``` [root@vz ~]# grep DISK_QUOTA /etc/vz/vz.conf DISK_QUOTA=yes ``` Основные параметры: - `DISKSPACE` — общий размер дискового пространства (задается в Kb) - `DISKINODES` — общее число дисковых inodes - `QUOTATIME` — время (в секундах) на которое контейнер может превысить значение soft предела Параметры записываются в конфигурационный файл в виде: ``` COMMAND="softlimit:hardlimit" ``` где: - `COMMAND` — команда (`DISKSPACE` или `DISKINODES`) - `softlimit` — значение которое превышать нежелательно, после пересечения этого предела наступает grace период, по истечении которого, дисковое пространство или inodes прекратят свое существование - `hardlimit` — значение которое превысить нельзя Например, запись: ``` DISKSPACE="19922944:20971520" DISKINODES="1300000:1310720" QUOTATIME="600" ``` означает, что задается `softlimit` для дискового пространства равным ~19G и `hardlimit` равный 20G, то же самое с inodes 1300000 и 1310720 соответственно. Если размер занятого дискового пространства или inodes будет выше `softlimit`, то в течении 600 сек (10 мин), в случае не освобождения дискового пространства или inodes, они прекратят свое существование. Аналогично, можно установить эти параметры с помощью `vzctl`: ``` [root@vz ~]# vzctl set ct1 --diskspace 5G:6G --save Resize the image /vz/private/3d32522a-80af-4773-b9fa-ea4915dee4b3/root.hdd to 6291456K dumpe2fs 1.42.9 (28-Dec-2013) [root@vz ~]# vzctl set ct1 --diskinodes 10000:110000 --save ``` ### Процессор Планировщик процессора в OpenVZ также двухуровневый. На первом уровне планировщик решает, какому контейнеру дать квант процессорного времени, базируясь на значении параметра `CPUUNITS` для контейнера. На втором уровне стандартный планировщик GNU/Linux решает, какому процессу в выбранном контейнере дать квант времени, базируясь на стандартных приоритетах процесса. Основными параметрами управления CPU являются: - `CPUUNITS` — гарантируемое минимальное количество времени процессора, которое получит соответствующий контейнер - `CPUMASK` — привязка контейнера к конкретным процессорам, по умолчанию нагрузка распределяется на все процессоры - `CPULIMIT` — верхний лимит процессорного времени в процентах - `CPUS` — количество используемых процессорных ядер контейнером - `NODEMASK` — привязка ядер NUMA-систем к контейнеру Параметр `CPUUNITS` указывает процессорное время доступное для контейнера. По умолчанию для каждого контейнера это значение равно 1000. То есть, если для контейнера `ct1` установить значение 2000, а для контейнера `ct2` оставить значение 1000, то при равных условиях контейнер `ct1` получит ровно в два раза больше процессорного времени. ``` [root@vz ~]# prlctl set ct1 --cpuunits 2000 set cpuunits 2000 ``` Если система многопроцессорная, то установка параметра `CPUMASK` может пригодиться для привязки контейнера к конкретным процессорам. В случае восьмипроцессорной системы можно, к примеру, привязать контейнер к процессорам 0-3, 6, 7: ``` [root@vz ~]# prlctl set ct1 --cpumask 0-3,6,7 set cpu mask 0-3,6,7 ``` Параметр `CPULIMIT` указывает общий верхний лимит процессорного времени для всех ядер процессора: ``` [root@vz ~]# prlctl set ct1 --cpulimit 15 set cpulimit 15% ``` Для одноядерного процессора верхний лимит будет равен 100%, для двухядерного 200% и так далее. Существует также возможность задания `CPULIMIT` в абсолютных значениях (MHz): ``` [root@vz ~]# prlctl set ct1 --cpulimit 600m set cpulimit 600Mhz ``` В параметре `CPUS` задается число доступных для контейнера процессорных ядер. Контейнер по умолчанию получает в использование все процессорные ядра: ``` [root@vz ~]# CPUINFO="grep processor /proc/cpuinfo" [root@vz ~]# prlctl exec ct1 $CPUINFO processor : 0 processor : 1 processor : 2 processor : 3 ``` Установим для контейнера лимит в 2 процессорных ядра: ``` [root@vz ~]# prlctl set ct1 --cpus 2 set cpus(4): 2 [root@vz ~]# prlctl exec ct1 $CPUINFO processor : 0 processor : 1 ``` Для систем архитектуры NUMA существует возможность привязки контейнера к процессорам NUMA-нод: ``` [root@vz ~]# prlctl set ct1 --nodemask 0 ``` Утилиты контроля ресурсов процессора, гарантируют любому контейнеру количество времени центрального процессора, которое собственно и получает этот контейнер. При этом контейнер может потреблять больше времени, чем определено этой величиной, если нет другого конкурирующего с ним за время CPU сервера. ### Операции ввода/вывода В OpenVZ существует возможность управления дисковыми операциями ввода/вывода. Можно устанавливать значения таких параметров как: - `IOPRIO` - `IOLIMIT` - `IOPSLIMIT` Параметр `IOPRIO` указывает приоритет операция ввода вывода для контейнера. По умолчанию для всех контейнеров установлен равный приоритет (значение 4). Изменение значения параметра можно регулировать от 0 (максимальный приоритет) до 7: ``` [root@vz ~]# prlctl set ct1 --ioprio 6 set ioprio 6 ``` Параметр `IOLIMIT` позволяет ограничивать пропускную способность операций ввода/вывода. По умолчанию параметр имеет значение 0, то есть отсутствие лимитов. Установка значения в MB/s: ``` [root@vz ~]# prlctl set ct1 --iolimit 20 Set up iolimit: 20971520 ``` Существует возможность указания префиксов метрических значений: - `G` — гигабайт - `M` — мегабайт - `K` — килобайт - `B` — байт Максимальная пропускная способность дисковых операций ввода/вывода составляет 2GB/s. Помимо ограничения пропускной способности операций ввода/вывода, существует возможность ограничения количества операций ввода/вывода в секунду. Параметр `IOPSLIMT` позволяет установить численное значение операций ввода/вывода в секунду, например 300: ``` [root@vz ~]# prlctl set ct1 --iopslimit 300 set IOPS limit 300 ``` По умолчанию значение этого параметра равно 0, что означает отсутствие лимитов. Проверка ограничения пропускной способностей операций ввода/вывода на примере `IOLIMIT`. Значение `IOLIMIT` равно 0: ``` root@ct1:/# dd if=/dev/zero of=test bs=1048576 count=10 10+0 records in 10+0 records out 10485760 bytes (10 MB) copied, 0.210523 s, 49.8 MB/s ``` Значение `IOLIMIT` равно 500K: ``` root@ct1:/# dd if=/dev/zero of=test bs=1048576 count=10 10+0 records in 10+0 records out 10485760 bytes (10 MB) copied, 17.4388 s, 601 kB/s ``` ### Память В OpenVZ используется управление памятью четвертого поколения с помощью VCMM. В прошлом же использовалось управление памятью с помощью: - VSwap (третье поколение) - SLM (второе поколение) - User Beancounters (первое поколение) С пользовательской стороны управление памятью с помощью VSwap и VCMM ничем не отличаются, однако с точки зрения реализации, VCMM уже находится в ванильном ядре и не требует патчей со стороны разработчиков OpenVZ. Ограничения физической памяти и swap задаются в конфигурационном файле контейнера параметрами `PHYSPAGES` и `SWAPPAGES`. Значения устанавливаются в блоках, например: ``` PHYSPAGES="262144:262144" SWAPPAGES="262144:262144" ``` равняются значениям в 1024MB (262144 блок / 256 = 1024MB). С помощью `prlctl` значения параметров можно указывать в метрической системе: ``` [root@vz ~]# prlctl set ct1 --memsize 1G --swappages 1G Set the memsize parameter to 1024Mb. Set swappages 262144 ``` Overcommiting — возможность использования большего числа ресурсов, чем выдано контейнеру. Значение `VM_OVERCOMMIT` указывает число, во сколько раз больше памяти сможет использовать контейнер в случае необходимости. По умолчанию значение `VM_OVERCOMMIT` равно 1.5. То есть для контейнера установлено, с 1024MB оперативной памяти и 1024MB swap, суммарно доступно 2048MB памяти, в случае необходимости контейнер сможет использовать (2048MB * 1.5 = 3072MB) памяти. Для изменения значения достаточно прописать параметр в конфигурационный файл контейнера и перезапустить его: ``` VM_OVERCOMMIT="2" ``` Также возможна установка параметра с помощью `vzctl`: ``` [root@vz ~]# vzctl set ct1 --vm_overcommit 2 --save ``` При использовании значения 2 для ранее упомянутого контейнера с 2048MB памяти, будет доступно (2048MB * 2 = 4096MB) памяти. Естественно, если если эти ресурсы доступны на хост-ноде. ### Мониторинг ресурсов С помощью утилиты `vznetstat` можно увидеть входящий и исходящий трафик (в байтах и пакетах) для всех контейнеров: ``` [root@vz ~]# vznetstat UUID Net.Class Input(bytes) Input(pkts) Output(bytes) Output(pkts) 0 0 244486 3024 1567749 2491 54bc2ba6-b040-469e-9fda-b0eabda822d4 0 0 0 0 0 4730cba8-deed-4168-9f9e-34373e618026 0 0 0 0 0 3d32522a-80af-4773-b9fa-ea4915dee4b3 0 2925512 49396 49398885 49254 ``` Для конкретного контейнера можно воспользоваться ключом `-v`: ``` [root@vz ~]# vznetstat -v 3d32522a-80af-4773-b9fa-ea4915dee4b3 UUID Net.Class Input(bytes) Input(pkts) Output(bytes) Output(pkts) 3d32522a-80af-4773-b9fa-ea4915dee4b3 0 2925512 49396 49398885 49254 ``` Утилита `vzstat` позволяет узнать информацию по нагрузке на контейнер, занятым ресурсам и состоянии сети: ``` [root@vz ~]# vzstat -p 3d32522a-80af-4773-b9fa-ea4915dee4b3 -t loadavg 0 0 0 CTNum 3 procs 289 1 288 0 0 0 0 CPU 16 0 2 3 95 sched latency 372 9 Mem 989 360 0 Mem latency 1 0 ZONE0 (DMA): size 15MB, act 4MB, inact 4MB, free 4MB (0/0/1) ZONE1 (DMA32): size 1007MB, act 243MB, inact 274MB, free 355MB (43/54/64) Mem lat (ms): A0 1, K0 0, U0 1, K1 0, U1 0 Slab pages: 62MB/62MB (ino 22MB, de 0MB, bh 1MB, pb 0MB) Swap 952 952 0.000 0.000 Net stats 0.382 5949 5.542 5820 if br0 stats 0.171 2975 2.771 2910 if lo stats 0.000 0 0.000 0 if virbr1-nic stats 0.000 0 0.000 0 if enp0s3 stats 0.211 2975 2.771 2910 if virbr1 stats 0.000 0 0.000 0 Disks stats 0.000 0.000 CTID ST %VM %KM PROC CPU SOCK FCNT MLAT IP ``` `vzpid` позволяет узнать к какому контейнеру принадлежит процесс, это может быть полезно при просмотре списка процессов с хост-ноды и поиска "процесса-грузчика": ``` [root@vz ~]# top ... PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 5625 33 20 0 364432 6232 1284 S 26.2 0.6 0:03.20 apache2 ... [root@vz ~]# vzpid 5625 Pid VEID Name 5625 3d32522a-80af-4773-b9fa-ea4915dee4b3 apache2 ``` Утилита `vzps` аналогична утилите `ps`, она позволяет вывести список процессов и их состояние для конкретного контейнера: ``` [root@vz ~]# vzps aufx -E 3d32522a-80af-4773-b9fa-ea4915dee4b3 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND 0 2432 0.0 0.0 0 0 ? S 20:10 0:00 [kthreadd/3d3252] 0 2433 0.0 0.0 0 0 ? S 20:10 0:00 \_ [khelper] 0 2420 0.0 0.3 28168 3136 ? Ss 20:10 0:00 init -z 101 3088 0.0 0.1 26168 1448 ? Ss 20:10 0:00 \_ /lib/systemd/systemd-networkd 0 3117 0.0 0.1 28856 1620 ? Ss 20:10 0:00 \_ /lib/systemd/systemd-journald 0 3135 0.0 0.1 38916 1624 ? Ss 20:10 0:00 \_ /lib/systemd/systemd-udevd 0 3376 0.0 0.3 55156 3128 ? Ss 20:10 0:00 \_ /usr/sbin/sshd -D 102 3380 0.0 0.1 25732 1092 ? Ss 20:10 0:00 \_ /lib/systemd/systemd-resolved 0 3382 0.0 0.1 25884 1120 ? Ss 20:10 0:00 \_ /usr/sbin/cron -f 0 3388 0.0 0.1 182848 1884 ? Ssl 20:10 0:00 \_ /usr/sbin/rsyslogd -n 0 3433 0.0 0.0 12648 840 ? Ss+ 20:10 0:00 \_ /sbin/agetty --noclear tty2 linux 0 3434 0.0 0.0 12648 840 ? Ss+ 20:10 0:00 \_ /sbin/agetty --noclear --keep-baud console 115200 38400 9600 linux 0 3508 0.0 0.0 20200 956 ? Ss 20:10 0:00 \_ /usr/sbin/xinetd -pidfile /run/xinetd.pid -stayalive -inetd_compat -inetd_ipv6 0 3617 0.0 0.1 65452 1164 ? Ss 20:10 0:00 \_ /usr/sbin/saslauthd -a pam -c -m /var/run/saslauthd -n 2 0 3625 0.0 0.0 65452 836 ? S 20:10 0:00 | \_ /usr/sbin/saslauthd -a pam -c -m /var/run/saslauthd -n 2 0 3755 0.0 0.2 73496 2724 ? Ss 20:10 0:00 \_ /usr/sbin/apache2 -k start 33 5747 0.2 0.5 363364 5300 ? Sl 20:46 0:00 | \_ /usr/sbin/apache2 -k start 0 4074 0.0 0.2 36144 2388 ? Ss 20:10 0:00 \_ /usr/lib/postfix/master 105 4081 0.0 0.2 38208 2316 ? S 20:10 0:00 \_ pickup -l -t unix -u -c 105 4082 0.0 0.2 38256 2336 ? S 20:10 0:00 \_ qmgr -l -t unix -u ``` Утилита `vztop` теперь заменена алиасом на `htop` с отображением UUID контейнера, которому принадлежит процесс: ``` [root@vz ~]# which vztop alias vztop='htop -s CTID' /usr/bin/htop ``` *Утилита vztop* ![vztop](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/vztop.png) ## [⬆](#toc) Проброс устройств в контейнеры ### TUN/TAP Технология VPN позволяет устанавливать безопасное сетевое соединение между компьютерами. Для того чтобы VPN работала в контейнере, необходимо разрешить использование TUN/TAP устройств для контейнера. *Схема работы Virtual Private Network* ![VPN](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/vpn.png) По умолчанию модуль TUN уже загружен в ядро, проверить это можно командой `lsmod`: ``` [root@vz ~]# lsmod | grep ^tun tun 27183 1 ``` Если все-таки модуль отключен, то включить его можно командой `modprobe`: ``` [root@vz ~]# modprobe tun ``` Проброс модуля TUN в контейнер: ``` [root@vz ~]# vzctl set ct3 --devnodes net/tun:rw --save Setting devices Create /etc/tmpfiles.d/device-tun.conf [root@vz ~]# prlctl exec ct3 ls -l /dev/net/tun crw------- 1 root root 10, 200 Feb 10 13:12 /dev/net/tun ``` На этом настройка TUN окончена. Далее необходимо установить ПО для работы с VPN. Например одну из программ: - [OpenVPN](https://openvpn.net) - [tinc](https://tinc-vpn.org) ### FUSE FUSE (Filesystem in Userspace) — модуль ядра Linux, позволяющий создавать виртуальные файловые системы. FUSE может пригодиться, например при монтировании Яндекс.Диска или других виртуальных файловых систем. Для того, чтобы для контейнеров был доступен FUSE, его необходимо включить на хост-ноде: ``` [root@vz ~]# modprobe fuse [root@vz ~]# lsmod | grep fuse fuse 106371 0 ``` Также необходимо добавить модуль в автозагрузку, чтобы он подгружался автоматически при рестарте хост-ноды: ``` [root@vz ~]# echo fuse >> /etc/modules-load.d/vz.conf ``` Включение FUSE для контейнера: ``` [root@vz ~]# vzctl set ct3 --devnodes fuse:rw --save Setting devices Create /etc/tmpfiles.d/device-fuse.conf [root@vz ~]# prlctl exec ct3 ls -l /dev/fuse crw------- 1 root root 10, 229 Feb 10 13:42 /dev/fuse ``` Пример подключения Яндекс.Диска в контейнере: ``` [root@vz ~]# prlctl exec ct3 yum install fuse davfs2 [root@vz ~]# prlctl exec ct3 mount -t davfs https://webdav.yandex.ru /mnt/ Please enter the username to authenticate with server https://webdav.yandex.ru or hit enter for none. Username: user Please enter the password to authenticate user username with server https://webdav.yandex.ru or hit enter for none. Password: pass ``` ### NFS NFS (Network File System) – это сетевая файловая система, позволяющая пользователям обращаться к файлам и каталогам, расположенным на удаленных компьютерах, как если бы эти файлы и каталоги были локальными. По умолчанию модуль ядра NFS уже включен в OpenVZ, поэтому нужно всего лишь пробросить устройство в контейнер. Перед пробросом модуля контейнер нужно остановить: ``` [root@vz ~]# prlctl stop ct1 [root@vz ~]# prlctl set ct1 --features nfsd:on set features: nfsd:on ``` А после – включить и проверить работоспособность сервиса `nfs`: ``` [root@vz ~]# prlctl start ct1 [root@vz ~]# prlctl exec ct1 systemctl start nfs [root@vz ~]# prlctl exec ct1 systemctl is-active nfs active ``` ### PPTP PPTP (Point-to-Point Tunneling Protocol) — туннельный протокол типа точка-точка, позволяющий компьютеру устанавливать защищенное соединение с сервером за счет создания специального туннеля в стандартной, незащищенной сети. PPTP может также использоваться для организации туннеля между двумя локальными сетями. Для работы PPTP в контейнере OpenVZ нужно включить соответствующие модули ядра на хост-ноде. Добавление модулей ядра `ppp_async`, `ppp_deflate`, `ppp_mppe`: ``` [root@vz ~]# modprobe ppp_async [root@vz ~]# modprobe ppp_deflate [root@vz ~]# modprobe ppp_mppe [root@vz ~]# lsmod | grep ppp ppp_mppe 13002 0 ppp_deflate 12950 0 zlib_deflate 26914 1 ppp_deflate ppp_async 17413 0 ppp_generic 33029 3 ppp_mppe,ppp_async,ppp_deflate slhc 13450 1 ppp_generic crc_ccitt 12707 1 ppp_async ``` Добавление модулей в автозагрузку: ``` [root@vz ~]# echo ppp_async >> /etc/modules-load.d/vz.conf [root@vz ~]# echo ppp_deflate >> /etc/modules-load.d/vz.conf [root@vz ~]# echo ppp_mppe >> /etc/modules-load.d/vz.conf ``` Остановка контейнера, проброс устройства и запуск контейнера: ``` [root@vz ~]# prlctl stop ct1 [root@vz ~]# vzctl set ct1 --devnodes ppp:rw --save [root@vz ~]# prlctl start ct1 ``` Проверка работы сервиса: ``` [root@vz ~]# prlctl enter ct1 [root@ct1 ~]# ls /dev/ppp /dev/ppp [root@ct1 ~]# /usr/sbin/pppd ~�}#�!}!}!} }4}"}&} } } } }%}&}0V��}'}"}(}"ty ``` ### Netfilter/IPTables Netfilter — это межсетевой экран в ядре Linux. В OpenVZ существует возможность включать или отключать Netfilter для контейнера. Доступно четыре режима работы Netfilter в контейнере: - disabled — отключены все модули - stateless (по умолчанию) — все модули включены, за исключением NAT и conntracks - stateful — все модули включены, за исключением NAT - full — все модули включены Для изменения параметров Netfilter, контейнер должен быть отключен. Пример отключения всех модулей Netfilter для контейнера: ``` [root@vz ~]# prlctl stop ct1 [root@vz ~]# prlctl set ct1 --netfilter disabled Set netfilter: disabled [root@vz ~]# prlctl start ct1 [root@vz ~]# prlctl exec ct1 iptables -L INPUT iptables v1.4.21: can't initialize iptables table `filter': Table does not exist (do you need to insmod?) Perhaps iptables or your kernel needs to be upgraded. ``` Включение всех модулей: ``` [root@vz ~]# prlctl stop ct1 [root@vz ~]# prlctl set ct1 --netfilter full Set netfilter: full [root@vz ~]# prlctl start ct1 [root@vz ~]# prlctl exec ct1 iptables -L INPUT Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED ACCEPT icmp -- anywhere anywhere ACCEPT all -- anywhere anywhere ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh REJECT all -- anywhere anywhere reject-with icmp-host-prohibited ``` ## [⬆](#toc) SimFS и ploop Для работы OpenVZ с файлами контейнера, существует два метода: - SimFS (каталоги и файлы в файловой системе хост-ноды) - ploop (отдельный файл для каждого контейнера) По умолчанию в OpenVZ используется ploop. SimFS уже давно не используется, и с версии OpenVZ 7 больше не будет поддерживаться. Основные преимущества ploop: - поддержка корректной и надежной изоляции пользователей друг от друга - журнал файловой системы больше не является узким местом - живая миграция - поддержка различных типов хранения данных - быстрое изменение размера контейнера без его отключения ploop может работать только с файловой системой ext4. Для тех, кому требуется использование устаревшего SimFS существует возможность его включения: ``` [root@vz ~]# vim /etc/vz/vz.conf #VEFSTYPE="ext4" VEFSTYPE="simfs" [root@vz ~]# prlctl create ct3 --vmtype=ct [root@vz ~]# ls /vz/private/731a1572-d609-498f-8c8b-8739e336a210/fs/ .autorelabel boot/ etc/ lib/ media/ opt/ root/ sbin/ sys/ usr/ .vzfifo bin/ dev/ home/ lib64/ mnt/ proc/ run/ srv/ tmp/ var/ ``` Для отключения SimFS нужно в файле `/etc/vz/vz.conf` установить переменную `VEFSTYPE="ext4"`. ## [⬆](#toc) Управление снапшотами Перед созданием снапшота рекомендуется закончить установку ПО, загрузку файлов и запись на внешние устройства. Также рекомендуется отменить транзакции во внешние БД. Создание снапшота контейнера: ``` [root@vz ~]# prlctl snapshot ct2 -n FreshCentOS7 -d "Fresh CentOS 7 container" Creating the snapshot... The snapshot with id {aa9649d9-9ed1-408a-9463-36ce0cea6ba7} has been successfully created. ``` где параметр `-n` указываем имя снапшота, `-d` – его описание, описание снапшота всегда указывается в кавычках. Снапшоты сохраняются в каталог `/vz/private/$UUID/dump/`: ``` [root@vz ~]# ls /vz/private/49465252-b780-45f1-9784-538166be2367/dump/ {aa9649d9-9ed1-408a-9463-36ce0cea6ba7} {aa9649d9-9ed1-408a-9463-36ce0cea6ba7}.ve.conf ``` Подробная информация о снапшоте: ``` [root@vz ~]# prlctl snapshot-list ct2 -i {aa9649d9-9ed1-408a-9463-36ce0cea6ba7} ID: {aa9649d9-9ed1-408a-9463-36ce0cea6ba7} Name: FreshCentOS7 Date: 2016-07-31 01:44:43 State: poweroff Description: Fresh CentOS 7 container ``` Список доступных снапшотов для контейнера: ``` [root@vz ~]# prlctl snapshot-list ct2 PARENT_SNAPSHOT_ID SNAPSHOT_ID {aa9649d9-9ed1-408a-9463-36ce0cea6ba7} {aa9649d9-9ed1-408a-9463-36ce0cea6ba7} *{e76f0a0d-aa8e-491f-a720-daa65dfb911a} ``` Символ `*` указывает текущую ветку снапшота: ``` [root@vz ~]# prlctl snapshot-list ct2 -t _{aa9649d9-9ed1-408a-9463-36ce0cea6ba7}*{e76f0a0d-aa8e-491f-a720-daa65dfb911a} ``` Для проверки работы снапшота создадим файл, а потом восстановимся из снапшота, в котором этого файла нет: ``` [root@vz ~]# prlctl exec ct2 touch /root/file.txt [root@vz ~]# prlctl exec ct2 ls /root/file.txt /root/file.txt [root@vz ~]# prlctl snapshot-switch ct2 --id {aa9649d9-9ed1-408a-9463-36ce0cea6ba7} Switch to the snapshot... The CT has been successfully switched. [root@vz ~]# prlctl exec ct2 ls /root/file.txt ls: cannot access /root/file.txt: No such file or directory ``` Удаление снапшота: ``` [root@vz ~]# prlctl snapshot-delete ct2 --id {aa9649d9-9ed1-408a-9463-36ce0cea6ba7} Delete the snapshot... The snapshot has been successfully deleted. ``` При удалении родительского снапшота, снапшоты-потомки не удаляются. ## [⬆](#toc) Работа с виртуальными машинами Помимо создания контейнеров, OpenVZ 7 поддерживает создание и управление виртуальными машинами на базе QEMU/KVM. Утилита `prlctl` имеет возможность создавать и управлять виртуальными машинами, помимо этого также доступно управление с помощью `libvirt`. ### Создание и запуск ВМ Создание виртуальной машины практически ничем не отличается от создания контейнера: ``` [root@vz ~]# prlctl create vm1 --distribution rhel7 --vmtype vm Creating the virtual machine... Generate the VM configuration for rhel7. The VM has been successfully created. ``` Ключ `--distribution` (`-d`) указывает на семейство ОС или дистрибутив для оптимизации виртуального окружения. Список всех официально поддерживаемых ОС: ``` [root@vz ~]# prlctl create vm1 -d list The following values are allowed: win-2000 win-xp win-2003 win-vista win-2008 win-7 win-8 win-2012 win-8.1 win rhel rhel7 suse debian fedora-core fc xandros ubuntu mandriva centos centos7 vzlinux7 psbm redhat opensuse linux-2.4 linux-2.6 linux mageia mint freebsd-4 freebsd-5 freebsd-6 freebsd-7 freebsd-8 freebsd chrome-1 chrome ``` Для каждой виртуальной машины в каталоге `/vz/vmprivate/` создается собственная директория с именем, соответствующим ее UUID: ``` [root@vz ~]# ls /vz/vmprivate/1bdb465a-31e6-46c5-ad7b-947f6ff00208/ config.pvs config.pvs.backup harddisk.hdd ``` Для каждой ВМ имеется как минимум два файла: - файл конфигурации `config.pvs` - виртуальный жесткий диск `harddisk.hdd` В файле конфигурации описываются параметры виртуальной машины в XML-формате. В свою очередь виртуальный жесткий диск может быть двух типов: - plain — диск с фиксированным размером - expanded — диск с изменяемым размером По умолчанию при создании виртуальной машины, создается expanded-диск размером 65G. Просмотр только что созданной ВМ: ``` [root@vz ~]# prlctl list -a UUID STATUS IP_ADDR T NAME {6fe60288-fe50-49fe-a68d-7a8330837358} stopped 192.168.0.161 CT ct1 {2cdb07fd-a68a-4279-81c1-3d269460c2f7} stopped 192.168.0.162 CT ct2 {485372f0-2ae3-4bfe-aa55-e556c37fea9f} stopped - VM vm1 ``` По аналогии с контейнерами установим необходимые параметры для виртуальной машины: ``` [root@vz ~]# prlctl set vm1 --description "Backend for app" [root@vz ~]# prlctl set vm1 --device-set net0 --ipadd 192.168.0.180/24 [root@vz ~]# prlctl set vm1 --device-set net0 --ipadd 192.168.0.180/24 [root@vz ~]# prlctl set vm1 --device-set net0 --ipadd FE80:0:0:0:20C:29FF:FE01:FB07 [root@vz ~]# prlctl set vm1 --nameserver 192.168.0.1,192.168.0.2 [root@vz ~]# prlctl set vm1 --hostname vm1.vz.localhost [root@vz ~]# prlctl set vm1 --memsize 1024 [root@vz ~]# prlctl set vm1 --cpus 2 [root@vz ~]# prlctl set vm1 --cpuunits 1000 [root@vz ~]# prlctl set vm1 --cpulimit 1024m [root@vz ~]# prlctl set vm1 --cpumask 0-1 [root@vz ~]# prlctl set vm1 --ioprio 6 [root@vz ~]# prlctl set vm1 --iolimit 0 [root@vz ~]# prlctl set vm1 --iopslimit 0 ``` Ключ `--videosize` указывает размер выделяемой видеопамяти в MB для виртуальной машины: ``` [root@vz ~]# prlctl set vm1 --videosize 64 ``` Ключ `--autostart` аналогичен `--onboot` для контейнеров, который указывает возможность автостарта контейнера при старте хост-ноды: ``` [root@vz ~]# prlctl set vm1 --autostart on ``` Параметры виртуальной машины установлены, ее можно запускать, однако для установки гостевой ОС необходим соответствующий образ. Для хранения образов ОС можно создать отдельный каталог и централизованно хранить в нем все образы: ``` [root@vz ~]# mkdir /vz/vmprivate/images/ [root@vz ~]# ls /vz/vmprivate/images/ -1 CentOS-7-x86_64-Minimal-1503-01.iso 9200.16384.WIN8_RTM.120725-1247_X64FRE_SERVER_EVAL_RU-RU-HRM_SSS_X64FREE_RU-RU_DV5.ISO ``` Ознакомительные образы Windows Server можно найти по адресу: Установка ВМ с образа `CentOS-7-x86_64-Minimal-1503-01.iso`: ``` [root@vz ~]# prlctl set vm1 --device-set cdrom1 --image "/vz/vmprivate/images/CentOS-7-x86_64-Minimal-1503-01.iso" --iface scsi --position 1 ``` Изменение размера диска до 8G: ``` [root@vz ~]# prl_disk_tool resize --hdd /vz/vmprivate/vm1.pvm/harddisk.hdd --size 8G ``` Просмотр конфигурации виртуальной машины перед запуском: ``` [root@vz ~]# prlctl list vm1 -i | grep Hardware -A9 Hardware: cpu cpus=2 VT-x accl=high mode=32 cpuunits=1000 cpulimit=1024Mhz ioprio=6 iolimit='0' mask=0-1 memory 1024Mb video 64Mb 3d acceleration=highest vertical sync=yes memory_guarantee auto hdd0 (+) scsi:0 image='/vz/vmprivate/vm1.pvm/harddisk.hdd' type='expanded' 8192Mb subtype=virtio-scsi cdrom0 (+) ide:0 image='/vz/vmprivate/vm1.pvm/cloud-config.iso' cdrom1 (+) scsi:1 image='/vz/vmprivate/images/CentOS-7-x86_64-Minimal-1503-01.iso' subtype=virtio-scsi usb (+) net0 (+) dev='vme4292dc5f' network='Bridged' mac=001C4292DC5F card=virtio ips='192.168.0.180/255.255.255.0 FE80:0:0:0:20C:29FF:FE01:FB07/64 ' ``` ### VNC Подключение VNC для ВМ: ``` [root@vz ~]# prlctl set vm1 --vnc-mode manual --vnc-port 5901 --vnc-passwd Oiwaiqud Configure VNC: Remote display: mode=manual port=5901 ``` Также можно предоставить беспарольный доступ к VNC с помощью ключа `--vnc-nopasswd` вместо `--vnc-passwd`. Для каждой виртуальной машины должен быть установлен уникальный порт для VNC. По аналогии с виртуальными машинами, VNC доступен и для контейнеров. Запуск виртуальной машины: ``` [root@vz ~]# prlctl start vm1 ``` Теперь к ВМ можно подключиться по VNC: ``` user@localhost ~ $ sudo apt-get install xvnc4viewer user@localhost ~ $ xvnc4viewer 192.168.0.150:5901 Password: Oiwaiqud ``` *Подключенная VNC-сессия к виртуальной машине* ![VNC](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/vnc.png) Далее следует обычная установка ОС в виртуальную машину. По окончании установки необходимо перезагрузиться. *Установленная гостевая ОС* ![Установленная гостевая ОС](https://raw.githubusercontent.com/vps-server-ru/vz-tutorial/master/images/installed-os.png) После установки ОС, можно соединиться к виртуальной машине по SSH: ``` user@localhost ~ $ ssh root@192.168.0.180 root@192.168.0.180's password: eihaixahghath7A [root@vm1 ~]# ``` ### Дополнения гостевой ОС OpenVZ поддерживает OpenVZ Guest Tools (дополнения гостевой ОС), которые позволяют выполнять некоторые операции в ВМ такие как: - запуск команд в ВМ с помощью `prlctl exec` - установка паролей для пользователей с помощью `prlctl set --userpasswd` - управление сетевыми настройками в ВМ Установка дополнений для `vm1` с хост-ноды: ``` [root@vz ~]# prlctl installtools vm1 Installing... The Parallels tools have been successfully installed. ``` Далее необходимо войти в ВМ, например по SSH и запустить скрипт установки дополнений: ``` [root@vz ~]# ssh root@192.168.0.180 root@192.168.0.180's password: eihaixahghath7A [root@vm1 ~]# mount /dev/cdrom /mnt/ mount: /dev/sr0 is write-protected, mounting read-only [root@vm1 ~]# bash /mnt/install Preparing... ################################# [100%] Updating / installing... 1:qemu-guest-agent-vz-2.5.0-19.el7 ################################# [100%] Preparing... ################################# [100%] Updating / installing... 1:prl_nettool-7.0.1-3.vz7 ################################# [100%] Preparing... ################################# [100%] Updating / installing... 1:vz-guest-udev-7.0.0-2 ################################# [100%] Done! ``` Проверка корректности установки дополнений с хост-ноды: ``` [root@vz ~]# prlctl exec vm1 uname -a Linux vm1.tld 3.10.0-229.el7.x86_64 #1 SMP Fri Mar 6 11:36:42 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux [root@vz ~]# prlctl set vm1 --userpasswd testuser:iel9cophoo2Aisa Authentication tokens updated successfully. [root@vz ~]# prlctl exec vm1 id testuser uid=1000(testuser) gid=1000(testuser) groups=1000(testuser) ``` В гостевой Windows установка дополнений сводится к трем пунктам: - установка драйвера, который находится в `/vioserial//amd64/vioser.inf` - запуск `prl_nettool_.msi` и `qemu-ga-.msi` - проверка работоспособности сервиса `qemu-ga.exe` Автоматическое обновление дополнений гостевой ОС в ВМ: ``` [root@vz ~]# prlctl set vm1 --tools-autoupdate on ``` ### Приостановка виртуальных машин Команды управления контейнерами с помощью `prlctl` аналогично используются и для ВМ: - `set` - `list` - `start` - `stop` - `restart` - `suspend` - `resume` - `exec` - `enter` - `console` - `status` - `create` - `delete` - `mount` - `umount` - `clone` - `move` - `snapshot` Вдобавок к этим командам существует возможность приостанавливать ВМ: ``` [root@vz ~]# prlctl pause vm1 Pause the VM... The VM has been successfully paused. [root@vz ~]# prlctl status vm1 VM vm1 exist paused [root@vz ~]# prlctl start vm1 ``` ### Шаблоны конфигураций На основе уже имеющихся виртуальных машин можно создавать типовые конфигурации. Пример создания шаблона `config-1024MB-centos7`, основанный на ранее настроенной `vm1`: ``` [root@vz ~]# mkdir /etc/parallels/samples [root@vz ~]# cp /vz/vmprivate/vm1.pvm/config.pvs /etc/parallels/samples/config-1024MB-centos7.pvs [root@vz ~]# prlctl create vm3 [root@vz ~]# prlctl list vm3 -i | egrep "cpu|memory|video|hdd0" Boot order: hdd0 cdrom0 cpu cpus=1 VT-x accl=high mode=32 ioprio=4 iolimit='0' memory 512Mb video 32Mb 3d acceleration=highest vertical sync=yes memory_guarantee auto hdd0 (+) scsi:0 image='/vz/vmprivate/vm3.pvm/harddisk.hdd' type='expanded' 65536Mb subtype=virtio-scsi [root@vz ~]# prlctl set vm3 --applyconfig config-1024MB-centos7 [root@vz ~]# prlctl list vm3 -i | egrep "cpu|memory|video|hdd0" Boot order: hdd0 cdrom0 cpu cpus=2 VT-x accl=high mode=32 cpuunits=1000 cpulimit=1024Mhz ioprio=4 iolimit='0' mask=0-1 memory 1024Mb video 64Mb 3d acceleration=highest vertical sync=yes memory_guarantee auto hdd0 (+) scsi:0 image='/vz/vmprivate/vm3.pvm/harddisk.hdd' type='expanded' 8192Mb subtype=virtio-scsi ``` ### Добавление и удаление устройств в ВМ Для каждой виртуальной машины доступно максимальное количество устройств: - 4 IDE или 8 SCSI (HDD, CD/DVD-ROM) устройств - 16 сетевых адаптеров - 4 последовательных (COM) порта - один USB-контроллер - одно FDD устройство Добавление дополнительного HDD для виртуальной машины с Linux: ``` [root@vz ~]# prlctl list vm1 -i | grep hdd Boot order: hdd0 cdrom1 hdd0 (+) scsi:0 image='/vz/vmprivate/vm1.pvm/harddisk.hdd' type='expanded' 8192Mb subtype=virtio-scsi [root@vz ~]# prlctl set vm1 --device-add hdd --size 2048 --iface scsi Creating hdd1 (+) scsi:2 image='/vz/vmprivate/vm1.pvm/harddisk1.hdd' type='expanded' 2048Mb subtype=virtio-scsi Created hdd1 (+) scsi:2 image='/vz/vmprivate/vm1.pvm/harddisk1.hdd' type='expanded' 2048Mb subtype=virtio-scsi [root@vz ~]# prlctl list vm1 -i | grep hdd Boot order: hdd0 cdrom1 hdd1 hdd0 (+) scsi:0 image='/vz/vmprivate/vm1.pvm/harddisk.hdd' type='expanded' 8192Mb subtype=virtio-scsi hdd1 (+) scsi:2 image='/vz/vmprivate/vm1.pvm/harddisk1.hdd' type='expanded' 2048Mb subtype=virtio-scsi ``` После того как диск добавлен, нужно создать на нем раздел и отформатировать его: ``` [root@vz ~]# prlctl enter vm1 [root@vm1 /]# lsblk | grep sd sda 8:0 0 8G 0 disk ├─sda1 8:1 0 500M 0 part /boot └─sda2 8:2 0 7.5G 0 part sdb 8:16 0 2G 0 disk [root@vm1 /]# fdisk /dev/sdb Command (m for help): n Partition type: p primary (0 primary, 0 extended, 4 free) e extended Select (default p): p Partition number (1-4, default 1): First sector (2048-4194303, default 2048): Last sector, +sectors or +size{K,M,G} (2048-4194303, default 4194303): Command (m for help): w [root@vm1 /]# mkfs -t ext4 /dev/sdb1 [root@vm1 /]# mount /dev/sdb1 /mnt/ [root@vm1 /]# tail -1 /etc/mtab >> /etc/fstab ``` С помощью ключа `--device-disconnect` можно отключить устройство от ВМ: ``` [root@vz ~]# prlctl set vm1 --device-disconnect cdrom1 Disconnect device: cdrom1 The device successfully disconnected [root@vz ~]# prlctl list vm1 -i | grep cdrom1 Boot order: hdd0 cdrom1 hdd1 cdrom1 (+) scsi:1 image='/vz/vmprivate/images/CentOS-7-x86_64-Minimal-1503-01.iso' state=disconnected subtype=virtio-scsi ``` Включить устройство можно воспользовавшись ключом `--device-connect`. Чтобы полностью удалить устройство, нужно использовать ключ `--device-del`: ``` [root@vz ~]# prlctl set vm1 --device-del usb Remove the usb device. [root@vz ~]# prlctl set vm1 --device-del cdrom1 Remove the cdrom1 device. [root@vz ~]# prlctl list vm1 -i | egrep "cdrom1|usb" ``` При удалении HDD из виртуальной машины можно сохранить сам виртуальный диск, для этого используется ключ `--detach-only`, по умолчанию диск удаляется, что является умолчанием ключа `--destroy-image`. Изменение приоритета загрузки устройств: ``` [root@vz ~]# prlctl list vm1 -i | grep "Boot order" Boot order: hdd0 hdd1 [root@vz ~]# prlctl set vm1 --device-bootorder "hdd1 hdd0" [root@vz ~]# prlctl list vm1 -i | grep "Boot order" Boot order: hdd1 hdd0 ``` Пример добавления дополнительного сетевого устройства: ``` [root@vz ~]# prlctl set vm1 --device-add net --network Bridged --mac auto --ipadd 192.168.0.181 --gw 192.168.122.1 --nameserver 192.168.0.1 --adapter-type virtio Enable automatic reconfiguration for this network adapter. Creating net1 (+) dev='' ifname='eth1' network='Bridged' mac=001C42AFDC9B card=virtio ips='192.168.0.181/255.255.255.0 ' gw='192.168.0.1' Created net1 (+) dev='vme42afdc9b' network='Bridged' mac=001C42AFDC9B card=virtio ips='192.168.0.181/255.255.255.0 ' gw='192.168.0.1' [root@vz ~]# prlctl list vm1 -i | grep -i net net0 (+) dev='vme4292dc5f' network='Bridged' mac=001C4292DC5F card=virtio ips='192.168.0.180/255.255.255.0 FE80:0:0:0:20C:29FF:FE01:FB07/64 ' net1 (+) dev='vme42afdc9b' network='Bridged' mac=001C42AFDC9B card=virtio ips='192.168.0.181/255.255.255.0 ' gw='192.168.0.1' ``` ### Горячее подключение CPU и RAM Для виртуальных машин доступно горячее подключение (hotplug) ресурсов без перезагрузки самих виртуальных машин. К таким ресурсам относятся оперативная память и процессор. По умолчанию для виртуальных машин горячее подключение отключено. Для добавления оперативной памяти "налету" необходимо установить значение ключа `--mem-hotplug` в `on`: ``` [root@vz ~]# prlctl list vm1 -i | grep "memory " memory 1024Mb [root@vz ~]# prlctl set vm1 --mem-hotplug on set mem hotplug: 1 ``` После установки параметра нужно единожды перезагрузить виртуальную машину и затем изменять количество памяти: ``` [root@vz ~]# prlctl restart vm1 [root@vz ~]# prlctl set vm1 --memsize 1536M Set the memsize parameter to 1536Mb. [root@vz ~]# prlctl list vm1 -i | grep "memory " memory 1536Mb hotplug ``` Для включения CPU hotplug, необходимо чтобы операционная система гостевой ВМ поддерживала данную функцию. На данный момент поддерживаются: - дистрибутивы основанные на RHEL 5 и выше - Windows Server 2008 x64 и выше Включение CPU hotplug происходит по аналогии с MEM hotplug: ``` [root@vz ~]# prlctl list vm1 -i | grep cpu cpu cpus=2 VT-x accl=high mode=32 cpuunits=1000 cpulimit=1024Mhz ioprio=6 iolimit='0' mask=0-1 [root@vz ~]# prlctl set vm1 --cpu-hotplug on set cpu hotplug: 1 ``` Перезагрузка виртуальной машины и проверка ресурсов: ``` [root@vz ~]# prlctl restart vm1 [root@vz ~]# prlctl set vm1 --cpuunits 2000 --cpus 3 --cpumask 0-2 set cpus(4): 3 set cpuunits 2000 set cpu mask 0-2 [root@vz ~]# prlctl list vm1 -i | grep cpu cpu cpus=3 VT-x hotplug accl=high mode=32 cpuunits=2000 cpulimit=1024Mhz ioprio=6 iolimit='0' mask=0-2 ``` Для отключения hotplug используется значения ключей `--mem-hotplug off` и `--cpu-hotplug off` соответственно. ### Оптимизация виртуальных машин с помощью KSM KSM (Kernel Same-Page Merging) — технология ядра Linux, которая позволяет ядру объединять одинаковые страницы памяти между различными процессами или виртуальными гостевыми системами в одну для совместного использования. Технология предусматривает сканирование памяти в целях поиска дубликатов страниц, каждая пара дубликатов объединяется в одну страницу, помечаемую как подлежащую копированию при записи, таким образом ядро будет автоматически разделять страницы памяти, как только один процесс изменит данные. Поиск дубликатов накладывает дополнительную нагрузку на процессорные ресурсы, поэтому в технологии была предусмотрена оценка — насколько часто будут те или иные страницы памяти изменяться, чтобы в тех случаях, когда ресурсные издержки сравнительно высоки не прибегать к слиянию страниц. KSM обеспечивает системам виртуализации возможность перезакладки ресурсов оперативной памяти (memory overcommitment). В условиях достаточно однородных экземпляров гостевых операционных систем возможен значительный эффект, в частности, экспериментальная реализация KSM от Red Hat показала, что 52 виртуальных экземпляра Windows XP с выделенными 1GB памяти, могут работать на хост-ноде с 16GB оперативной памяти. Для включения KSM в OpenVZ необходимо запустить сервисы `ksm` и `ksmtuned`: ``` [root@vz ~]# systemctl start ksm ksmtuned [root@vz ~]# systemctl enable ksm ksmtuned ``` Работоспособность KSM можно проверить на примере общих страниц в памяти (shared memory pages): ``` [root@vz ~]# cat /sys/kernel/mm/ksm/pages_sharing 120990 ``` ## [⬆](#toc) Миграция контейнеров и виртуальных машин В OpenVZ поддерживается "живая" миграция контейнеров и виртуальных машин с использованием CRIU и P.Haul. Пример миграции контейнера `ct3` с хост-ноды `vz-source` на `vz-dest` (192.168.0.190). Создаем и копируем SSH-ключ с `vz-source` на `vz-dest` для беспарольной аутентификации: ``` [root@vz-source ~]# ssh-keygen [root@vz-source ~]# ssh-copy-id root@192.168.0.190 ``` Запускаем миграцию в `screen`: ``` [root@vz-source ~]# screen -S migrate-dest [root@vz-source ~]# prlctl migrate ct3 192.168.0.190 ``` Проверка на `vz-dest` смигрированного контейнера: ``` [root@vz-dest ~]# prlctl list ct3 UUID STATUS IP_ADDR T NAME {4730cba8-deed-4168-9f9e-34373e618026} running 192.168.0.163 CT ct3 ``` ## [⬆](#toc) Расширенная информация о контейнерах и ВМ Подробную информацию о контейнере или виртуальной машине можно получить с помощью параметра `list` с ключом `-i` (`--info`): ``` [root@vz ~]# prlctl list -i ct4 INFO ID: {22c418d7-948b-456e-9d84-d59ab5ead661} EnvID: 22c418d7-948b-456e-9d84-d59ab5ead661 Name: ct4 Description: Type: CT State: running OS: centos7 Template: no Uptime: 00:00:00 (since 2016-02-09 17:04:41) Home: /vz/private/22c418d7-948b-456e-9d84-d59ab5ead661 Owner: root Effective owner: owner GuestTools: state=possibly_installed Autostart: on Autostop: suspend Autocompact: on Undo disks: off Boot order: EFI boot: off Allow select boot device: off External boot device: Remote display: mode=off address=0.0.0.0 Remote display state: stopped Hardware: cpu cpus=unlimited VT-x accl=high mode=32 cpuunits=1000 ioprio=4 memory 512Mb video 0Mb 3d acceleration=highest vertical sync=yes memory_guarantee auto hdd0 (+) image='/vz/private/22c418d7-948b-456e-9d84-d59ab5ead661/root.hdd' type='expanded' 10240Mb mnt=/ venet0 (+) type='routed' ips='192.168.0.164/255.255.255.0 FE80:0:0:0:20C:29FF:FE01:FB10/64 ' Host Shared Folders: (-) Features: Encrypted: no Faster virtual machine: on Adaptive hypervisor: off Disabled Windows logo: on Auto compress virtual disks: on Nested virtualization: off PMU virtualization: off Offline management: (-) Hostname: ct4.vz.localhost DNS Servers: 192.168.0.1 192.168.0.2 Search Domains: 192.168.0.1 ``` Существует также возможность просмотра дополнительной информации о контейнерах: ``` [root@vz ~]# prlctl list -o type,status,name,hostname,dist,ip T STATUS NAME HOSTNAME DIST IP_ADDR CT running ct2 ct2.vz.localhost debian 192.168.0.162 FE80:0:0:0:20C:29FF:FE01:FB09 CT running ct1 ct1.vz.localhost debian 192.168.0.161 FE80:0:0:0:20C:29FF:FE01:FB08 VM stopped vm1 vm1.vz.localhost rhel7 192.168.0.163 FE80:0:0:0:20C:29FF:FE01:FB07 ``` Список всех доступных полей: ``` [root@vz ~]# prlctl list -L uuid UUID envid ENVID status STATUS name NAME dist DIST owner OWNER system-flags SYSTEM_FLAGS description DESCRIPTION numproc NPROC ip IP_ADDR ip_configured IP_ADDR hostname HOSTNAME netif NETIF mac MAC features FEATURES location LOCATION iolimit IOLIMIT netdev NETDEV type T ha_enable HA_ENABLE ha_prio HA_PRIO - - ``` ## [⬆](#toc) Рекомендации системному администратору - если работа хост-ноды замедлилась, для анализа нагрузки можно воспользоваться утилитами `vzps`, `vztop`, `iotop`, `atop` - для обнаружения сетевых проблем можно воспользоваться утилитами `ping`, `traceroute`, `nmap`, `mtr`, `tcpdump`, `nc`, `iftop`, `netstat`, `ss` - `strace` будет верным помощником для отслеживания системных вызовов - используйте RAID для обеспечения сохранности данных - для экстренных ситуаций, когда могут быть проблемы с сетью необходимо всегда иметь под рукой IPMI или KVM-доступ - не перезагружайте хост-ноду без выяснения обстоятельств неполадок, делайте это только в самых крайних случаях - следите за временем на сервере, используйте для синхронизации NTP на хост-ноде - в контейнерах нет смысла устанавливать второй экземпляр NTP, достаточно только указать нужный часовой пояс - не запускайте блобы или скрипты, которые принадлежат VPS, непосредственно с хост-ноды - для поиска руткитов можно воспользоваться утилитами `chrootkit` и `rkhunter` - следите за нагрузкой сервера, обезопасьтесь от DoS/DDoS - используйте системы конфигураций, такие как Puppet, Ansible, Chef, SaltStack, CFEngine если используется большое количество однотипных конфигураций на хост-нодах - делайте резервные копии важных данных - следите за свободным местом на жестких дисках, используйте ротацию логов - следите за пулом IP-адресов, они могут закончиться в самый неподходящий момент - проверяйте каталог `/var/log/`, который содержит логи системы - используйте `iptables`, `fail2ban`, `ipset` - генерируйте сложные для перебора пароли (например с помощью `pwgen`), периодически меняйте их, уведомляйте пользователей об этом - внимательно работайте на сервере под учетной записью `root` - следите за рассылками новостей по безопасности - обновляйте ПО, систему и ее компоненты - следите за правами пользователей, файлов и каталогов на сервере - используйте системы мониторинга ресурсов (например Cacti, Munin, MRTG, Zabbix, Nagios, Icinga, Monit) - ведите внутреннюю документацию по серверам и их настройке - в случае обнаружения проблем, можно обратиться к документации проектов OpenVZ и Virtuozzo, а также задать вопросы на тематических форумах ## [⬆](#toc) Ссылки - - - - - ## [⬆](#toc) Лицензия [![CC BY-SA 4.0](https://licensebuttons.net/l/by-sa/4.0/88x31.png)](https://creativecommons.org/licenses/by-sa/4.0/deed.ru)