Pull to refresh

Перенос работающей Linux системы на XFS с HDD на SSD меньшего размера

Reading time9 min
Views23K

Привет, Хабр! Представляю вашему вниманию русскоязычную версию статьи "Migrating CentOS system from HDD to smaller SSD on XFS filesystem" автора Denis Savenko.


Cover Image


Данная статья является русскоязычной версией ранее мной же опубликованной статьи на английском языке с небольшими корректировками на аудиторию. Сразу оговорюсь — я не являюсь маньяком линукса или даже профессиональным системным администратором, поэтому вполне вероятно, что порой я мог использовать необычные, или даже глупые решения. Я буду очень благодарен вам, если вы укажете мне на них в комментариях, чтобы я мог улучшить данное руководство вместо того, чтобы просто заминусовать статью. Заранее вас за это благодарю.


Я думаю я не один, кто в какой-то момент решил преобрести себе SSD-диск для работающей системы. В моём случае это была работающая система на CentOS 7 на моём крошечном домашнем сервере. Далее я хотел перенести её "как есть" на новый диск. Но, как оказалось, это не так то просто сделать, учитывая следующее:


  • Новый SSD диск был гораздо меньшего объёма, чем уже установленный HDD (серьёзно, SSD всё ещё весьма дорог по сравнению с дисковыми накопителями).
  • Разделы на прежнем диске были отформатированы в файловой системе xfs. Это и не удивительно, учитывая тот факт, что CentOS, начиная с 7-ой версии предлагает эту файловую систему "по умолчанию" (наряду и с другими системами на основе RHEL, такими как, собственно, Red Hat Enterprise Linux 7, Oracle Linux 7 или Scientific Linux 7).
  • Работающая система должна остаться без изменений, включая конфигурацию, установленное ПО, права доступа и прочие атрибуты файловой системы.

Позвольте мне пояснить, почему описанные мной выше вещи являются серьёзными усложнениями поставленной перед нами задачи.


Во-первых, если бы размер нового диска был таким же или больше, чем у прежнего, можно было бы применить полное клонирование разделов с данными. Для этого существует масса утилит, таких как dd, ddrescue, partclone или даже clonezilla. Единственное, что нужно было бы сделать после, это подправить пару конфигурационных файлов в загрузочном разделе. Если же вы используете LVM для ваших разделов (что также является опцией по умолчанию в CentOS 7), задача могла бы быть ещё проще — в логический том добавляется новый диск, после чего с использованием команды pvmove данные переносятся на другой физический носитель внутри логического тома, и старый диск изымается из раздела, однако это невозможно при меньшем размере нового физического носителя.


Затем, если бы использовалась файловая система, отличная от xfs, например, достаточно популярная ext4, можно было бы "сжать" старый раздел диска до размеров нового диска. Затем выполняются какие либо действия из описанных выше и вы в дамках. Однако, изменение размера разделов в сторону уменьшения на xfs невозможно в силу её реализации — вы можете только увеличить разделы при её использовании.


И последнее, но ничуть не менее важное, если бы перед нами не стояло задачи перенести работающую сконфигурированную систему с сохранением всех метаданных, было бы проще просто установить систему с нуля на новый диск, заранее сохранив пару важных файлов. Это не подходило мне по двум причинам — во-первых волосы становились дыбом при мысли, что мне придётся повторить все те же действия, которые я выполнял на протяжении нескольких дней кряду, а во-вторых — это просто не спортивно. Я был уверен, что при должном понимании технических особенностей, перенос работающей системы на другой диск не должен был быть невыполнимой задачей.


Тем не менее, я выработал и оттестировал как минимум на двух различных окружениях подробный пошаговый план переноса работающей системы, берущий во внимание все вышеописанные ограничения.


Этап 1. Подготовка


Вот список того, что нам потребуется для переноса:


  1. Собственно, подлежащая миграции работающая система. В моём случае это была CentOS 7.4, но я уверен, что ситуация не будет отличаться от любой другой линукс-системы, работающей на xfs.
  2. Live CD или флешка с каким-либо дистрибутивом линукс. Для простоты, я буду отталкиваться от того же CentOS 7.4 Live CD. Я предпочитаю версию с Gnome, но это уже дело вкуса. Выбор этого дистрибутива обусловлен тем, что во-первых, он у меня уже был, а во-вторых с ним сразу поставляется нужный нам для переноса набор утилит, а в частности xfsdump. Я не буду останавливаться здесь на том, как создать загрузочный диск или флешку с Live CD дистрибутивом, так как предполагаю, что хабрачитатель должен справиться с этим и без меня.
  3. Объём данных на прежнем накопителе не должен превышать размер нового диска (будь то SSD или любой другой диск меньшего размера). В моём случае занято было всего порядка 10 ГБ, поэтому я даже не задумывался от чего нужно избавляться.
  4. Чашка горячего кофе.

Этап 2. Миграция


Глотнём кофе и приступим к процессу переноса с запуска системы с подготовленного Live CD дистрибутива. Затем откройте терминал и перейдите в режим суперпользователя при помощи команды su -


Далее в данном руководстве предполагается, что все команды выполняются от имени суперпользователя (root)

Шаг 1. Разрешение удалённого доступа (опционально)


Для меня удобнее иметь удалённый доступ к машине, на которой я буду производить перенос, т.к. я имею возможность просто копипастить заранее подготовленные команды в свой PuTTY терминал. Если вы загрузили это руководство в браузере на целевой машине, смело переходите к следующему шагу — всё, здесь описанное, вам не понадобится.


Для того, чтобы разрешить удалённый доступ, необходимо задать пароль для пользователя root и запустить SSH демон:


su
passwd
systemctl start sshd

Теперь можно подключиться к целевой машине вашим SSH клиентом (например, PuTTY).


Шаг 2. Разбивка диска на разделы


Вы можете использовать вашу любимую утилиту для этого. Например, в Gnome есть предустановленная утилита для управления дисками. Также в интернетах хвалят gparted, однако я намеренно использовал fdisk, т.к, например, gparted просто не распознавал мой NVMe SSD-диск.


Диск следует разбить по образу и подобию прежнего диска. Я не маньяк партиционирования, поэтому моя схема партиционирования была стандартной:


  • /boot — стандартный раздел размером 1GB;
  • swap раздел размером 4G;
  • / — корневой раздел, LVM volume group с наименованием "main", занимающий оставшееся пространство на диске.

Итак, приступим к разбивке нового диска:


lsblk # проверим какое наименование в системе получил новый диск, в моём случае это nvme0n1
fdisk /dev/nvme0n1
n # добавить новый раздел (для /boot)
p # primary partition
# оставляем по умолчанию (1-й раздел)
# оставляем по умолчанию (от начала диска)
+1G # размер для раздела /boot
# готово
n # добавить новый раздел (для новой LVM volume group)
p # primary partition
# оставляем по умолчанию (2-й раздел)
# оставляем по умолчанию (от начала предыдущего раздела)
# оставляем по умолчанию (100% оставшегося места)
# готово
a # установка флага "bootable"
1 # для 10го раздела
p # проверим, всё ли в порядке
w # записываем таблицу партиционирования на диск

Раздел /boot должен быть стандартным линукс-разделом, поэтому сразу создаём файловую систему на нём:


mkfs.xfs /dev/nvme0n1p1 -f

И теперь нам необходимо создать LVM-структуру для второго раздела на диске. Назовём новую LVM-группу newmain (впоследствии переименуем):


pvcreate /dev/nvme0n1p2 # создаем новый физический LVM-диск для раздела
vgcreate newmain /dev/nvme0n1p2 # создаем новую LVM-группу и добавляем в неё только что добавленный физический LVM-диск
lvcreate -L 4G -n swap newmain # создаем логический раздел размером 4 ГБ под swap
lvcreate -l 100%FREE -n root newmain # создаем логический раздел на всё оставшееся место под корень

Теперь мы готовы к созданию файловой системы на новых логических разделах:


mkfs.xfs /dev/newmain/root # создание файловой системы для корневого раздела
mkswap -L swap /dev/newmain/swap # создание swap на новом разделе
swapon /dev/newmain/swap

Шаг 3. Активная фаза


Прежде чем мы начнём, сделаем обе LVM-группы активными (т.к. мы работаем из под Live CD):


vgchange -a y main
vgchange -a y newmain

Создадим директории для точек монтирования, и примонтируем к системе старые и новые разделы наших дисков:


mkdir -p /mnt/old/boot
mkdir -p /mnt/old/root
mkdir -p /mnt/new/boot
mkdir -p /mnt/new/root
mount /dev/sda1 /mnt/old/boot
mount /dev/nvme0n1p1 /mnt/new/boot
mount /dev/main/root /mnt/old/root
mount /dev/newmain/root /mnt/new/root

Убедимся, что всё в порядке при помощи команды lsblk:


lsblk
NAME             MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda                8:0    0 931.5G  0 disk
├─sda1             8:1    0     1G  0 part /mnt/old/boot
└─sda2             8:2    0 930.5G  0 part
  ├─main-swap    253:0    0   3.6G  0 lvm  [SWAP]
  └─main-root    253:1    0 926.9G  0 lvm  /mnt/old/root
nvme0n1          259:0    0 119.2G  0 disk
├─nvme0n1p1      259:3    0     1G  0 part /mnt/new/boot
└─nvme0n1p2      259:4    0 118.2G  0 part
  ├─newmain-swap 253:5    0     4G  0 lvm  [SWAP]
  └─newmain-root 253:6    0 114.2G  0 lvm  /mnt/new/root

Если вы видите что-то наподобие этого, вы всё сделали верно. И здесь начинается настоящая магия — мы собираемся использовать xfsdump для миграции наших данных. Эта утилита достаточно умная и знает о внутреннем устройстве файловой системы xfs, что позволяет ей копировать только занятые данными блоки, что, в свою очередь, во-первых позволяет нам копировать данные на диск меньшего размера, а во-вторых сильно ускоряет процесс переноса. Итак, давайте сделаем дамп данных при помощи этой утилиты, и на лету развернём эти данные на новом месте:


xfsdump -l0 -J - /mnt/old/boot | xfsrestore -J - /mnt/new/boot
xfsdump -l0 -J - /mnt/old/root | xfsrestore -J - /mnt/new/root

Пару слов об использованных флагах:


  • -J уменьшает размер фидбека;
  • - сообщает xfsdump и xfsrestore использовать стандартные потоки stdout и stdin соответственно вместо файлов.

Эта процедура может занять некоторое время (зависит от объёма ваших данных). Поэтому здесь вам пригодится приготовленная заранее чашка кофе, которую самое время выпить, а то остынет.


Если всё прошло хорошо, ваши данные были полностью скопированы с сохранением всех метаданных. Теперь необходимо подправить пару конфигурационных файлов и переустановить Grub2 на новый диск, чтобы сделать его загрузочным.


Шаг 4. Делаем новый диск загрузочным


Первое, что нужно сделать, это узнать UUID для старого и нового загрузочных разделов (/boot) при помощи команды blkid:


blkid
...
/dev/nvme0n1p1: UUID="3055d690-7b2d-4380-a3ed-4c78cd0456ba" TYPE="xfs"
...
/dev/sda1: UUID="809fd5ba-3754-4c2f-941a-ca0b6fb5c86e" TYPE="xfs"
...

Предполагая, что sda1 — прежний раздел \boot, и nvme0n1p1 — новый, производим замену UUID в конфигурационных файлах на новой точке монтирования:


sed -i "s/809fd5ba-3754-4c2f-941a-ca0b6fb5c86e/3055d690-7b2d-4380-a3ed-4c78cd0456ba/g" /mnt/new/root/etc/fstab
sed -i "s/809fd5ba-3754-4c2f-941a-ca0b6fb5c86e/3055d690-7b2d-4380-a3ed-4c78cd0456ba/g" /mnt/new/boot/grub2/grub.cfg

Эти две команды подготовят ваши системные файлы конфигурации к новому диску.


Теперь самое время переименовать LVM-группы и отмонтировать диски:


umount /mnt/{old,new}/{boot,root}
vgrename -v {,old}main
vgrename -v {new,}main

Единственное, что осталось сделать, это переустановить загрузчик. Это необходимо делать с использованием chroot:


mount /dev/main/root /mnt
mkdir -p /mnt/boot
mount /dev/nvme0n1p1 /mnt/boot
mount -t devtmpfs /dev /mnt/dev
mount -t proc /proc /mnt/proc
mount -t sysfs /sys /mnt/sys
chroot /mnt/ grub2-install /dev/nvme0n1

Шаг 5. Последний штрих


На данном этапе все данные уже должны быть перенесены и новый диск должен стать загрузочным. Нужно только перезапуститься, вынуть Live CD из привода, и выбрать новый диск в BIOS для загрузки:


systemctl reboot -f

Если что-то пошло не так и система не загружается, вы всегда можете "откатиться" на старый диск, просто запустившись с Live CD повторно и переименовав LVM-группы обратно, выполнив vgrename -v {,new}main и vgrename -v {old,}main, и затем снова перезапуститься.

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




Использование старого HDD в качестве медиа-хранилища


Если вы, как и я, после переноса системы, хотите использовать ваш прежний диск как медиа-хранилище, это делается также легко.


Во-первых, переразбейте прежний диск


fdisk /dev/sda
d # удалить раздел 2
d # удалить раздел 1
n # новый раздел
p # primary partition
# раздел 1
# от начала
# до конца диска
# готово
p # проверим, что всё хорошо
w # перезапишем таблицу партиционирования

Мы не станем создавать файловую систему на диске напрямую. Вместо этого мы создадим новую LVM-группу, в которую добавим этот диск. Это позволит нам в будущем легко добавлять новые диски в эту группу без лишней мороки (логический диск при этом останется прежний):


pvcreate /dev/sda1 # новый физический LVM-диск
vgcreate media /dev/sda1 # новая LVM-группа
lvcreate -l 100%FREE -n media1 media # новый логический топ размером во весь добавленный диск
vgchange -a y media # делаем новую LVM-группу активной

mkfs.xfs /dev/media/media1 # создаем файловую систему на логическом диске

mkdir -p /var/media # создаем директорию для точки монтирования
mount /dev/media/media1 /var/media # монтируем новый диск к системе

Для того, чтобы сохранить изменения после перезагрузки системы, следует также добавить запись о точке монтирования в /etc/fstab:


/dev/mapper/media-media1 /var/media                       xfs     defaults        0 0

Готово!


Теперь можно утверждать, что мы успешно перенесли работающую на xfs систему на новый диск меньшего размера. Как бонус, мы начали использовать прежний диск в качестве медиа-хранилища.




UPDATE 02.04.2018


Так как мы производили перенос системы на SSD, то, как советуют в комментариях, хорошо бы уже после переноса в работающей системе включить периодическое исполнение команды trim (сборщик мусора для SSD-дисков, который позволяет не терять в производительности через время). Для этого необходимо выполнить команду:


systemctl enable fstrim.timer

Это включит на новой системе исполнение trim раз в неделю на любой systemd системе. В случае, если вы или ваша система не используете systemd, есть исчерпывающее руководство от DigitalOcean на почти любой случай.




Пожалуйста, оставляйте ваши комментарии, если нашли ошибку или знаете способ лучше как выполнить те или иные действия. Надеюсь, данная инструкция окажется вам полезной!

Tags:
Hubs:
+4
Comments25

Articles