Клонирование ОС под шифрованным LVM на меньший по объему диск
В рабочих процессах клонирование Linux-хостов для меня стало обычным делом. Но однажды пришлось клонировать сервер с LVM и шифрованием LUKS на меньший по объему диск. И оказалось не все так просто.
Прошу заметить, у меня работал этот метод исключительно на железных серверах. На KVM с qcow2 дисками это сделать не получилось, система после разблокировки LUKS сваливалась в initframfs с ошибками, что отсутствует
/bin
и/sbin
. Это последствия клонирования с ошибками, возможно надо использовать другие инструменты, напримерdd
.
Ошибки, с которыми я столкнулся на виртуальных машинах
Дано:
Сервер Debian
debian-src
с шифрованным LVM на дискеsda
объемом 20GB, который занят на ~3GB.Чистый диск
sdb
объемом 15GB, на который необходимо перенестиdebian-src
Что не так с шифрованным LVM?
В самом начале я даже и не думал, что что-то может пойти не так, посему просто загрузился с Clonezilla, через режим Expert указал флаг -icds
, который пропускает проверку размера диска назначения. Что позволяет склонировать диск большого объема на диск меньшего объема при условии, что больший диск использует место, не превышающее объем меньшего диска.
Но под конец клонирования я столкнулся с ошибкой нехватки места на диске назначения:
И тут стало ясно: LVM не позволяет просто так склонировать диск, его нужно уменьшать, сложности добавило наличие шифрование LUKS.
Как уменьшить шифрованный LVM?
Для начала загружаемся с Live-CD на debian-src
(У меня под рукой был Linux Mint)
Расшифровываем LUKS
/dev/sda5
, даем тому названиеenc
и выводим информацию по PV (физическим томам) и LV (логическим томам)
root@mint:~# cryptsetup open /dev/sda5 enc
Enter passphrase for /dev/sda5:
root@mint:~# pvs
PV VG Fmt Attr PSize PFree
/dev/mapper/enc debian-src-vg lvm2 a-- 19.50g 44.00m
root@mint:~# lvs
LV VG Attr LSize
root debian-src-vg -wi-ao---- <18.51g
swap_1 debian-src-vg -wi-a----- 976.00m
root@mint:~# df -h /dev/mapper/debian--src--vg-root
Filesystem Size Used Avail Use%
/dev/mapper/debian--src--vg-root 19G 1.3G 16G 8%
Видим, что PV полностью заполнен, а в LV корня свободно 16GB, необходимо PV уменьшить.
Начинаем уменьшать объем LV
debian--src--vg-root
. Уменьшать будем все на 10GB.
root@mint:~# lvresize --resize -y -L -10G /dev/debian-src-vg/root
Do you want to unmount "/media/mint/39551c0b-2da8-4303-8de5-65e7d6c552e9" ? [Y|n] y
fsck from util-linux 2.34
resize2fs 1.45.5 (07-Jan-2020)
Resizing the filesystem on /dev/mapper/debian--src--vg-root to 2230272 (4k) blocks.
The filesystem on /dev/mapper/debian--src--vg-root is now 2230272 (4k) blocks long.
Size of logical volume debian-src-vg/root changed from <18.51 GiB (4738 extents) to <8.51 GiB (2178 extents).
Logical volume debian-src-vg/root successfully resized.
Ключ
-y
разрешает размонтировать LV перед началом ресайза
Если у вас есть swap, то после 2 шага у нас останется свободное пространство между LV root и swap. Давайте удалим его.
root@mint:~# pvs -v --segments
PV VG Fmt Attr PSize PFree Start SSize LV Start Type PE Ranges
/dev/mapper/enc debian-src-vg lvm2 a-- 19.50g 10.04g 0 2178 root 0 linear /dev/mapper/enc:0-2177
/dev/mapper/enc debian-src-vg lvm2 a-- 19.50g 10.04g 2178 2560 0 free
/dev/mapper/enc debian-src-vg lvm2 a-- 19.50g 10.04g 4738 244 swap_1 0 linear /dev/mapper/enc:4738-4981
/dev/mapper/enc debian-src-vg lvm2 a-- 19.50g 10.04g 4982 11 0 free
root@mint:~# pvmove --alloc anywhere /dev/mapper/enc:4738-4981
/dev/mapper/enc: Moved: 2.87%
/dev/mapper/enc: Moved: 100.00%
Обращаем внимание на PE Ranges
и видим, что между LV root
и swap_1
есть свободное пространство, перемещаем swap /dev/mapper/enc:4738-4981
поближе к root.
После перемещения видим, что свободное пространство переместилось в конец:
root@mint:~# pvs -v --segments
PV VG Fmt Attr PSize PFree Start SSize LV Start Type PE Ranges
/dev/mapper/enc debian-src-vg lvm2 a-- 19.50g 10.04g 0 2178 root 0 linear /dev/mapper/enc:0-2177
/dev/mapper/enc debian-src-vg lvm2 a-- 19.50g 10.04g 2178 244 swap_1 0 linear /dev/mapper/enc:2178-2421
/dev/mapper/enc debian-src-vg lvm2 a-- 19.50g 10.04g 2422 2571 0 free
Начинаем уменьшать LUKS партицию. В первую очередь посмотрим размер:
root@mint:~# cryptsetup status enc
/dev/mapper/enc is active and is in use.
type: LUKS2
cipher: aes-xts-plain64
keysize: 512 bits
key location: keyring
device: /dev/sda5
sector size: 512
offset: 32768 sectors
size: 40906752 sectors
mode: read/write
Нужное нам значение — size: 40906752 sectors
Воспользуемся формулой вычитания объема LUKS-партиции: LUKS_size_sectors - значение_уменьшения_в_гб * 1024 * 1024 * 2 = значение для cryptsetup resize
Я уменьшаю LUKS на 10GB, значения в моем случае: 40906752-10*1024*1024*2=19935232
root@mint:~# cryptsetup resize enc -b 19935232
Enter passphrase for /dev/sda5:
Выведем информацию о LUKS партиции, она нам пригодится позже. Нас интересует offset
и size
:
root@mint:~# cryptsetup status enc
/dev/mapper/enc is active and is in use.
...
offset: 32768 sectors
size: 19935232 sectors
...
Деактивируем VG (Группу томов) и закрываем LUKS.
root@mint:~# vgchange -a n debian-src-vg
WARNING: Device /dev/mapper/enc has size of 19935232 sectors which is smaller than corresponding PV size of 40906752 sectors. Was device resized?
WARNING: One or more devices used as PVs in VG debian-src-vg have changed sizes.
0 logical volume(s) in volume group "debian-src-vg" now active
root@mint:~# cryptsetup close enc
Учтите, все LV должны быть отмонтированы, иначе получите ошибку.
Если после этого шага вы примонтируете LUKS обратно, то будет необходимо повторить шаги 4 и 5.
Видим предупреждение о том, что LUKS партиция меньше, чем PV в VG debian-src-vg
. Это мы починим чуть позже.
Начинаем уменьшать саму партицию диска
sda5
, потому что там располагается корень системы.
root@mint:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 1.9G 1 loop /rofs
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 487M 0 part
├─sda2 8:2 0 1K 0 part
└─sda5 8:5 0 19.5G 0 part
root@mint:~# parted /dev/sda
GNU Parted 3.3
Using /dev/sda
(parted) unit s
(parted) p
Model: ATA QEMU HARDDISK (scsi)
Disk /dev/sda: 41943040s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 2048s 999423s 997376s primary ext2 boot
2 1001470s 41940991s 40939522s extended
5 1001472s 41940991s 40939520s logical
Воспользуемся формулой вычисления нового размера партиции: NEW_PARTITION_SECTOR_END = PARTITION_SECTOR_START + (LUKS_SIZE_SECTORS + LUKS_OFFSET_SECTORS) - 1
Значения в моем случае: 1001472+(19935232+32768)-1=20969471
(parted) resizepart 5 20969471
Warning: Shrinking a partition can cause data loss, are you sure you want to continue?
Yes/No? yes
(parted) q
Information: You may need to update /etc/fstab.
Монтируем LUKS, активируем VG и видим, что у нас получилось сжать диски. Но ошибка, что LUKS партиция меньше, чем PV в
debian-src-vg
осталась, сейчас мы ее устраним.
root@mint:~# cryptsetup luksOpen /dev/sda5 enc
Enter passphrase for /dev/sda5:
root@mint:~# vgchange -a y debian-src-vg
WARNING: Device /dev/mapper/enc has size of 19935232 sectors which is smaller than corresponding PV size of 40906752 sectors. Was device resized?
WARNING: One or more devices used as PVs in VG debian-src-vg have changed sizes.
2 logical volume(s) in volume group "debian-src-vg" now active
root@mint:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 487M 0 part
├─sda2 8:2 0 1K 0 part
└─sda5 8:5 0 9.5G 0 part
└─enc 253:0 0 9.5G 0 crypt
├─debian--src--vg-root 253:1 0 8.5G 0 lvm
└─debian--src--vg-swap_1 253:2 0 976M 0 lvm
Уменьшаем размер PV, а также максимально расширим LV root в пределах уменьшенного PV.
root@mint:~# pvresize /dev/mapper/enc
WARNING: Device /dev/mapper/enc has size of 19935232 sectors which is smaller than corresponding PV size of 40906752 sectors. Was device resized?
WARNING: One or more devices used as PVs in VG debian-src-vg have changed sizes.
Physical volume "/dev/mapper/enc" changed
1 physical volume(s) resized or updated / 0 physical volume(s) not resized
root@mint:~# lvresize -l +100%FREE /dev/debian-src-vg/root
Size of logical volume debian-src-vg/root changed from <8.51 GiB (2178 extents) to 8.55 GiB (2189 extents).
Logical volume debian-src-vg/root successfully resized.
root@mint:~# e2fsck -f /dev/debian-src-vg/root
e2fsck 1.45.5 (07-Jan-2020)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/debian-src-vg/root: 37219/561936 files (1.4% non-contiguous), 408261/2230272 blocks
root@mint:~# resize2fs /dev/debian-src-vg/root
resize2fs 1.45.5 (07-Jan-2020)
Resizing the filesystem on /dev/debian-src-vg/root to 2241536 (4k) blocks.
The filesystem on /dev/debian-src-vg/root is now 2241536 (4k) blocks long.
Посмотрим как изменился размер наших дисков, PV и LV. С 19.5G мы уменьшили диск до 9.5G, ровно на 10 гигабайт.
root@mint:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 487M 0 part
├─sda2 8:2 0 1K 0 part
└─sda5 8:5 0 9.5G 0 part
└─enc 253:0 0 9.5G 0 crypt
├─debian--src--vg-root 253:1 0 8.6G 0 lvm
└─debian--src--vg-swap_1 253:2 0 976M 0 lvm
root@mint:~# pvs
PV VG Fmt Attr PSize PFree
/dev/mapper/enc debian-src-vg lvm2 a-- 9.50g 0
root@mint:~# lvs
LV VG Attr LSize
root debian-src-vg -wi-a----- 8.55g
swap_1 debian-src-vg -wi-a----- 976.00m
На этом мы закончили все манипуляции с размерностью дисков. Осталось дело за малым — взять Live CD Clonezilla и, как обычно, склонировать диск в экспертном режиме со флагом
-icds
Процесс клонирования
Загружаемся в Clonezilla, выбираем клонирование
device-device
, режим Expert,disk_to_local_disk
Выбираем наш уменьшенный
sda
как Source disk.
Ставим флаг
-icds
Позволяет склонировать диск большого объема на диск меньшего объема при условии, что больший диск использует место, не превышающее объем меньшего диска.
На этапе клонирования таблицы разметки, выбирайте флаг -k0, чтобы таблица склонировалась с Source диска.
Подтверждаем, что хотим склонировать на выбранный нам sdb диск и ждем окончания клонирования.
Увеличиваем размер диска
После клонирования необходимо расширить второй диск, на который мы склонировали ОС (в моем случае это sdb
)
Загружаемся в Live CD, разблокируем LUKS и проверяем диски. Видим, что скопировалась таблица разделов и система.
root@mint:~# cryptsetup open /dev/sdb5 enc
Enter passphrase for /dev/sdb5:
root@mint:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 487M 0 part
├─sda2 8:2 0 1K 0 part
└─sda5 8:5 0 9.5G 0 part
sdb 8:16 0 15G 0 disk
├─sdb1 8:17 0 487M 0 part
├─sdb2 8:18 0 1K 0 part
└─sdb5 8:21 0 9.5G 0 part
└─enc 253:0 0 9.5G 0 crypt
Попробуем расширить LUKS на максимум.
root@mint:~# cryptsetup -v resize 'enc'
Enter passphrase for /dev/sdb5:
Key slot 0 unlocked.
Command successful.
root@mint:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE
...
sdb 8:16 0 15G 0 disk
├─sdb1 8:17 0 365.3M 0 part
├─sdb2 8:18 0 1K 0 part
└─sdb5 8:21 0 14.7G 0 part
└─enc 253:0 0 14.6G 0 crypt
Теперь мы видим как sdb5
и enc
расширены насколько это возможно
Спойлер: через GParted у вас расширить не получится — выдает ошибку на команде
cryptsetup -v resize
Посмотрим информацию о PV и замечаем, что PV
enc
все еще остался размером в 9.5GiB. Нужно это исправить.
root@mint:~# pvdisplay -m
--- Physical volume ---
PV Name /dev/mapper/enc
VG Name debian-src-vg
PV Size 9.50 GiB / not usable 0
...
Изменяем размер PV.
root@mint:~# pvresize /dev/mapper/enc
Physical volume "/dev/mapper/enc" changed
1 physical volume(s) resized or updated / 0 physical volume(s) not resized
Проверяем размер LV, видим что корень тоже еще не расширен. Изменяем размер LV.
root@mint:~# lvs
LV VG Attr LSize
root debian-src-vg -wi------- 8.55g
swap_1 debian-src-vg -wi------- 976.00m
root@mint:~# lvresize -l +100%FREE /dev/debian-src-vg/root
Size of logical volume debian-src-vg/root changed from 8.55 GiB (2189 extents) to 13.67 GiB (3500 extents).
Logical volume debian-src-vg/root successfully resized.
Проверяем файловую систему и изменяем размер корня
root@mint:~# e2fsck -y /dev/debian-src-vg/root
...
/dev/debian-src-vg/root: ***** FILE SYSTEM WAS MODIFIED *****
/dev/debian-src-vg/root: 24777/561936 files (1.5% non-contiguous), 293922/2241536 blocks
root@mint:~# resize2fs /dev/debian-src-vg/root
resize2fs 1.45.5 (07-Jan-2020)
Resizing the filesystem on /dev/debian-src-vg/root to 3584000 (4k) blocks.
The filesystem on /dev/debian-src-vg/root is now 3584000 (4k) blocks long.
Проверяем размер диска, PV и LV
root@mint:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE
...
sdb 8:16 0 15G 0 disk
├─sdb1 8:17 0 365.3M 0 part
├─sdb2 8:18 0 1K 0 part
└─sdb5 8:21 0 14.7G 0 part
└─enc 253:0 0 14.6G 0 crypt
├─debian--src--vg-root 253:1 0 13.7G 0 lvm
└─debian--src--vg-swap_1 253:2 0 976M 0 lvm
root@mint:~# pvs
PV VG Fmt Attr PSize PFree
/dev/mapper/enc debian-src-vg lvm2 a-- 14.62g 0
root@mint:~# lvs
LV VG Attr LSize
root debian-src-vg -wi-a----- 13.67g
swap_1 debian-src-vg -wi-a----- 976.00m
Все! Теперь мы можем запускаться с нового диска. У меня есть пару серверов, которые я копировал таким образом и они стабильно работают больше полугода.
Эту статью я решил выложить на хабр из-за большого объема, более мелкие заметки я оставляю в своем тг-канале https://t.me/sdnv_funkhole.
Ссылки на ресурсы, которые помогли мне с этой задачей: