Знакомая боль: на сервере кончилось место под /var, базе нужно срочно расширить раздел, а ты сидишь и в полночь руками гоняешь pvcreate, vgextend, lvextend, resize2fs - и на каждом шаге шанс промахнуться буквой и убить чужие данные. Один сервер - терпимо. Тридцать однотипных нод - уже катастрофа. Именно тут заходит ansible lvm: ты один раз описываешь желаемое состояние диска, и Ansible сам приводит к нему любое количество машин, причём идемпотентно. Прогнал плейбук дважды - второй раз ничего не меняется, потому что состояние уже достигнуто.
Для тех, кто готовится к RHCE (EX294), это не теория, а хлеб с маслом. Сборка LVM (lvg/lvol) на новом диске и расширение тома без простоя - типовая экзаменационная задача. На ней регулярно срезаются: то порядок задач перепутают, то filesystem забудут растянуть, то resize запустят там, где данные жалко. Разберём всю цепочку по косточкам.

Механика: из чего собирается LVM и какие модули за это отвечают
Напомню физику в трёх словах. LVM - это слой абстракции между блочным устройством и файловой системой. Снизу вверх:
- PV (physical volume) - физический том, то есть размеченный раздел диска или весь диск.
- VG (volume group) - группа томов, общий "пул" места, собранный из одного или нескольких PV.
- LV (logical volume) - логический том, который нарезается из пула VG. Вот на нём уже живёт файловая система.
В Ansible этим заведуют модули из коллекции community.general (она входит в стандартный ansible пакет, отдельно ставить обычно не надо):
- community.general.parted - размечает диск, создаёт раздел с флагом lvm.
- community.general.lvg - создаёт и расширяет volume group из физических томов. PV он создаёт сам неявно из указанных в pvs устройств - отдельного модуля под pvcreate в типовом сценарии не нужно.
- community.general.lvol - создаёт логический том, задаёт его размер, расширяет (в том числе на +100%FREE) и при желании растягивает ФС параметром resizefs.
- community.general.filesystem - кладёт на LV файловую систему (xfs, ext4 и т.д.).
- ansible.posix.mount - монтирует и прописывает запись в /etc/fstab.
Практика: ansible lvg и ansible lvol - собираем LVM на новом диске
Допустим, в систему воткнули чистый диск /dev/sdb. Хотим: раздел под LVM, группу vg_data, том lv_app на 5 ГиБ с XFS, смонтированный в /opt/app. Вот рабочий ansible lvm пример целиком.
Код: Выделить всё
---
- name: Собрать LVM на новом диске
hosts: storage
become: true
tasks:
- name: Создать GPT-раздел под LVM на /dev/sdb
community.general.parted:
device: /dev/sdb
number: 1
label: gpt
flags: [lvm]
part_start: 0%
part_end: 100%
state: present
- name: Создать volume group из раздела
community.general.lvg:
vg: vg_data
pvs:
- /dev/sdb1
state: present
- name: Создать логический том на 5 ГиБ
community.general.lvol:
vg: vg_data
lv: lv_app
size: 5g
state: present
- name: Положить XFS на логический том
community.general.filesystem:
fstype: xfs
dev: /dev/vg_data/lv_app
- name: Смонтировать и прописать в fstab
ansible.posix.mount:
path: /opt/app
src: /dev/vg_data/lv_app
fstype: xfs
state: mounted
Короткая пометка по дистрибутивам. Команды и пути выше - для RHEL/Fedora/RED OS/Astra, то есть всего systemd-семейства; модули LVM от дистрибутива не зависят, потому что под капотом вызывают одни и те же утилиты lvm2. Разница лишь в имени файловой системы: на RHEL по умолчанию принято брать xfs, на Debian/Ubuntu чаще ext4 - но fstype в модуле ты задаёшь явно, так что плейбук переносим как есть. Учти только, что xfs физически нельзя уменьшить, его можно лишь растить.
Расширение тома без простоя - то, ради чего всё затевалось
Самый частый реальный кейс: место кончилось, надо добавить, не выгоняя сервис. Тут модуль ansible lvol раскрывается в полную силу. Конструкция size с плюсом означает "добавить к текущему размеру", а 100%FREE - "забрать всё свободное место группы".
Код: Выделить всё
- name: Растянуть том на всё свободное место VG и расширить ФС
community.general.lvol:
vg: vg_data
lv: lv_app
size: +100%FREE
resizefs: true
А что если ты сначала увеличил сам диск (например, расширил виртуальный диск в гипервизоре или облаке)? Тогда раздел и PV не знают, что под ними стало больше места. На этот случай у lvg есть параметр pvresize: он перечитывает размер физических томов и подтягивает группу.
Код: Выделить всё
- name: Подтянуть размер PV после роста диска
community.general.lvg:
vg: vg_data
pvs:
- /dev/sdb1
pvresize: true
Типичные грабли
- Перепутан порядок задач. lvol до lvg, lvg до parted - и плейбук падает с "volume group not found" или "device not found". Зависимость линейная, не ленись держать её в правильной последовательности.
- Забыт resizefs. Том вырос, ФС нет. Симптом - df показывает старый объём при том, что lvs показывает новый. Лечится повторным проходом lvol с resizefs: true.
- Уменьшение тома. Расширение онлайн безопасно, а вот сжатие - нет. XFS уменьшить вообще нельзя в принципе. ext4 можно, но только на размонтированном томе и заранее ужав ФС. Модуль lvol по умолчанию не даст ужать LV без явного shrink: true именно потому, что это операция с риском потери данных. Не сжимай боевые тома на автопилоте.
- parted на диске с данными. Модуль управляет таблицей разделов. Промахнулся device-ом, указал диск с живой разметкой - и снёс чужие данные. На проде всегда сверяй имя устройства, а лучше прогоняй в режиме --check на тестовой машине.
- Имена устройств "плавают". /dev/sdb сегодня может стать /dev/sdc после перезагрузки или добавления контроллера. Для критичных вещей опирайся на стабильные идентификаторы (by-id, by-path), а не на короткие имена.
Возьми тестовую виртуалку RHEL/Fedora (или RED OS) и добавь ей второй чистый диск.
- Напиши плейбук, который проходит всю цепочку parted -> lvg -> lvol -> filesystem -> mount и монтирует том на 2 ГиБ в /srv/lab.
- Прогони его дважды. Убедись, что второй прогон полностью идемпотентен (changed=0).
- Расширь том на +100%FREE с resizefs: true и проверь результат через df -h и lvs - цифры должны совпасть.
- Добавь в группу второй PV (ещё один раздел), снова растяни том и убедись, что место пришло из нового диска.
- Для самопроверки глянь lsblk, vgdisplay и cat /etc/fstab - запись о монтировании должна быть на месте.
- В каком порядке должны идти задачи parted, lvg, lvol, filesystem, mount и почему этот порядок нельзя менять?
- Что делает size: +100%FREE и зачем рядом обязателен resizefs: true?
- Чем pvresize в модуле lvg отличается от расширения через lvol и когда он нужен?
- Почему расширение тома Ansible делает безопасно онлайн, а уменьшение требует осторожности и отдельного флага?
LVM в Ansible - это пять модулей community.general и ansible.posix, выстроенных в строгую цепочку parted -> lvg -> lvol -> filesystem -> mount. Создание описывается декларативно и идемпотентно, расширение тома делается онлайн без простоя через +100%FREE и resizefs, а pvresize подтягивает группу после роста физического диска. Держи в голове порядок задач, не забывай растягивать ФС и трижды думай перед уменьшением - и LVM-задача на EX294 перестанет быть проблемой.