Debian 9(CSM启动)在线把系统盘转成RAID | Drown in Codes

Debian 9(CSM启动)在线把系统盘转成RAID | Drown in Codes

需求

服务器上装了两块硬盘其中一块上装了一个Debian现在需要把两块硬盘做成软RAID比较坑的地方在于服务器只有SSH访问没有任何带外管理

环境

开了台类似配置的虚拟机做了个实验系统是Debian 9CSM方式启动用GRUB作为bootloader虚拟机的硬盘配置如下

  1. root@test-2xdisk ~ # lsblk
  2. NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
  3. sr0 11:0 1 1024M 0 rom
  4. vda 254:0 0 30G 0 disk
  5. └─vda1 254:1 0 15G 0 part /
  6. vdb 254:16 0 30G 0 disk
  7. root@test-2xdisk ~ # fdisk -l /dev/vda
  8. Disk /dev/vda: 30 GiB, 32212254720 bytes, 62914560 sectors
  9. Units: sectors of 1 * 512 = 512 bytes
  10. Sector size (logical/physical): 512 bytes / 512 bytes
  11. I/O size (minimum/optimal): 512 bytes / 512 bytes
  12. Disklabel type: dos
  13. Disk identifier: 0xbeefbeef
  14. Device Boot Start End Sectors Size Id Type
  15. /dev/vda1 * 2048 31454975 31452928 15G 83 Linux

配置方法

这一方案的基本原理是先在空硬盘上建立一个degraded的RAID阵列把系统复制进去重启从RAID阵列启动再把原来的系统盘加入RAID阵列

在开始之前我们需要确认以下几点

  • 系统可以使用root用户远程登录
  • 你到该服务器有稳定的网络连接SSH不会频繁掉线

以下所有操作需要使用root用户进行

安装所有必要的程序

  1. apt install mdadm psmisc wget xz-utils

首先我们给空硬盘分区建立一个FD00Linux RAID autodetect类型的分区记得不要用完整个盘的空间后面稍微留一点以防不同硬盘的可用空间不同导致添加硬盘时出现问题

  1. $ fdisk /dev/vdb
  2. Welcome to fdisk (util-linux 2.29.2).
  3. Changes will remain in memory only, until you decide to write them.
  4. Be careful before using the write command.
  5. Device does not contain a recognized partition table.
  6. Created a new DOS disklabel with disk identifier 0x540a0e81.
  7. Command (m for help): n
  8. Partition type
  9. p primary (0 primary, 0 extended, 4 free)
  10. e extended (container for logical partitions)
  11. Select (default p): p
  12. Partition number (1-4, default 1): 1
  13. First sector (2048-62914559, default 2048):
  14. Last sector, +sectors or +size{K,M,G,T,P} (2048-62914559, default 62914559): +28G
  15. Created a new partition 1 of type ‘Linux’ and of size 28 GiB.
  16. Command (m for help): t
  17. Selected partition 1
  18. Partition type (type L to list all types): fd
  19. Changed type of partition ‘Linux’ to ‘Linux raid autodetect’.
  20. Command (m for help): w
  21. The partition table has been altered.
  22. Calling ioctl() to re-read partition table.
  23. Syncing disks.

创建RAID 1阵列

  1. $ mdadm –create /dev/md0 –level=1 –raid-devices=2 missing /dev/vdb1
  2. mdadm: Note: this array has metadata at the start and
  3. may not be suitable as a boot device. If you plan to
  4. store ‘/boot’ on this device please ensure that
  5. your boot-loader understands md/v1.x metadata, or use
  6. –metadata=0.90
  7. Continue creating array? y
  8. mdadm: Defaulting to version 1.2 metadata
  9. mdadm: array /dev/md0 started.

给RAID阵列分区创建文件系统

  1. $ fdisk /dev/md0
  2. Welcome to fdisk (util-linux 2.29.2).
  3. Changes will remain in memory only, until you decide to write them.
  4. Be careful before using the write command.
  5. Device does not contain a recognized partition table.
  6. Created a new DOS disklabel with disk identifier 0x94f402e2.
  7. Command (m for help): n
  8. Partition type
  9. p primary (0 primary, 0 extended, 4 free)
  10. e extended (container for logical partitions)
  11. Select (default p): p
  12. Partition number (1-4, default 1): 1
  13. First sector (2048-58687487, default 2048):
  14. Last sector, +sectors or +size{K,M,G,T,P} (2048-58687487, default 58687487):
  15. Created a new partition 1 of type ‘Linux’ and of size 28 GiB.
  16. Command (m for help): w
  17. The partition table has been altered.
  18. Calling ioctl() to re-read partition table.
  19. Syncing disks.
  20. $ mkfs -t ext4 /dev/md0p1

关掉系统上能关掉的非关键服务全新安装的Debian 9上应该只有这么多如果有别的服务的话一并关掉

  1. systemctl stop fail2ban
  2. systemctl stop cron
  3. systemctl stop rsyslog
  4. systemctl stop systemd-journald
  5. systemctl stop exim4
  6. systemctl stop systemd-timesyncd

卸载掉所有能卸载的文件系统

  1. $ umount -a
  2. umount: /sys/fs/cgroup/systemd: target is busy
  3. (In some cases useful info about processes that
  4. use the device is found by lsof(8) or fuser(1).)
  5. umount: /sys/fs/cgroup: target is busy
  6. (In some cases useful info about processes that
  7. use the device is found by lsof(8) or fuser(1).)
  8. umount: /: target is busy
  9. (In some cases useful info about processes that
  10. use the device is found by lsof(8) or fuser(1).)
  11. umount: /run: target is busy
  12. (In some cases useful info about processes that
  13. use the device is found by lsof(8) or fuser(1).)
  14. umount: /dev: target is busy
  15. (In some cases useful info about processes that
  16. use the device is found by lsof(8) or fuser(1).)
  17. $ swapoff -a

这里报错是正常的这一步完成以后请确认除了根文件系统和虚拟文件系统以外的所有分区已经卸载如果还有程序在占用这些分区可以使用fuser来找到这些程序然后手工关闭它们

开一个tmpfs做我们一会儿移动系统时候使用的根文件系统这里你可以选择复制现有的系统进去但是一个全新安装的Debian 9怎么也有1GiB左右考虑到内存占用问题我们从LXC那儿偷一个315MiB的根文件系统

  1. wget https://images.linuxcontainers.org/images/debian/stretch/amd64/default/20190406_05:24/rootfs.tar.xz
  2. mkdir /tmp/tmproot
  3. mount -t tmpfs none /tmp/tmproot
  4. tar -xvf rootfs.tar.xz -C /tmp/tmproot
  5. rm rootfs.tar.xz

然后我们悄悄把现在的根文件系统换下来

  1. mkdir -p /tmp/tmproot/oldroot
  2. mount –make-rprivate /
  3. pivot_root /tmp/tmproot /tmp/tmproot/oldroot
  4. for i in dev proc sys run; do mount –move /oldroot/$i /$i; done

在新的根文件系统里面装一个SSH daemon替换掉外面那个

  1. cp /oldroot/etc/resolv.conf /etc
  2. apt update
  3. apt install ssh
  4. cp -axr /oldroot/etc/ssh /etc
  5. cp -a /oldroot/etc/{passwd,shadow} /etc
  6. cp -axr /oldroot/root/.ssh /root
  7. systemctl restart ssh

在不断开原有SSH会话的情况下再连接一次服务器确认能够正常连接如果一切正常那么断开原来的SSH会话

最后检查一次原来的根文件系统还有谁在用然后把它们一一关闭kill -15 $PID

  1. $ fuser -vm /oldroot
  2. USER PID ACCESS COMMAND
  3. /oldroot: root kernel mount /oldroot
  4. root 1 ….m systemd
  5. root 300 ….m agetty
  6. root 301 ….m agetty
  7. root 302 ….m agetty
  8. root 303 ….m agetty
  9. root 304 ….m agetty
  10. root 305 ….m agetty
  11. root 3555 f…m systemd-udevd
  12. root 11343 ….m mdadm
  13. root 11395 F…m rsyslogd
  14. root 11405 ….m systemd-journal

最后应该只剩下一个systemd

  1. $ fuser -vm /oldroot
  2. USER PID ACCESS COMMAND
  3. /oldroot: root kernel mount /oldroot
  4. root 1 ….m systemd

这时候我们重启一下systemd本身这样原来的根文件系统就完全不会被占用了daemon-reexec的时候可能因为某些unit导致卡住Ctrl+C即可

  1. $ systemctl daemon-reexec
  2. $ fuser -vm /oldroot
  3. USER PID ACCESS COMMAND
  4. /oldroot: root kernel mount /oldroot

复制原来的文件系统到RAID阵列上

  1. mkdir -p /newroot
  2. mount /dev/md0p1 /newroot
  3. cp -avrfx /oldroot/* /newroot

重建fstab打开/newroot/etc/fstab找到原来的根文件系统改成/dev/md0p1或者UUID

chroot进新系统

  1. for i in dev proc sys run; do mount –bind /$i /newroot/$i; done
  2. chroot /newroot

创建正确的mdadm配置

  1. mdadm –detail –scan >> /etc/mdadm/mdadm.conf

重建initramfs

  1. update-initramfs -u -k all

重建GRUB配置打开/etc/default/grubGRUB_DEVICE如有改成/dev/md0p1然后创建新的GRUB配置

  1. grub-mkconfig > /boot/grub/grub.cfg

安装GRUB到新的物理硬盘

  1. $ grub-install –recheck /dev/vdb
  2. Installing for i386-pc platform.
  3. grub-install: warning: Couldn‘t find physical volume `(null)’. Some modules may be missing from core image..
  4. grub-install: warning: Couldn‘t find physical volume `(null)’. Some modules may be missing from core image..
  5. Installation finished. No error reported.

为了让系统即使仍然从原系统盘引导仍然能从新的mdadm阵列启动我们需要把新的GRUB配置文件复制到原系统盘上

  1. exit # exit chroot
  2. cp /newroot/grub/grub.cfg /oldroot/grub/grub.cfg

重启如果一切正常的话你将会看到RAID阵列被挂载到根上

  1. $ lsblk
  2. NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
  3. sr0 11:0 1 1024M 0 rom
  4. vda 254:0 0 30G 0 disk
  5. └─vda1 254:1 0 15G 0 part
  6. vdb 254:16 0 30G 0 disk
  7. └─vdb1 254:17 0 28G 0 part
  8. └─md0 9:0 0 28G 0 raid1
  9. └─md0p1 259:0 0 28G 0 md /

清空原系统盘数据并加入RAID阵列

  1. swapoff -a
  2. sfdisk -d /dev/vdb | sfdisk /dev/vda
  3. grub-install –recheck /dev/vda
  4. # might need reboot to make kernel read the new partition table
  5. mdadm /dev/md0 -a /dev/vda1

mdadm会开始重建RAID阵列

  1. $ cat /proc/mdstat
  2. Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10]
  3. md0 : active raid1 vda1[2] vdb1[1]
  4. 29343744 blocks super 1.2 [2/1] [_U]
  5. [==>………………] recovery = 13.6% (4009344/29343744) finish=2.1min speed=200467K/sec
  6. unused devices: <none>

至此迁移工作结束


参考