如何利用修复光盘将一个 CentOS 5 系统转换成 RAID1
1. 引言
1.1. 内容
这个文档要描述的是将一个缺省的 CentOS 5 系统转换为 RAID 1 的程序。我盼望你能够将这个技巧扩展到一个更复杂的系统,因为本作者缺乏足够耐性来枚举所有可能的系统设置,及如何转换成所有可能的硬盘阵列类型。
通过修复模式,现存的文件系统可以在非运行中、只读的状况下被复制,这样对系统比较有保障。
1.2. 警告
为了规范程序,下面是数个限制……
- 新设备的类型(ATA、SATA、SCSI)与现有的设备相同。这并非必然的:一个拥有 ATA 及 SATA 的系统配上 SCSI 绝对可行。拥有两个类同的界面的话,硬盘便可以互换。但假若使用两个不同的界面,程序中途便不能如这里所示范般进行检查。
- 机器只提供 2 个可用的界面。其它界面将会被略过。将系统扩展至额外的界面将会令存储系统的结构与这里所描述的有差别。
- 新设备与现有设备的容量是等同或相若。
- 现有设备预期会成为 RAID 的成员。最后这两点是有关连的:RAID 1 在多于一个硬盘的情况下才有意义。如果系统是新安装的,近似的第一个硬盘应该很易找得着。然而,假若两个硬盘都会被应用,当被问及是否重装在原有的硬盘上,请选择安装至新的硬盘上。
1.3. 先决条件
要有效地应用这份文档,我们推荐你拥有……
- 一台利用缺省分割来安装、运行中的 CentOS 5 系统。
- 安装媒体。原先用来安装系装的媒体是首选,因为它含有系统所需的一切驱动程序。这当然假设在安装时并没有遇上问题。
- 已检查的备份。这个程序包括检查所作的改动不会导致一个无效的系统,但已检查的备份是任何运作中的系统的重要元素。
- 将要新增的存储设备。包括数据及电源线。
1.4. 免责声明
这里并不提供任何类型的保证。系统间的差异实在太大,令这份文档不能涵盖所有可能性。系统管理员请留意:如果你的系统毁坏了,你要了承担一切后果(这句有版权吗?)。
2. 引导修复模式
修复模式是维修损坏了的系统最迫不得已时才用的方法。一个系统总会有某种修复用的开机方法。
2.1. 利用安装媒体开机
这可以是 CD、DVD、USB 存储器或 PXE 映像。创建安装媒体的方法超越了这份文档的范围,但你可以假设这个媒体存在,因为你拥有一台安装成功的机器。如果这个媒体并不存在,请查看 http://www.centos.org。
2.2. 选择修复模式
在开机的提示符,输入
linux rescue
然后按 Enter。
2.3. 选择语言
利用箭嘴键选择所需语言并按 Enter。
2.4. 选择键盘类型
利用箭嘴键选择所需键盘分配并按 Enter。
2.5. 网络界面
网络界面并非必要的。请用箭嘴键选择 No 并按 Enter。
2.6. 省略挂载现有系统
在修复划面,利用箭嘴键选择 Skip 并按 Enter。我们稍后将会进行挂载。
2.7. 修复模式
恭喜你!你已经进入修复模式!
修复模式在这些情况下很有用……
- 维修 grub
- 你安装了第三方的操作系统,无意中令系统不能开机
- 更改 root 密码至已知的值
3. 设置新设备
此刻,新设备的实物应该已经安装在系统中,并且正确地接了线。普遍来说,这是在切了电源的情形下进行。
3.1. 判断新设备的名称
假设新的存储设备已经安装在系统内,并且接驳了合适的数据及电源线,那么你多数可以用这个方法来判断现有及新设备的名称……
fdisk -l
样例的系统返回……
Disk /dev/sda: 250.0 GB, 250000000000 bytes 255 heads, 63 sectors/track, 30394 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sda1 * 1 13 104391 83 Linux /dev/sda2 14 30394 244035382+ 8e Linux LVM Disk /dev/sdb: 250.0 GB, 250000000000 bytes 255 heads, 63 sectors/track, 30394 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk /dev/sdb doesn't contain a valid partition table
在这个例子里,现有系统正在使用 /dev/sda,而新的设备名叫 dev/sdb。如果是 ATA 的话,它们大可以是 /dev/hda 及 /dev/hdc。可能的话,这两个设备应该在不同的界面上。就 SATA 及 SCSI 而言,设备的名称不能透露它们位于哪个界面上,但就 ATA 而言,/dev/hda 及 /dev/hdb 表示它们在同一个界面上。这或许是无可避免,但却不可取。
3.2. 创建新的分区
根据可追溯到 SunOS 年代的传统智慧,把 /boot 放在 RAID 1 设备上带来潜在的安全性及容错问题。以人手方式复制 /boot 至另一个转轴(随着传统扩展,包括 Solaris 上的 / 分区映像)提供一个安全性备份,因为拥有两个可访问的 /boot 分区增加某个 /boot 仍旧可用的机会。
你可以说这个做法能创建一个更可靠的系统,因为它在主分区被更新或恶意破坏时,提供了另一个开机修复的途径,而代价只是(通过挂载、一个 rsync 指命、及卸下)保持次要及主要分区同步。若然真的要修复开机设备,你只须编辑 grub 的指命行并指定后备的 /root 设备问题便能「迎刃而解」。另外值得留意的,就是运用「双重 /root」这个方案时必须预备一台本地的终端機。
一旦主要的 /boot 分区被修改及成功地测试后,你便可以用手动的方式定时将它同步。针对修复时备用及失效时提供保障,利用 raid 把内容「分布」到两个转轴的「好处」并不胜于在两个转轴保留基本的 /boot 分区。这是由于 raid 层级加入额外的复杂性及故障点。话虽如此,有些人基于其它人不同意的理由希望在每一处应用磁盘数组,而这篇文章会继续讨论这个做法。
这篇文章的目标是要拥有一台通过 raid 能抵受设备出现故障的系统,而不是其它做法。我我们将忽视其它考虑因素。我们会将 /boot 放在磁盘数组,藉以简化程序。
注:上述句子所谓「简化程序」的复杂情度其实过于在两个实体硬盘上装入传统分区,然后定时定候通过 rsync 把次设备与主设备同步。
缺省的安装为 / 创建一个颇复杂的设置,而我们加入 RAID 1 时将会令它更复杂。使用 LVM 的好处就是你可以移动分区来迎合不同的空间需求。
请利用 fdisk 这个分区工具程序……
fdisk /dev/sdb
按 n 及 Enter 来创建一个新的分区。按 p 及 Enter 来选择主分区。按 1 及 Enter 来选择首个分区。按 Enter 来选择新分区在设备的头开始。输入 +100M 及按 Enter 来限制新分区的尺寸为 100M。按 t 及 Enter,接着输入 fd 及按 Enter 来更改分区类型为 RAID。
按 n 及 Enter 来创建第二个新的分区。按 p 及 Enter 来选择主分区。按 2 及 Enter 来选择第二个分区。按 Enter 来选择新分区由下一个柱面开始。按 Enter 来使用设备上余下的空间。按 t 及 Enter 来更改分区类型。由于我们将会有多个分区,我们须要选择 2 并按 Enter。输入 fd 及按 Enter 来选择 RAID。
按 p 及 Enter 来确定分区的设置。
按 w 及 Enter 将修改写入。
系统的回复应该是……
The number of cylinders for this disk is set to 30394. There is nothing wrong with that, but this is larger than 1024, and could in certain setups cause problems with: 1) software that runs at boot time (e.g., old versions of LILO) 2) booting and partitioning software from other OSs (e.g., DOS FDISK, OS/2 FDISK) Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-30394, default 1): Using default value 1 Last cylinder or +size or +sizeM or +sizeK (1-30394, default 30394): +100M Command (m for help): t Selected partition 1 Hex code (type L to list codes): fd Changed system type of partition 1 to fd (Linux raid autodetect) Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First cylinder (14-30394, default 14): Using default value 14 Last cylinder or +size or +sizeM or +sizeK (14-30394, default 30394): Using default value 30394 Command (m for help): t Partition number (1-4): 2 Hex code (type L to list codes): fd Changed system type of partition 2 to fd (Linux raid autodetect) Command (m for help): p Disk /dev/sdb: 250.0 GB, 250000000000 bytes 255 heads, 63 sectors/track, 30394 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sdb1 1 13 104391 fd Linux raid autodetect /dev/sdb2 14 30394 244035382+ fd Linux raid autodetect Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. Syncing disks.
至于那些想剪贴指令的人……
echo -e "n\np\n1\n\n+100M\nt\nfd\nn\np\n2\n\n\nt\n2\nfd\np\nw" | fdisk /dev/sdb
3.3. 创建 RAID 设备
为 /boot 创建一个 RAID 1 设备。由于第二个设备暂时仍未存在,因此它需要预留一个地方。我们稍后便会加入第二个设备。
mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb1 missing
所得的输出应该是……
mdadm: array /dev/md0 started.
为 / 创建第二个 RAID 1 设备。
mdadm --create /dev/md1 --level=1 --raid-devices=2 /dev/sdb2 missing
所得的输出应该是……
mdadm: array /dev/md1 started.
3.4. 将新的 /boot 设备格式化
缺省的安装会将一个 ext3 分区放置在 /boot。标签可以帮助系统判断分区应该挂载在哪里。要依从这个标准……
mkfs.ext3 -L '/boot' /dev/md0
所得的输出应该是……
mke2fs 1.39 (29-May-2006) Filesystem label=/boot OS type: Linux Block size=1024 (log=0) Fragment size=1024 (log=0) 26104 inodes, 104320 blocks 5216 blocks (5.00%) reserved for the super user First data block=1 Maximum filesystem blocks=67371008 13 block groups 8192 blocks per group, 8192 fragments per group 2008 inodes per group Superblock backups stored on blocks: 8193, 24577, 40961, 57345, 73729 Writing inode tables: done Creating journal (4096 blocks): done Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 30 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override.
3.5. 创建新的 / 分区
这样将 /dev/md1 设置为一个实体扇区……
lvm pvcreate /dev/md1
创建一个新的扇区群组……
lvm vgcreate RaidSys /dev/md1
创建一个新的逻辑调换扇区……
lvm lvcreate --size 4G --name swap RaidSys
创建一个新的逻辑 root 扇区……
lvm lvcreate --size 200G --name Root RaidSys
将新的调换设备格式化……
mkswap /dev/RaidSys/swap
将新的 / 设备格式化……
mkfs.ext3 -L '/' /dev/RaidSys/Root
3.6. 挂载分区
将所有设备挂载在我们找得着的地方……
mkdir /mnt/boot.old mount -o ro /dev/sda1 /mnt/boot.old mkdir /mnt/boot.new mount /dev/md0 /mnt/boot.new lvm vgchange --available y VolGroup00 mkdir /mnt/root.old mount -o ro /dev/VolGroup00/LogVol00 /mnt/root.old mkdir /mnt/root.new mount /dev/RaidSys/Root /mnt/root.new
4. 移动数据至新设备
4.1. 对 /boot 进行同步
rsync 这个工具应该能够保留拥有权及更改日期,加上 X 标志更能保留扩展属性。加入 H 旗可以保留硬连结(多谢 Phil)。很不幸地,它似乎不能保留 SELinux 的属性。请将数据同步……
rsync -avXH /mnt/boot.old/* /mnt/boot.new/
对于较喜欢用 tar 的人们,这样做会从旧的 /boot 创建一个没有加压的压缩档,然后将它解压到新的设备上……
tar -C /mnt/boot.old -cf - . | tar -C /mnt/boot.new -xf -
4.2. 对 / 进行同步
再一次利用 rsync 工具……
rsync -avXH /mnt/root.old/* /mnt/root.new/
或者 tar……
tar -C /mnt/root.old -cf - . | tar -C /mnt/root.new -xf -
4.3. 重新标签 SELinux
为要请求 SELinux 的属性在开机时重新被标签,创建一个标志文件……
touch /mnt/root.new/.autorelabel
4.4. 令新的设备可作开机之用
你必须完成某些修改新系统的维护项目才能令它可以开机。
4.4.1. 安装 grub
令新的 RAID 设备可以用来开机……
grub root (hd1,0) setup (hd1) quit
4.4.2. 编辑 grub 配置文件
root 设备是与别不同的,grub 需要知道关于它来告诉内核。编辑 /mnt/boot.new/grub/menu.lst。安装媒体内包括 joe,它可以用来仿真 nano 及 vi。请用你觉得舒服的指令。将所有 /dev/VolGroup00/LogVol00 的地方改为 /dev/RaidSys/Root。存储你的修改。
4.4.3. 编辑文件系统列表
一旦系统能够再次开机,你需要知道新的 root 设备是什么。编辑 /mnt/root.new/etc/fstab,将所有 /dev/VolGroup00/LogVol00 改为 /dev/RaidSys/Root。一般来说,/boot 是靠标签来挂载,但我们现在于每个硬盘上都有 /boot。让我们将 LABEL=/boot 改为 /dev/md0。将 /dev/VolGroup00/LogVol01 改为 /dev/RaidSys/swap。存储你的修改。
4.4.4. 创建新的 initrd
旧的系统在开机并不需要 RAID 驱动程序。现在它需要了。我们必须在 initrd 设置 RAID 驱动程序。以一个运作中的系统来完成这步骤会最容易。我们可以将 proc、dev、sys 及 selinux 这些虚拟目录联系到修复系统的版本,让它看似一个运作中的系统。
umount /mnt/boot.new mount /dev/md0 /mnt/root.new/boot mount -o bind /proc /mnt/root.new/proc mount -o bind /dev /mnt/root.new/dev mount -o bind /sys /mnt/root.new/sys mount -o bind /selinux /mnt/root.new/selinux
现在进入新的系统……
chroot /mnt/root.new
查看现有的映像来判断你现有的系统是什么……
ls /boot/*.img
在测试的系统上,这样做返回……
/boot/initrd-2.6.18-128.1.6.el5.img /boot/initrd-2.6.18-128.el5.img
这表示 2.6.18-128.1.6.el5 是最新版的内核。创建一个新的 initrd……
mkinitrd -f /boot/initrd-2.6.18-128.1.6.el5.img 2.6.18-128.1.6.el5
返回修复模式……
exit
4.5. 清理
在重新开机前,先将系统撤消到未挂载的状况。这样会告诉系统是时候写入任何留在高速缓冲内的改动。
umount /mnt/root.new/selinux umount /mnt/root.new/sys umount /mnt/root.new/dev umount /mnt/root.new/proc umount /mnt/root.new/boot umount /mnt/root.new umount /mnt/boot.old umount /mnt/root.old
5. 利用新设备开机
我们现在已经准备好测试我们的单硬盘 RAID 1 系统。我们并没有对现有的设备作出任何改动,因此我们可以忽略我们所做的一切事情,并以现有的设备重新开机。
5.1. 移动设备
我们已经干净俐落地卸除了我们的存储设备,因此我们可以简单切断系统电源,又或者使用这个指令……
exit
它会令系统重新引导。由于我们在下一步需要系统是关闭的,当它完成关机准备重新引导时,请关闭它并切断电源。
将第二个存储设备连接到首个界面上。在我们的测试中,请勿连接原有设备。请在 BIOS 中为硬件改动更新设置。
5.2. 测试系统
删除修复媒体并打开系统。它应该能如同未作出改动般引导。
登录、进到命令行、并输入以下指令来检查我们有否应用 RAID 装罝……
mount
我们应该获得类似这样的输出……
/dev/mapper/RaidSys-Root on / type ext3 (rw) proc on /proc type proc (rw) sysfs on /sys type sysfs (rw) devpts on /dev/pts type devpts (rw,gid=5,mode=620) /dev/md0 on /boot type ext3 (rw) tmpfs on /dev/shm type tmpfs (rw) none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw) sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
重要的部份是 /dev/mapper/RaidSys-Root on / type ext3 (rw) 及 /dev/md0 on /boot type ext3 (rw)。我们的系统现已应用 RAID/LVM。
6. 扩展 RAID 分区至第二个设备
我们已经有一台运作中的单碟 RAID 1 系统。这个系统已被检查过能正常运作,而并证实藏有数据。这个系统已经准备好扩展为一个多碟 RAID 1 系统。
由这点开始,原有的存储设备将会被修改。这小心确定新的 RAID 系统的确能正常运作。
你可以选择于系统运作的同时扩展到第二个设备。除了较复杂之外,没有其它理由阻止你这样做。
6.1. 重新安装原先/第二个设备
关闭系统并安装原先的设备,将它连接在第二个界面上,作为附屬件。
6.2. 用修复媒体开机
执行早前引导修复模式部份内的指令。
6.3. 启用 RAID 设备
安装媒体并不包含缺省的 mdadm.conf 档,因此你需要创建它。一个简单的方法是……
mdadm --examine --scan > /etc/mdadm.conf
接着,启用所有被检测到的 RAID 设备……
mdadm --assemble --scan
6.4. 转换第二个设备上的分区
我们需要设置第二个设备存储设备,好让它能与配合其它 RAID 设备。通过 fdisk,先删除旧的分区,然后创建新的……
fdisk /dev/sdb
按 d 及 Enter,然后 2 及 Enter 来删除第二个分区,。
按 d 及 Enter 来删除首个分区。
按 n 及 Enter 来创建新的 /boot 分区。按 p 及 Enter 来选择主分区。接 1 及 Enter 来选择首个分区。按 Enter 来选择新分区在设备的头开始。输入 +100M 及按 Enter 来限制新分区的尺寸为 100M。按 t 及 Enter,接着输入 fd 及按 Enter 来更改 /boot 分区的类型。
按 n 及 Enter 来创建别一个分区。按 p 及 Enter 来选择主分区。按 2 及 Enter 来选择第二个分区。按 Enter 来选择新分区由可用的空间的起首开始。按 Enter 来使用设备上余下的空间。按 t、Enter、2 及 Enter 来选择更改第二个分区的类型,接着输入 fd 及按 Enter 来选择。
按 p 及 Enter 来显示分区的设置,以便检查。
按 w 及 Enter 将新的分区表写进设备内。
The number of cylinders for this disk is set to 30394. There is nothing wrong with that, but this is larger than 1024, and could in certain setups cause problems with: 1) software that runs at boot time (e.g., old versions of LILO) 2) booting and partitioning software from other OSs (e.g., DOS FDISK, OS/2 FDISK) Command (m for help): d Partition number (1-4): 2 Command (m for help): d Selected partition 1 Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-30394, default 1): Using default value 1 Last cylinder or +size or +sizeM or +sizeK (1-30394, default 30394): +100M Command (m for help): t Selected partition 1 Hex code (type L to list codes): fd Changed system type of partition 1 to fd (Linux raid autodetect) Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 2 First cylinder (14-30394, default 14): Using default value 14 Last cylinder or +size or +sizeM or +sizeK (14-30394, default 30394): Using default value 30394 Command (m for help): t Partition number (1-4): 2 Hex code (type L to list codes): fd Changed system type of partition 2 to fd (Linux raid autodetect) Command (m for help): p Disk /dev/sdb: 250.0 GB, 250000000000 bytes 255 heads, 63 sectors/track, 30394 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sdb1 1 13 104391 fd Linux raid autodetect /dev/sdb2 14 30394 244035382+ fd Linux raid autodetect Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. Syncing disks.
6.5. 扩展 RAID 的 /boot 分区至第二个设备
要查看 RAID 现时的状态……
cat /proc/mdstat
系统返回的应该类似……
Personalities : [raid0] [raid1] [raid6] [raid5] [raid4] md1 : active raid1 sda2[0] 244035264 blocks [2/1] [U_] md0 : active raid1 sda1[0] 104320 blocks [2/1] [U_] unused devices: <none>
6.5.1. 加入第二个 /boot 分区至 RAID 设备
利用 mdadm 将第二个设备上的首个分区加进头一个 RAID 设备内
mdadm /dev/md0 -a /dev/sdb1
6.5.2. 检查 RAID 的 /boot 设备
我们想检查第二个设备是否已被加入……
cat /proc/mdstat
它应该返回……
Personalities : [raid0] [raid1] [raid6] [raid5] [raid4] md1 : active raid1 sda2[0] 244035264 blocks [2/1] [U_] md0 : active raid1 sdb1[1] sda1[0] 104320 blocks [2/2] [UU] unused devices: <none>
留意 md0 现在有两个使用中的设备 [UU]。
6.6. 扩展 RAID 的 / 分区至第二个设备
6.6.1. 加入第二个 / 分区至 RAID 设备
同样地针对 /boot……
mdadm /dev/md1 -a /dev/sdb2
6.6.2. 检查 RAID 的 / 设备
加入第二个设备到 md1 后,立即执行……
cat /proc/mdstat
它应该返回……
Personalities : [raid0] [raid1] [raid6] [raid5] [raid4] md1 : active raid1 sdb2[2] sda2[0] 244035264 blocks [2/1] [U_] [>....................] recovery = 0.1% (254976/244035264) finish=63.7min speed=63744K/sec md0 : active raid1 sdb1[1] sda1[0] 104320 blocks [2/2] [UU] unused devices: <none>
这是一个较大的分区,因此需较长时间来同步。估计的完成时间是 63.7 分钟。
一旦 md1 完成同步,cat /proc/mdstat 应该返回……
Personalities : [raid0] [raid1] [raid6] [raid5] [raid4] md1 : active raid1 sdb2[1] sda2[0] 244035264 blocks [2/2] [UU] md0 : active raid1 sdb1[1] sda1[0] 104320 blocks [2/2] [UU] unused devices: <none>
我们推荐完成同步后才重新开机。
6.7. 在第二个设备上安装 grub
令第二个设备可以用来开机……
grub root (hd1,0) setup (hd1) quit
6.8. 重新引导完整的 RAID 1 系统
要离开修复模式,请输入……
exit
如果需要的话,请亦删除所有安装媒体。
7. 总结
整个程序现在已经完成,而且系统应该能够运作。
8. 更多阅读
CentOS 5 文档部署指南Chapter 4. Redundant Array of Independent Disks (RAID)
CentOS 5 文档LVM 管理指引Chapter 2. LVM Components
mdadm、lvm 的指令说明
本页的英文版本由 Ed Heron 创建。
Translation of revision 37