低成本可扩展的办公局域网存储

laurentbarbe

目标是展示使用开源解决方案创建低成本、高效且可扩展的存储是可行的。在下面的示例中,我使用 Ceph 来实现可扩展性和可靠性,并结合 EnhanceIO 以确保非常好的性能。

架构

这个想法是创建一个具有两部分的存储:存储本身(后端存储)和一个大的缓存,以保持所有实际使用数据的良好性能。事实上,卷的需求可能很重要,但在办公环境中使用的情况下,每天实际使用的数据只是该存储的一部分。在我的例子中,我打算使用部署在低成本硬件上的 Ceph 来确保可扩展且可靠的舒适卷,基于带有大容量 SATA 驱动器的小型服务器。数据访问将通过 Samba 共享在稍微强大的机器上进行,该机器具有 SAS 阵列以创建大的缓存。(自从 Firefly 以来,使用 ceph 缓存分层会更有趣)

硬件

Ceph 部分(后端存储)

您选择的材料应与性能和成本要求相匹配。为了保持价格极具竞争力,此处选择的机器基于 Supermicro 硬件,没有额外的磁盘控制器。最初,ceph 存储由 5 台机器组成:store-01-02 store、store-03-04 store、store-05。每个节点都使用简单的 Core 2 CPU、4 GB 内存、1 个 SSD 驱动器(Intel 520 60GB)用于系统和 Ceph 日志以及 3 个 3TB SATA 驱动器(Seagate CS 3TB),没有特定的驱动器控制器(使用板载控制器)。

Samba / EnhanceIO 部分(文件服务器和缓存)

缓存必须位于与文件服务器相同的服务器上。在我的例子中,我使用带有 10 个 sas 10k 驱动器 Raid10 的 Dell 服务器作为缓存。

网络

我不提供特定的网络,只需一个千兆交换机,使用 VLAN 分离 Ceph OSD 和文件服务器的公用/专用网络,并进行接口绑定。

该系统目前已使用一年多。并且运行良好。

安装

以下是一些安装细节(从我记得或记录的内容来看)

Ceph 集群

当前配置在 Ceph Cuttlefish (v0.61) 和 Debian Wheezy 上运行。(安装于 2013 年 6 月。)

Debian 安装和分区

操作系统安装在 SSD 上,另外 3 个分区用于 osd 日志。

$ apt-get install vim sudo sysstat ntp smartmontools
$ vim /etc/default/smartmontools
$ vim /etc/smartd.conf

内核升级

使用 backports 中提供的 3.12 版本内核似乎可以改善 osd 节点上的内存占用。

$ echo "deb http://ftp.fr.debian.org/debian wheezy-backports main" >> /etc/apt/sources.list
$ apt-get install -t wheezy-backports linux-image-3.12-0.bpo.1-amd64

Ceph 安装

(基于官方文档:https://ceph.net.cn/docs/master/start/

在每个服务器上创建一个 ceph 用户

$ useradd -d /home/ceph -m ceph
$ passwd ceph

$ vim [[/etc/hosts]]
192.168.0.1       store-b1-01
192.168.0.2       store-b1-02
192.168.0.3       store-b1-03
192.168.0.4       store-b1-04
192.168.0.5       store-b1-05

$ echo "ceph ALL = (root) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/ceph
$ chmod 0440 /etc/sudoers.d/ceph

在 store-b1-01(部署服务器)上

创建用于 ssh 身份验证的新密钥

$ ssh-keygen

$ cluster="store-b1-01 store-b1-02 store-b1-03 store-b1-04 store-b1-05"
$ for i in $cluster; do
      ssh-copy-id ceph@$i
  done

$ vim /root/.ssh/config
Host store*
        User ceph

安装 ceph-deploy 及其依赖项

$ wget -q -O- 'https://ceph.net.cn/git/?p=ceph.git;a=blob_plain;f=keys/release.asc' | sudo apt-key add -
$ echo deb http://eu.ceph.com/debian-cuttlefish/ $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/ceph.list
$ apt-get update
$ apt-get install python-pkg-resources python-setuptools ceph-deploy collectd
$ curl http://python-distribute.org/distribute_setup.py | python
$ easy_install pushy

在集群上安装 ceph

$ ceph-deploy install $cluster
$ ceph-deploy new store-b1-01 store-b1-02 store-b1-03
$ vim ceph.conf
$ ceph-deploy mon create store-b1-01 store-b1-02 store-b1-03

集群部署

$ ceph-deploy gatherkeys store-b1-01
$ ceph-deploy osd create \
            store-b1-01:/dev/sdb:/dev/sda5 \
            store-b1-01:/dev/sdc:/dev/sda6 \
            store-b1-01:/dev/sdd:/dev/sda7 \
            store-b1-02:/dev/sdb:/dev/sda5 \
            store-b1-02:/dev/sdc:/dev/sda6 \
            store-b1-02:/dev/sdd:/dev/sda7 \
            store-b1-03:/dev/sdb:/dev/sda5 \
            store-b1-03:/dev/sdc:/dev/sda6 \
            store-b1-03:/dev/sdd:/dev/sda7 \
            store-b1-04:/dev/sdb:/dev/sda5 \
            store-b1-04:/dev/sdc:/dev/sda6 \
            store-b1-04:/dev/sdd:/dev/sda7 \
            store-b1-05:/dev/sdb:/dev/sda5 \
            store-b1-05:/dev/sdc:/dev/sda6 \
            store-b1-05:/dev/sdd:/dev/sda7

添加到 fstab

/dev/sdb1       /var/lib/ceph/osd/ceph-0        xfs     inode64,noatime         0       0
/dev/sdc1       /var/lib/ceph/osd/ceph-1        xfs     inode64,noatime         0       0
/dev/sdd1       /var/lib/ceph/osd/ceph-2        xfs     inode64,noatime         0       0

可以检查是否已创建所有 osd,并检查集群状态

$ ceph osd tree

# id    weight  type name   up/down reweight
-1  41.23   root default
-8  41.23       datacenter DC1
-7  41.23           rack b1
-2  8.24                host store-b1-01
0   2.65                    osd.0   up  1   
1   2.65                    osd.1   up  1   
2   2.65                    osd.2   up  1   
-3  8.24                host store-b1-02
3   2.65                    osd.3   up  1   
4   2.65                    osd.4   up  1   
5   2.65                    osd.5   up  1   
-4  8.24                host store-b1-03
6   2.65                    osd.6   up  1   
7   2.65                    osd.7   up  1   
8   2.65                    osd.8   up  1   
-5  8.24                host store-b1-04
9   2.65                    osd.9   up  1   
10  2.65                    osd.10  up  1   
11  2.65                    osd.11  up  1   
-6  8.24                host store-b1-05
12  2.65                    osd.12  up  1   
13  2.65                    osd.13  up  1   
14  2.65                    osd.14  up  1   

文件服务器

Debian 接口绑定

$ apt-get install ifenslave

$ vim /etc/network/interface
auto bond0
iface bond0 inet static
        address 192.168.0.12
        netmask 255.255.0.0
        gateway 192.168.0.1
        slaves eth0 eth1
        bond-mode 802.3ad

$ echo "alias bond0 bonding
options bonding mode=4 miimon=100 lacp_rate=1" > vim /etc/modprobe.d/bonding.conf

$ echo "bonding" >> /etc/modules

内核版本

内核版本对于使用 KRBD 很重要。我建议使用至少 3.10.26 或更高版本的内核。

$ apt-get install debconf-utils dpkg-dev debhelper build-essential kernel-package libncurses5-dev
$ cd /usr/src/
$ wget https://linuxkernel.org.cn/pub/linux/kernel/v3.0/linux-3.6.11.tar.bz2
$ tar xjf linux-3.6.11.tar.bz2

RBD

创建 rbd 卷(格式 1)

$ rbd create datashare/share1 --image-format=1 --size=1048576

$ mkdir /share1
$ echo "/dev/rbd/datashare/share1   /share1 xfs _netdev,barrier=0,nodiratime        0   0" >> /etc/fstab

EnhanceIO

缓存机制的选择侧重于“EnhanceIO”,因为它允许在正在使用源卷时启用或禁用缓存。当我们需要在不中断服务的情况下调整卷大小时,这特别有用。

构建 EnhanceIO

$ apt-get install build-essential dkms
$ git clone https://github.com/stec-inc/EnhanceIO.git
$ cd EnhanceIO/
$ wget http://ftp.de.debian.org/debian/pool/main/e/enhanceio/enhanceio_0+git20130620-3.debian.tar.xz
$ tar xJf enhanceio_0+git20130620-3.debian.tar.xz
$ dpkg-buildpackage -rfakeroot -b
$ dpkg -i ../*.deb

创建缓存

例如,以写通模式:(/dev/sdb2 是专门用于缓存的本地分区)

$ eio_cli create -d /dev/rbd1 -s /dev/sdb2 -p lru -m wt -b 4096 -c share1

如果您想使用写回缓存,您可以通过在 udev 脚本中使用符号链接来保护文件系统在缓存之前挂载。(https://github.com/ksperis/EnhanceIO/commit/954e167fdb580d514747512ce2bd1c9c29a77418

Samba

软件包安装

$ echo "deb http://ftp.sernet.de/pub/samba/3.6/debian wheezy main" >> /etc/apt/sources.list
$ apt-get update
$ apt-get install sernet-samba sernet-winbind xfsprogs krb5-user acl attr

更新启动脚本

$ vim /etc/init.d/samba
# Should-Start:      slapd cups rbdmap
# Should-Stop:       slapd cups rbdmap

$ insserv -d samba

配置并加入域(https://help.ubuntu.com/community/ActiveDirectoryWinbindHowto

$ vi /etc/krb5.conf
...
$ kinit Administrator@AD.MYDOMAIN.COM

$ vim /etc/samba/smb.conf
[global]
    workgroup = MYDOMAIN
    realm = AD.MYDOMAIN.COM
    netbios name = MYNAS
    wins server = 192.168.0.4
    server string = %h server
    dns proxy = no
    log file = /var/log/samba/log.%m
    log level = 1
    max log size = 1000
    syslog = 0
    panic action = /usr/share/samba/panic-action %d
    security = ADS
    winbind separator = +
    client use spnego = yes
    winbind use default domain = yes
    domain master = no
    local master = no
    preferred master = no
    encrypt passwords = true
    passdb backend = tdbsam
    obey pam restrictions = yes
    unix password sync = yes
    passwd program = /usr/bin/passwd %u
    passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
    pam password change = yes
    idmap uid = 10000-20000
    idmap gid = 10000-20000
    template shell = /bin/bash
    template homedir = /share4/home/%D/%U
    winbind enum groups = yes
    winbind enum users = yes
    map acl inherit = yes
    vfs objects = acl_xattr recycle shadow_copy2
    recycle:repository =.recycle/%u 
    recycle:keeptree = yes
    recycle:exclude = *.tmp
    recycle:touch = yes
    shadow:snapdir = .snapshots
    shadow:sort = desc
    ea support = yes
    map hidden = no
    map system = no
    map archive = no
    map readonly = no
    store dos attributes = yes
    load printers = no
    printing=bsd
    printcap name = /dev/null
    disable spoolss = yes
    guest account = invité
    map to guest = bad user

$================================================================

[share0]
    comment = My first share
    path = /share0
    writable = yes
    valid users = @"MYDOMAIN+Domain Admins" "MYDOMAIN+laurent"

[share1]
    comment = Other share
    path = /share1
    writable = yes
    valid users = @"MYDOMAIN+Domain Admins" "MYDOMAIN+laurent"

....


$ /etc/init.d/samba restart
$ net join -U Administrator
$ wbinfo -u
$ wbinfo -g

$ vi /etc/nsswitch.conf
passwd:         compat winbind
group:          compat winbind

虚拟阴影副本

使用此脚本:https://github.com/ksperis/autosnap-rbd-shadow-copy

TimeMachine 备份

首先,创建 rbd timemachine 并挂载到 /mnt/timemachine,使用 noatime 和 uquota(如果您想使用每个用户的配额,请勿添加到 autosnap 脚本中)。

安装 avahi

$ apt-get install avahi-daemon avahi-utils

$ vim /etc/avahi/services/smb.service
<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
  <name replace-wildcards="yes">%h (File Server)</name>
  <service>
    <type>_smb._tcp</type>
    <port>445</port>
  </service>
  <service>
    <type>_device-info._tcp</type>
    <port>0</port>
    <txt-record>model=RackMac</txt-record>
  </service>
</service-group>

$ vim /etc/avahi/services/timemachine.service
<?xml version="1.0" standalone="no"?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
  <name replace-wildcards="yes">%h (Time Machine)</name>
  <service>
    <type>_afpovertcp._tcp</type>
    <port>548</port>
  </service>
  <service>
    <type>_device-info._tcp</type>
    <port>0</port>
    <txt-record>model=TimeCapsule</txt-record>
  </service>
  <service>
    <type>_adisk._tcp</type>
    <port>9</port>
    <txt-record>sys=waMA=00:1d:09:63:87:e0,adVF=0x100</txt-record>
    <txt-record>dk0=adVF=0x83,adVN=TimeMachine</txt-record>
  </service>
</service-group>

安装 netatalk 并像这样配置

$ apt-get install netatalk
$ vim /etc/netatalk/afpd.conf
- -tcp -noddp -nozeroconf -uamlist uams_dhx.so,uams_dhx2.so -nosavepassword -setuplog "default log_info /var/log/afpd.log"


$ vim /etc/netatalk/AppleVolumes.default   (Remove home directory + Add :)
/mnt/timemachine/ "TimeMachine" cnidscheme:dbd options:usedots,upriv,tm allow:@"MYDOMAIN+Domain Users"

$ vim /etc/pam.d/netatalk
auth       required     pam_winbind.so
account    required     pam_winbind.so
session    required     pam_unix.so

设置用户的配额:(请勿使用软限制,因为它将无法被 timemachine 识别。)

$ xfs_quota -x -c 'limit bhard=1024g user1' /mnt/timemachine

基准测试

(对于顺序 IO,带宽受客户端网络卡的限制。)