FreeBSD ZFS存储服务器的规划

FreeBSD ZFS存储服务器的规划

注意:本文内容已经过时。TODO:需要进行一部分改写,包括:zpool根fs不应挂载、关于如何配置纯ZFS系统的介绍、4K扇区等话题。

FreeBSD 7.0具备以 ZFS 作为根文件系统的能力。本文将以一台有6块硬盘的服务器介绍从FreeBSD/amd64 7.0 LiveFS光盘(随发行版发行的LiveCD系统)全新安装一份FreeBSD,并使用ZFS作为根目录的具体方法。

存储的规划

我们假定有6块750GB的SATA硬盘,ad0-ad5;系统有8GB RAM,希望作为存储服务器。在尽量保证数据完整性和性能的前提下,我们会希望有:

    使用五块硬盘作为RAIDZ1或RAIDZ2卷;一块硬盘作为备盘;
    系统的引导和配置信息保存2份,以便当系统无法引导时进行灾难恢复;
    适当大小的 swap 空间,在本例中,我们选择的容量是 8GB。

分区如下所示:

FreeBSD ZFS存储服务器的规划

说明:对于新系统,可以使用 GPT 分区、纯ZFS。此时,分配格局大致如下:

FreeBSD ZFS存储服务器的规划

初始化命令为:

gpart create -s gpt ad0
gpart add -s 94 -t freebsd-boot ad0
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ad0
gpart add -s 4194304 -t freebsd-swap -l swap0 ad0
gpart add -t freebsd-zfs -l disk0 ad0

准备

使用 LiveFS 光盘引导之后会自动进入sysinstall,选择 Fixit → CDROM。进入Fixit shell,会看到这样的提示符:

Fixit#

这时,我们可以开始分区了。首先,初始化覆盖所有磁盘的slice:

fdisk -IB /dev/ad0
fdisk -I /dev/ad1
fdisk -I /dev/ad2
fdisk -I /dev/ad3
fdisk -I /dev/ad4
fdisk -IB /dev/ad5

接下来在这些磁盘上初始化bsdlabel。由于 bsdlabel 需要调用 vi(透过 EDITOR 环境变量),而 sysinstall会将这个环境变量设置为 /mnt2/stand/vi,因此需要改一下:

unsetenv EDITOR
bsdlabel -wB /dev/ad0s1
bsdlabel -w /dev/ad1s1
bsdlabel -w /dev/ad2s1
bsdlabel -w /dev/ad3s1
bsdlabel -w /dev/ad4s1
bsdlabel -wB /dev/ad5s1

分别编辑这些labels。对于ad0和ad5,类似这样:

8 partitions:
#           size        offset        fstype
a:  4194304              16      unused
c:              *                0       unused
d:             *                 *       unused

对于ad1-ad4,类似这样:

8 partitions:
#           size        offset        fstype
b:  4194304              16      unused
c:              *                0       unused
d:             *                 *       unused

我们希望不因为盘序问题导致混乱,因此会用到 geom label。在本次启动时,我们并不立即创建 ZFS,而只是初始化一个用于启动的 UFS 分区:

newfs -L boot /dev/ad0s1a
mount -o async /dev/ufs/boot /mnt

下面,从光盘上复制一系列文件到这个分区上:

cd /mnt
cp -pR /mnt2/*bin /mnt2/boot /mnt2/etc /mnt2/lib* /mnt2/usr /mnt2/var .
mkdir dev

接下来进行初步的配置:

cd /mnt/boot
rm loader.conf mfsroot.gz
echo "/dev/ufs/boot / ufs rw 0 0" > /mnt/etc/fstab
echo "/dev/ad1s1b none swap sw 0 0" >> /mnt/etc/fstab
echo "/dev/ad2s1b none swap sw 0 0" >> /mnt/etc/fstab
echo "/dev/ad3s1b none swap sw 0 0" >> /mnt/etc/fstab
echo "/dev/ad4s1b none swap sw 0 0" >> /mnt/etc/fstab
touch /etc/rc.conf
cd /
umount /mnt
tunefs -n enable /dev/ufs/boot

现在就可以从硬盘引导系统了。

创建 ZFS

从硬盘引导之后,以 root 身份登录。首先,我们为将要加入 zpool 的磁盘指定 GEOM label:

glabel label disk0 /dev/ad0s1d
glabel label disk1 /dev/ad1s1d
glabel label disk2 /dev/ad2s1d
glabel label disk3 /dev/ad3s1d
glabel label disk4 /dev/ad4s1d
glabel label disk5 /dev/ad5s1d

然后,在其上建立 zpool,我们将这个zpool命名为tank,将disk0-4作为其raidz1成员,并使用disk5作为热备盘:

zpool create tank raidz /dev/label/disk[0-4] spare /dev/label/disk5

此时,这个zpool会被自动挂接到 /tank。如果CPU比较快,通常启用压缩会改善性能:

zfs set compression=on tank

复制文件

首先需要为现在我们用来引导的这个 UFS 卷指定一个归宿:

mkdir /tank/bootdir

系统引导之后,需要访问某些 /boot 的内容:

cd /tank
ln -s bootdir/boot boot

复制 / 到 /tank:

cd /
cp -pR /*bin /etc /lib* /usr /var /tank
mtree -deUf /etc/mtree/BSD.root.dist -p /tank
mtree -deUf /etc/mtree/BSD.var.dist -p /tank/var
chmod u+s,g+s /tank/usr/bin/su

配置以ZFS作为 / 启动,修改 /boot/loader.conf 使其包含:

zfs_load="YES"
vfs.root.mountfrom="zfs:tank"

将 zpool 上的 ZFS 挂接方式改为 legacy:

zfs set mountpoint=legacy tank

在重启之前,需要修改 /etc/fstab:

/dev/ufs/boot /bootdir ufs rw 0 0

重新启动系统。此时根目录应该就是 zfs 了,接下来,可以在 /etc 中进行配置。

此后,建议使用通常的方式联编系统,以确保文件/目录权限的正确性。

配置的备份和同步

我们前面将 /dev/ad5s1a 留作配置备份卷。这个卷在未来出问题的时候应该是可以帮助你启动的,现在我们来对它进行初始化:

newfs -U -L altboot /dev/ad5s1a
mkdir -p /altbootdir

接下来我们需要将 /bootdir 的内容复制过去:

mount /dev/ufs/altboot /altbootdir
cd /bootdir
tar cf – * | tar xf – -C /altbootdir

平时将 /altbootdir 卷卸下即可。当对系统的配置进行较大的变动,特别是对 zpool 内容进行变动或升级内核之后,应再次重复前面的复制步骤。

原文链接:http://wiki.freebsdchina.org/doc/z/zfs_root

FreeBSD配置ZFS做为根系统

声明:不建议使用ZFS做根文件系统

需要的文件

需要FreeBSD的DVD镜像 或者 memstick.img文件,其他的都不完整,所以不推荐

启动到Fixit

1.启动DVD 2.选择Fixit 3.选择CDROM/DVD,回车

创建mbr结构分区表,如果已存可以省略

Fixit# gpart create -s mbr ad4

显示分区信息

Fixit# gpart show ad4

在ad4上创建FreeBSD使用的分区ad4s3

Fixit# gpart add -b 6313545 -s 119515536 -t freebsd ad4
ad4s3 added
Fixit# gpart create -s BSD ad4s3
ad4s3 created

创建FreeBSD Partition

ad4s3a的分区是去掉Swap分区后的大小,计算公式时1024x1024x2=1G

Fixit# gpart add -i 1 -b 0 -s 117418384 -t freebsd-zfs ad4s3
ad4s3a added
Fixit# gpart show ad4s3

Fixit# gpart add -i 2 -b 117418384 -s 8380811 -t freebsd-swap ad4s3
ad4s3b added
Fixit# gpart show ad4s3

安装FreeBSD自带的引导器,boot0阶段

Fixit# gpart bootcode -b /mnt2/boot/boot0 ad4
ad4 has bootcode

boot1阶段

Fixit# dd if=/mnt2/boot/zfsboot of=/dev/ad4s3 count=1

boot2阶段

Fixit# dd if=/mnt2/boot/zfsboot of=/dev/ad4s3a skip=1 seek=1024

加载zfs内核模块

Fixit# kldload /mnt2/boot/kernel/opensolaris.ko
Fixit# kldload /mnt2/boot/kernel/zfs.ko

创建ZFS存储池

Fixit# zpool create tank /dev/ad4s3a
Fixit# zpool set bootfs=tank tank

文件系统校验使用fletcher4方式

Fixit# zfs set checksum=fletcher4 tank

创建ZFS文件目录结构

Fixit# zfs create -o compression=on -o exec=on -o setuid=off tank/tmp
Fixit# chmod 1777 /tank/tmp
Fixit# zfs create tank/usr
Fixit# zfs create tank/home
Fixit# zfs create -o compression=lzjb -o setuid=off tank/usr/ports
Fixit# zfs create -o compression=off -o exec=off -o setuid=off tank/usr/ports/distfiles
Fixit# zfs create -o compression=off -o exec=off -o setuid=off tank/usr/ports/packages
Fixit# zfs create -o compression=lzjb -o exec=off -o setuid=off tank/usr/src
Fixit# zfs create tank/var
Fixit# zfs create -o compression=lzjb -o exec=off -o setuid=off tank/var/crash
Fixit# zfs create -o exec=off -o setuid=off tank/var/db
Fixit# zfs create -o compression=lzjb -o exec=on -o setuid=off tank/var/db/pkg
Fixit# zfs create -o exec=off -o setuid=off tank/var/empty
Fixit# zfs create -o compression=lzjb -o exec=off -o setuid=off tank/var/log
Fixit# zfs create -o compression=gzip -o exec=off -o setuid=off tank/var/mail
Fixit# zfs create -o exec=off -o setuid=off tank/var/run
Fixit# zfs create -o compression=lzjb -o exec=on -o setuid=off tank/var/tmp
Fixit# chmod 1777 /tank/var/tmp

安装FreeBSD到ZFS上

Fixit# cd /dist/8.1*
Fixit# export DESTDIR=/tank
这里推荐先不要释放ports,曾经8.0上释放ports会导致重启
Fixit# for dir in base catpages dict doc games info lib32 manpages; \
     do (cd $dir ; ./install.sh) ; done
Fixit# cd src ; ./install.sh all
Fixit# cd ../kernels ; ./install.sh generic
Fixit# cd /tank/boot ; cp -Rlp GENERIC/* /tank/boot/kernel/
Fixit# cd /
Fixit# zfs set readonly=on tank/var/empty

安装后配置

在rc.conf,src.conf,fstab,loader.conf文件里添加了这些内容就行,不管你使用什么方法ee,vi,echo。都行

Fixit# echo ‘zfs_enable="YES"’ > /etc/rc.conf
Fixit# echo ‘hostname="FreeBSD.tk.local"’ >> /etc/rc.conf
Fixit# echo ‘ifconfig_em0="DHCP"’ >> /etc/rc.conf
Fixit# echo ‘LOADER_ZFS_SUPPORT=YES’ > /tank/etc/src.conf
Fixit# echo ‘zfs_load="YES"’ > /tank/boot/loader.conf
Fixit# echo ‘vfs.root.mountfrom="zfs:tank"’ >> /tank/boot/loader.conf
Fixit# cat << EOF > /tank/etc/fstab
# Device                       Mountpoint              FStype  Options         Dump    Pass#
/dev/ad4s3b                    none                    swap    sw              0       0
EOF

重新编译引导器,添加zfs支持

Fixit# chroot /tank
Fixit# mount -t devfs devfs /dev
Fixit# export DESTDIR=""
Fixit# cd /usr/src/sys/boot/
Fixit# make obj
Fixit# make depend
Fixit# make
Fixit# cd i386/loader
Fixit# make install

设置密码

Fixit# passwd

设置时区

Fixit# tzsetup
Fixit# cd /etc/mail
Fixit# make aliases
Fixit# umount /dev
Fixit# exit

创建zpool.cache

Fixit# mkdir /boot/zfs
Fixit# zpool export tank && zpool import tank
Fixit# cp /boot/zfs/zpool.cache /tank/boot/zfs/zpool.cache
Fixit# export LD_LIBRARY_PATH=/mnt2/lib

修改zfs存储池tank的挂载点

Fixit# zfs set mountpoint=legacy tank
Fixit# zfs set mountpoint=/tmp tank/tmp
Fixit# zfs set mountpoint=/usr tank/usr
Fixit# zfs set mountpoint=/var tank/var
Fixit# zfs set mountpoint=/home tank/home

卸载所有

Fixit# zfs unmount -a

退出,重新引导系统

Fixit# exit

其他

1.有时会出现找不到引导器,重启后就可以引导了,原因不明

2.可能导致Windows7出现引导器修复界面

原文链接:http://wiki.freebsdchina.org/doc/z/zfsbootpartition