Организация разделов на системном диске в облаке Селектел

в 10:53, , рубрики: LVM, selectel cloud, Блог компании Селектел, Облачные вычисления, руководство пользователя, системное администрирование, метки: , ,

abstract: Этот пост описывает организацию системного диска на машинах в облаке и объясняет, почему именно так.

Предисловие: Всё написанное тут касается системных дисков создаваемых при установке виртуальных машин. Пользователи имеют полное право делать что хотят с этими дисками, и уж, тем паче, решать самостоятельно, как организовывать место на дополнительных дисках.

Мотивация

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

Вот проблемы, которые возникают в связи с этим:

  • Возможность изменить размер диска и корневой файловой системы
  • Возможность создать дополнительные разделы
  • Возможность подключить диски от одной машине к другой
  • С этого диска надо ещё и загрузиться

Наиболее примитивным решением является файловая система на весь диск (/dev/xvda подмонтирован как '/'). Её очень легко менять в размере, после изменения размера блочного устройства достаточно просто запустить команду «ресайз» для файловой системы. Её так же легко подключить к другим виртуальным машинам. Однако, отсутствие таблицы разделов приводит к тому, что дополнительные разделы создать нельзя — обычный колхоз: рут, home и /var/www (у кого-то это /srv/www, у кого-то /home/websitename и т.д.) оказываются на одном разделе с /var/log и прочими служебными файлами. Легко, просто, но на роль продвинутого инструмента совсем не тянет. А главное, новые разделы можно сделать только подключив дополнительные диски. Более того, даже swap-раздел не сделать, приходится изголяться с fallocate или dd для создания файла подкачки.

Второй вариант — старая-добрая таблица разделов. /dev/xvda1, /dev/xvda5, /dev/xvda6 и т.д. Плюсы: просто, понятно, легко подключать к другим машинам, но очень трудно менять размер, например, root'а. Нужно удалить раздел подкачки, изменить размер раздела в таблице разделов, изменить размер файловой системы, что-то сделать с файлом подчкачки. Если же на диске есть разделы с данными, нужно запускать жуткие и опасные процедуры перемещения таблицы разделов (а с учётом платных дисковых операций это вообще не вариант).

И, наконец, третий вариант — LVM. Что хорошо: ресайз файловой системы возможен и очень прост. Легко добавлять/удалять разделы. При этом мы имеем некоторые решаемые проблемы с подключением дисков в другие машины (как и какие там проблемы — см. ниже). Однако, есть маленькая проблемка. С lvm мы грузиться не умеем. Совсем.

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

Наше решение

На системном диске создаётся таблица разделов с двумя primary (первичными) разделами: /dev/xvda1 — /boot и /dev/xvda2 — физический том для LVM. Загрузка ядра идёт с /dev/xvda1, который маленький и (по-хорошему) не должен меняться в размере, файловая система и файл подкачки — на LVM внтури второго раздела.

Плюсы? Можно решить все задачи: изменение размеров раздела, подключение к другим машинам, загрузка, создание неограниченного числа разделов.
Минус: ресайз уже не «легко и просто» — чуть-чуть придётся напрячься. Но, всё-таки возможен с разумными усилиями.

Так как нерешённых проблем в этом варианте не осталось, мы остановились на нём. Я бы, конечно, предпочёл иметь «чистый LVM», но его парсинг из pygrub слишком сложен, особенно с учётом наличия вышестоящего LVM (мы используем LVM over iSCSI для хранения дисков клиентов).

Типовые операции

Начнём с самой частой — изменение размеров системного раздела.

  1. Увеличить размер блочного устройства (панель управления)
  2. Выполнить команду ptmax /dev/xvda2
  3. Перезагрузиться (спасибо линуксу, отказывающемуся делать перечитывание заблокированного диска с корневым разделом)
  4. Выполнить команду pvresize /dev/xvda2
  5. Посмотреть на свободные PE в VG: vgdisplay
  6. Увеличить размер логического тома: lvresize /dev/../sys -l +(число свободных extents)
  7. Изменить размер файловой системы: resize2fs /dev/../sys

Сложно? Да. Гибко и функционально? Да! Почему? Потому что использование LVM открывает множество «обходных» путей. Например, можно увеличивать размер раздела, который не является последним в списке. Или, например, легко можно создать любое число нужных логических томов.

Немного о ptmax. Так получилось, что эту утилиту нам (мне) пришлось написать с нуля. Самого кода там — с гулькин нос, большую часть составляют проверки «правильно ли всё делаем». Суть утилиты — если в таблице разделов у раздела есть свободное место за ним, увеличивает раздел до максимально возможного размера. Типовой сценарий для увеличения размера диска виртуальной машины.

Раньше это приходилось делать методом «удаления/пересоздания» раздела в fdisk, что мягко говоря, было не очень безопасно. Утилита под GPL, традиционно на гитхабе: github.com/amarao/ptmax.

Немного о многоточии. Вместо многоточия следует использовать tab использовать имя VG, которое используется в машине. Имя VG совпадает с hostname на момент установки. Почему мы используем его? Потому что если бы мы использовали одно и то же имя, то при подключении диска в другую машину возникала бы коллизия (причём коллизию можно было бы решить, переименовав VG, но только в одну сторону — задать такое же имя для второго VG в системе нельзя). Так что у каждого VG каждой машины «своё» имя. Упреждая вопросы: использовать одинаковое имя сервера для двух разных виртуальных машин — муветон. Случай подключения снапшота мы разберём чуть ниже.

Второй типовой сценарий — создание ещё одного раздела. По большому счёту, мало отличается от первой процедуры:

  1. Увеличить размер блочного устройства (панель управления)
  2. Выполнить команду ptmax /dev/xvda2
  3. Перезагрузиться (спасибо линуксу, отказывающемуся делать перечитывание заблокированного диска с корневым разделом)
  4. Выполнить команду pvresize /dev/xvda2
  5. Посмотреть на свободные PE в VG: vgdisplay
  6. Создать раздел: lvcreate /dev/VGNAME -n LVNAME -L XXXMb
  7. Создать файловую систему на нём: mkfs.ext4 /dev/VGNAME/LVNAME
  8. подмонтировать систему и прописать её в fstab

Следующий сценарий чуть более сложный — подключение диска на «чужой» виртуальной машине.

После подключения диска нужно активировать VG:

  1. pvscan /dev/xvdb (или другое имя устройства)
  2. vgscan
  3. lvscan
  4. lvdisplay
  5. lvchange -a y /dev/VGNAME/LVNAME (виден в выводе предыдущего пункта)
  6. mount/umount

После окончания работ, если диск нужно отключать, нужно сделать «деактивацию»:

  1. lvchange -a n /dev/VGNAME/LVNAME
  2. vgchange -a n /dev/VGNAME
  3. pvchange -a n /dev/xvdb

После этого диск можно будет отключать «на ходу».

Автор: amarao

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js