centos6에서 기본적으로 깔려 있는 grub version은 0.97이다.
centos7로 올라가면서 grub version이 2로 올라가게 되는데 이건 설치하는게 굉장히 쉽고 간편하게 되어 있다. grub.conf file도 자동으로 알아서 만들어주는 tool(grub2-mkconfig)이 있다.
centos6에서 grub을 제대로 설치하고, 설정을 해주려면 산넘고 물건너야 비로소 가능하다.
이 글에서는 P2V(physical to virtual)환경을 기준으로 test를 하였다.
일단 root filesystem을 담을 image file을 하나 생성한다.
[root@kvm2 scpark]# truncate -s 15G roro-`date +%Y%m%d`-3.raw [root@kvm2 scpark]# ls -atl --block-size G roro-`date +%Y%m%d`-3.raw -rw-r--r--. 1 root root 15G Aug 18 00:53 roro-20180818-3.raw [root@kvm2 scpark]# du -sh roro-`date +%Y%m%d`-3.raw 0 roro-20180818-3.raw [root@kvm2 scpark]# |
- truncate로 15GB짜리 텅 빈 sparse file을 만들었다.
그리고 root filesystem을 옮겨오기 위한 filesystem을 만들어준다.
[root@kvm2 scpark]# losetup -P -f roro-20180818-3.raw [root@kvm2 scpark]# lsblk ... loop2 7:2 0 15G 0 loop [root@kvm2 scpark]# losetup -a ... /dev/loop2: [2097]:59871267 (/data3/scpark/roro-20180818-3.raw) [root@kvm2 grub]# fdisk -l /dev/loop2 Disk /dev/loop2: 16.1 GB, 16106127360 bytes 255 heads, 63 sectors/track, 1958 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00000000 Device Boot Start End Blocks Id System /dev/loop2p1 * 1 131 1047552 83 Linux /dev/loop2p2 131 1958 14679040+ 83 Linux [root@kvm2 scpark]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT ... loop2 7:2 0 15G 0 loop ├─loop2p1 259:0 0 1023M 0 loop └─loop2p2 259:2 0 14G 0 loop [root@kvm2 scpark]# |
- losetup을 이용해서 file을 loopback device처럼 보이게 만들었다. 이때 -P옵션은 partscan으로 loopback device에서 partition을 만들었을때 제대로 devname이 잘 보이게끔 해주는 역할을 한다.
- 아래는 fdisk를 이용해서 partition을 만들었다. grub version 0.97에서는 MBR partition table만 지원한다.
그리고 format을 해주자.
[root@kvm2 scpark]# mkfs.ext2 -I 128 /dev/loop2p1 mke2fs 1.42.9 (28-Dec-2013) Discarding device blocks: done Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 65536 inodes, 261888 blocks 13094 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=268435456 8 block groups 32768 blocks per group, 32768 fragments per group 8192 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Writing superblocks and filesystem accounting information: done [root@kvm2 scpark]# dumpe2fs /dev/loop2p1|grep -i 'inode size' dumpe2fs 1.42.9 (28-Dec-2013) Inode size: 128 [root@kvm2 scpark]# mkfs.xfs /dev/loop2p2 meta-data=/dev/loop2p2 isize=512 agcount=4, agsize=917440 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=0, sparse=0 data = bsize=4096 blocks=3669760, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=1 log =internal log bsize=4096 blocks=2560, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 [root@kvm2 scpark]# |
- grub version이 낮으면 filesystem의 inode size가 128보다 높을경우 문제가 생길 수 있어서 -I옵션을 이용해서 inode size를 128로 주었다.
mount를 해주고, 기존 physical server에 있는 root filesystem file들을 가져오자.
[root@kvm2 scpark]# mkdir /mnt/loop2 [root@kvm2 scpark]# mount /dev/loop2p2 /mnt/loop2 [root@kvm2 scpark]# mkdir /mnt/loop2/boot [root@kvm2 scpark]# mount /dev/loop2p1 /mnt/loop2/boot [root@kvm2 scpark]# ls -atl /mnt/loop2/ total 4 drwxr-xr-x. 3 root root 18 Aug 18 01:30 . drwxr-xr-x. 7 root root 70 Aug 18 01:29 .. drwxr-xr-x. 3 root root 4096 Aug 18 01:25 boot [root@kvm2 scpark]# df -h ... /dev/loop2p2 14G 33M 14G 1% /mnt/loop2 /dev/loop2p1 1015M 1.3M 963M 1% /mnt/loop2/boot [root@kvm2 scpark]# [root@kvm2 loop2]# rsync -avg --exclude=/proc --exclude=/dev --exclude=/sys --exclude=/boot 192.168.4.13:/ /mnt/loop2/ ... [root@kvm2 loop2]# rsync -avg 192.168.4.13:/boot/ /mnt/loop2/boot/ ... |
- 이때 physical server에서는 DB와 같은 쓰기작업이 일어나는 process가 돌고 있으면 안된다. 만약 rsync 할 때 쓰기 작업이 일어나고 있었으면, 그 쓰기작업이 일어난 filesystem block은 corruption이 일어나 fsck를 해야 될 수도 있다.
이제 grub image를 install 해줄건데 지금 부터가 중요하다.
[root@kvm2 loop2]# for i in `echo proc dev sys` ;do mkdir /mnt/loop2/$i ; mount -B /$i /mnt/loop2/$i ; done [root@kvm2 loop2]# chroot /mnt/loop2/ [root@kvm2 /]# ls bash: ls: command not found [root@kvm2 /]# PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin [root@kvm2 /]# ls bin boot dev etc home lib lib64 lost+found media mnt opt proc root sbin selinux srv sys tmp usr var [root@kvm2 /]# pwd / |
- 먼저 chroot에 필요한 directory들을 bind mount 해주고…
- 만약 PATH환경변수가 이상해서 command들이 안듣는다면 환경변수도 맞춰준다.
df를 해보면 physical server에 있던 정보가 그대로 나올텐데 적절하게 맞춰서 고쳐주자.
[root@kvm2 /]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/centos66-LogVol00 14G 4.5G 9.6G 32% / devpts 63G 0 63G 0% /dev/pts tmpfs 63G 0 63G 0% /dev/shm /dev/sda8 1015M 27M 938M 3% /boot [root@kvm2 /]# diff -u /etc/mtab_back /etc/mtab --- /etc/mtab_back 2018-08-18 01:54:01.688939647 +0900 +++ /etc/mtab 2018-08-18 01:52:29.631475978 +0900 @@ -1,7 +1,9 @@ -/dev/mapper/centos66-LogVol00 / ext4 rw 0 0 -/dev/sda8 /boot ext4 rw 0 0 +/dev/loop2p2 / xfs rw 0 0 +/dev/loop2p1 /boot ext2 rw 0 0 proc /proc proc rw 0 0 sysfs /sys sysfs rw 0 0 devpts /dev/pts devpts rw,gid=5,mode=620 0 0 tmpfs /dev/shm tmpfs rw,rootcontext="system_u:object_r:tmpfs_t:s0" 0 0 none /proc/sys/fs/binfmt_misc binfmt_misc rw 0 0 [root@kvm2 /]# df -h Filesystem Size Used Avail Use% Mounted on /dev/loop2p2 14G 4.5G 9.6G 32% / /dev/loop2p1 1015M 27M 938M 3% /boot devpts 63G 0 63G 0% /dev/pts tmpfs 63G 0 63G 0% /dev/shm [root@kvm2 /]# |
이상태에서 grub install을 하면 아래와 같은 error가 날 수 있다.
[root@kvm2 /]# grub-install --version grub-install (GNU GRUB 0.97) [root@kvm2 /]# grub-install /dev/loop2 /dev/loop2 does not have any corresponding BIOS drive. |
- 이럴 경우 device.map과 mknod로 임의의 block file을 만들어준다.
-
[root@kvm2 grub]# !diff diff -u /boot/grub/device.map_backup /boot/grub/device.map --- /boot/grub/device.map_backup 2018-08-18 02:26:02.000000000 +0900 +++ /boot/grub/device.map 2018-08-18 02:30:43.000000000 +0900 @@ -1 +1 @@ -(hd0) /dev/sda +(hd0) /dev/vda [root@kvm2 grub]# [root@kvm2 grub]# ls -alt /dev/loop2* brw-rw----. 1 root disk 259, 8 Aug 18 02:20 /dev/loop2p2 brw-rw----. 1 root disk 259, 7 Aug 18 02:20 /dev/loop2p1 brw-rw----. 1 root disk 7, 3 Aug 18 02:19 /dev/loop2 [root@kvm2 grub]# mknod /dev/vda b 7 3 [root@kvm2 grub]# mknod /dev/vda1 b 259 7 [root@kvm2 grub]# mknod /dev/vda2 b 259 8 [root@kvm2 grub]# ls -atl /dev/vda* /dev/loop2* brw-r--r--. 1 root root 259, 8 Aug 18 02:33 /dev/vda2 brw-r--r--. 1 root root 259, 7 Aug 18 02:33 /dev/vda1 brw-r--r--. 1 root root 7, 3 Aug 18 02:32 /dev/vda brw-rw----. 1 root disk 259, 8 Aug 18 02:20 /dev/loop2p2 brw-rw----. 1 root disk 259, 7 Aug 18 02:20 /dev/loop2p1 brw-rw----. 1 root disk 7, 3 Aug 18 02:19 /dev/loop2 [root@kvm2 grub]#
- device.map은 grub-install script가 돌아갈 때 참조하는 device이다. hd0은 첫번째 device라는 뜻으로 앞으로 migraion할 가상머신에서는 첫번째 booting disk가 될것이니 hd0으로 해준것이다. device.map안에 sda를 vda로 바꿔준 이유는 현재 사용하고 있지 않는 devname이 필요하기 때문이었다. loop2는 마지막에 2라는 숫자가 들어가기 때문에 파티션을 만들게 되면 “loop2p1” 이런식으로 p1이라는 post fix가 붙게 되는데 이러면 grub-install script가 돌아갈 때 또 오류가 난다. 그래서 vda를 쓴것이다. vda가 아니라 sdy 등 쓰고있지 않는 devname 아무거나 쓰면 된다.
- mknod를 이용해서 grub을 install할 device의 major minor number에 대칭되게 block device file을 만들어 준다.
이제 grub.conf file을 수정 해주고…
[root@kvm2 grub]# diff -u grub.conf_backup grub.conf --- grub.conf_backup 2018-08-18 02:51:35.000000000 +0900 +++ grub.conf 2018-08-18 02:53:22.000000000 +0900 @@ -13,5 +13,5 @@ hiddenmenu title CentOS 6 (2.6.32-504.el6.x86_64) root (hd0,0) - kernel /vmlinuz-2.6.32-504.el6.x86_64 ro root=/dev/mapper/centos66-LogVol00 rd_LVM_LV=rhel73/swap rd_NO_LUKS KEYBOARDTYPE=pc KEYTABLE=us LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 rd_LVM_LV=cent74/swap crashkernel=auto rd_LVM_LV=centos66/LogVol00 rd_NO_DM rhgb quiet + kernel /vmlinuz-2.6.32-504.el6.x86_64 ro root=UUID=1fbfaba7-3479-4822-822e-014bc2a61fb1 KEYBOARDTYPE=pc KEYTABLE=us LANG=en_US.UTF-8 crashkernel=auto noquiet initrd /initramfs-2.6.32-504.el6.x86_64.img [root@kvm2 grub]# |
- 여기서 root (hd0,0)은 root filesystem이 아니라, boot partition이 있는 partition을 지정해준다. 만약 boot partition이 2번째 partition이라고 한다면 (hd0,1)이 되어야 할것이다.
- 그리고 kernel과 initrd file의 위치도 중요한데, 위에서 설정한 root partition의 어디에 file이 있는지 정확하게 지정해야 한다. 만약 boot partition이 따로 없고 root filesystem의 boot directory에 같이 들어가 있다고 한다면 kernel /boot/vmlinuz…. , initrd /boot/initramfs… 이런식으로 들어가야 할것이다.
- root filesystem의 devname 또는 UUID를 넣어줘야 하는데 UUID가 범용적으로 잘 되니 UUID를 넣도록 하자. 뒤에 swap이나 lvm에 관련된 옵션들은 다 삭제해준다.
- rhgb는 red hat graphical booiting이라는 뜻으로 부팅 시 centos 그림아래 booting bar가 나오게끔 해주는 것이며, quiet은 메세지를 띄위지 말라는 뜻이다. noquiet은 그 반대
이제 grub을 설치 해보자.
[root@kvm2 /]# grub-install /dev/vda Installing for i386-pc platform. Installation finished. No error reported. |
- error 없이 잘 설치된것을 볼 수 있다.
여기까지 잘 되었으면 문제없이 grub을 넘길 수 있을 것이다.
이제 initramfs와 /etc/fstab selinux 등의 문제들을 수정해 주면 부팅이 잘 될것이다..!
참고