1 环境准备
1.1 版本
Linux系统版本:Ubuntu Server 12.04.1 LTS;
Swift版本:1.0(稍后安装);
Python版本:2.7.3(稍后安装);
Python-swiftclient版本:1.3.0(稍后安装)。
1.2 节点IP
Proxy Node IP:172.17.10.14;
Storage Node 1 IP:172.17.10.10(有2个2T的存储设备);
Storage Node 2 IP:172.17.10.11(有1个2T的存储设备);
Storage Node 3 IP:172.17.10.13(有1个2T的存储设备)。
1.3 替换镜像(可选步骤)
“网速较慢”或者“安装软件失败”的情况下,可以考虑替换成国内的镜像:
vsroot@ubuntu:~$ sudo sed -i 's#us.archive.ubuntu.com#mirrors.163.com#g'/etc/apt/sources.list
vsroot@ubuntu:~$ sudo apt-get update
1.4 系统时间
vsroot@ubuntu:~$ date #查看系统时间是否正确,正确的话则忽略下面两步
vsroot@ubuntu:~$ sudo date -s"2013-11-04 15:05:57" #设置系统时间
vsroot@ubuntu:~$ sudo hwclock –w #写入硬件时间
1.5 关闭防火墙
请确保已关闭SELinux。
vsroot@ubuntu:~$ sudo ufw disable #关闭防火墙
2 通用的OS配置
2.1 在每个节点上创建Swift用户
vsroot@ubuntu:~$ sudo useradd -mk/home/swift -s /bin/bash swift
vsroot@ubuntu:~$ sudo passwd swift # 不妨把用户swift的密码设置成swift
编辑/etc/sudoers,在文件末尾添加以下内容:
vsroot@ubuntu:~$ sudo vim /etc/sudoers
# User alias specification
swift ALL=(ALL) NOPASSWD:ALL
然后,就可以切换到swift用户进行后续操作了:
vsroot@ubuntu:~$ su swift
2.2 在每个节点上安装Swift库
swift@ubuntu:~$ sudo apt-get installpython-software-properties
swift@ubuntu:~$ sudo add-apt-repository ppa:swift-core/release#忽略这步报错
swift@ubuntu:~$ sudo add-apt-repositorycloud-archive:grizzly #也可选择H版等
swift@ubuntu:~$ sudo apt-get update
swift@ubuntu:~$ sudo apt-get install swiftpython-swiftclient openssh-server
2.3 在每个节点上创建Swift工作目录
swift@ubuntu:~$ sudo mkdir -p /etc/swift
swift@ubuntu:~$ sudo chown -R swift:swift/etc/swift/
2.4 创建Swift配置文件
在任一节点上创建Swift配置文件:
swift@ubuntu:~$ cat>/etc/swift/swift.conf <<EOF
[swift-hash]
# random unique strings that can neverchange (DO NOT LOSE)
swift_hash_path_prefix = `od -t x8 -N 8 -An </dev/random`
swift_hash_path_suffix = `od -t x8 -N 8 -An </dev/random`
EOF
然后,依次拷贝该Swift配置文件到其它所有节点上:
swift@ubuntu:~$ scp /etc/swift/swift.conf 172.17.10.10:/etc/swift/
2.5 在每个节点上设置IP的环境变量
在所有的Storage Node上根据自身真实IP设置如下:
swift@ubuntu:~$ exportSTORAGE_LOCAL_NET_IP=172.17.10.10
在所有的Proxy Node上根据自身真实IP设置如下:
swift@ubuntu:~$ export PROXY_LOCAL_NET_IP=172.17.10.14
考虑到export命令只对当前用户的当前会话生效,也可以考虑将环境变量写到/etc/profile中:
swift@ubuntu:~$ sudo vim /etc/profile
swift@ubuntu:~$ source /etc/profile #当前会话立即生效
2.6 创建Swift服务目录并修改开机配置文件
swift@ubuntu:~$ sudo mkdir -p/var/run/swift
swift@ubuntu:~$ sudo chown swift:swift/var/run/swift
swift@ubuntu:~$ sudo vim /etc/rc.local
sudo mkdir -p /var/run/swift
sudo chown swift:swift /var/run/swift
exit 0
3 配置Proxy Node
3.1 安装swift-proxy库
swift@ubuntu:~$ sudo apt-get installswift-proxy memcached
3.2 创建SSL自签名证书
swift@ubuntu:~$ cd /etc/swift
swift@ubuntu:/etc/swift$ openssl req -new-x509 -nodes -out cert.crt -keyout cert.key
注意,证书的CommonName必须设置成Proxy Node的IP地址:172.17.10.14。
3.3 配置memcached并重启服务
swift@ubuntu:~$ sudo perl -pi -e "s/-l127.0.0.1/-l $PROXY_LOCAL_NET_IP/" /etc/memcached.conf
swift@ubuntu: ~$ sudo service memcachedrestart
最好检查一下memcached服务是否已经正常启动。
3.4 创建Proxy服务器配置文件
swift@ubuntu:~$ cat >/etc/swift/proxy-server.conf <<EOF
[DEFAULT]
cert_file= /etc/swift/cert.crt
key_file= /etc/swift/cert.key
bind_port= 8080
workers =8
user =swift
[pipeline:main]
pipeline= healthcheck proxy-logging cache tempauth proxy-logging proxy-server
[app:proxy-server]
use =egg:swift#proxy
allow_account_management= true
account_autocreate= true
[filter:proxy-logging]
use =egg:swift#proxy_logging
[filter:tempauth]
use =egg:swift#tempauth
user_system_root= testpass .admin https://$PROXY_LOCAL_NET_IP:8080/v1/AUTH_system
[filter:healthcheck]
use =egg:swift#healthcheck
[filter:cache]
use =egg:swift#memcache
memcache_servers= $PROXY_LOCAL_NET_IP:11211
EOF
3.5 创建account、container和object rings
swift@ubuntu:~$ cd /etc/swift
sudo swift-ring-builder account.builder create 18 3 1
sudo swift-ring-builder container.builder create 18 3 1
sudo swift-ring-builder object.builder create 18 3 1
其中,18代表partition的数目为2的18次幂,这个数字取决于你希望一个ring中会有多少个partition。3代表每个object的副本数。最后一个参数1,代表一个partition至少在1小时之后才能被移动。
3.6 让ring记录每个Storage Node的存储设备
export ZONE=1
export STORAGE_LOCAL_NET_IP=172.17.10.10
export WEIGHT=100
export DEVICE=sdb1
sudo swift-ring-builder account.builder addz$ZONE-$STORAGE_LOCAL_NET_IP:6002/$DEVICE $WEIGHT
sudo swift-ring-builder container.builderadd z$ZONE-$STORAGE_LOCAL_NET_IP:6001/$DEVICE $WEIGHT
sudo swift-ring-builder object.builder addz$ZONE-$STORAGE_LOCAL_NET_IP:6000/$DEVICE $WEIGHT
export ZONE=1
export STORAGE_LOCAL_NET_IP=172.17.10.10
export WEIGHT=100
export DEVICE=sdc1
sudo swift-ring-builder account.builder addz$ZONE-$STORAGE_LOCAL_NET_IP:6020/$DEVICE $WEIGHT
sudo swift-ring-builder container.builderadd z$ZONE-$STORAGE_LOCAL_NET_IP:6010/$DEVICE $WEIGHT
sudo swift-ring-builder object.builder add z$ZONE-$STORAGE_LOCAL_NET_IP:6030/$DEVICE$WEIGHT
export ZONE=2
export STORAGE_LOCAL_NET_IP=172.17.10.11
export WEIGHT=100
export DEVICE=sdb1
sudo swift-ring-builder account.builder addz$ZONE-$STORAGE_LOCAL_NET_IP:6002/$DEVICE $WEIGHT
sudo swift-ring-builder container.builderadd z$ZONE-$STORAGE_LOCAL_NET_IP:6001/$DEVICE $WEIGHT
sudo swift-ring-builder object.builder addz$ZONE-$STORAGE_LOCAL_NET_IP:6000/$DEVICE $WEIGHT
export ZONE=3
export STORAGE_LOCAL_NET_IP=172.17.10.13
export WEIGHT=100
export DEVICE=sdb1
sudo swift-ring-builder account.builder addz$ZONE-$STORAGE_LOCAL_NET_IP:6002/$DEVICE $WEIGHT
sudo swift-ring-builder container.builderadd z$ZONE-$STORAGE_LOCAL_NET_IP:6001/$DEVICE $WEIGHT
sudo swift-ring-builder object.builder addz$ZONE-$STORAGE_LOCAL_NET_IP:6000/$DEVICE $WEIGHT
注意,这里需要根据Storage Node的存储设备实际情况来设定:
① DEVICE需要根据Storage Node上的/etc/rsyncd.conf中的path来设置,例如path为/srv/node/,查看/srv/node/下存在目录sdb1上的话,则DEVICE值为sdb1;
② ZONE从1开始计数,逐次加1;当一个Storage Node存在多个DEVICE时,可以设为同一个ZONE(推荐),也可以设为多个ZONE;
③ 如果每个挂载分区的大小都一样,WEIGHT(权重)不妨均设置成100。
3.7 确认ring 的内容是否正确并平衡(Rebalance)ring
swift-ring-builder account.builder
swift-ring-builder container.builder
swift-ring-builder object.builder
sudo swift-ring-builder account.builderrebalance
sudo swift-ring-builder container.builderrebalance
sudo swift-ring-builder object.builderrebalance
3.8 拷贝ring到其它所有节点
swift@ubuntu:~$ scp /etc/swift/*.ring.gz 172.17.10.10:/etc/swift/
这里需要把account.ring.gz、container.ring.gz和object.ring.gz拷贝到其它所有Proxynode和Storage node的/etc/swift目录下。
并需要确保所有节点的配置文件都属于swift用户:
swift@ubuntu:~$ sudo chown -R swift:swift/etc/swift
3.9 开启Proxy 服务
swift@ubuntu:~$ sudo swift-init proxy start
4 配置Storage Node
4.1 在所有StorageNode上安装库
swift@Ubuntu:~$ sudo apt-get installswift-account swift-container swift-object xfsprogs
4.2 为StorageNode的每个存储设备安装XFS逻辑卷
需要根据Storage Node的存储设备实际情况,为每个存储设备安装XFS逻辑卷。
swift@ubuntu:~$ sudo fdisk /dev/sdb #需要建立独立分区
swift@ubuntu:~$ sudo mkfs.xfs -i size=512/dev/sdb1
如果文件系统小于100MiB或有大量小型档案,建议使用512字节区块;其余情况建议使用4KiB区块。
swift@ubuntu:~$ sudo vim /etc/fstab
/dev/sdb1 /srv/node/sdb1 xfs noatime,nodiratime,nobarrier,logbufs=80 0
swift@ubuntu:~$ sudo mkdir -p/srv/node/sdb1
swift@ubuntu:~$ sudo mount -o inode64 /srv/node/sdb1
如果磁盘大于1T,上面的mount命令可以加上-o inode64以达到更好的性能。
swift@ubuntu:~$ sudo chown swift:swift/srv/node/sdb1
4.3 创建rsync配置文件
swift@ubuntu:~$ sudo su #切换用户后,需重新定义STORAGE_LOCAL_NET_IP
root@ubuntu:~$ cat >/etc/rsyncd.conf<<EOF
uid = swift
gid = swift
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
address = $STORAGE_LOCAL_NET_IP
[account]
max connections = 2
path = /srv/node/
read only = false
lock file = /var/lock/account.lock
[container]
max connections = 2
path = /srv/node/
read only = false
lock file = /var/lock/container.lock
[object]
max connections = 2
path = /srv/node/
read only = false
lock file = /var/lock/object.lock
EOF
root@ubuntu:~$ su swift #切换用户后,需重新定义STORAGE_LOCAL_NET_IP
4.4 修改rsync标签
swift@ubuntu:~$ sudo perl -pi -e's/RSYNC_ENABLE=false/RSYNC_ENABLE=true/' /etc/default/rsync
4.5 启动rsync服务
swift@ubuntu:~$ sudo service rsync restart
如果服务不能正常启动,请检查rsync配置文件。
确认rsync是否已连接所有服务:
swift@ubuntu:~$ rsyncrsync://pub@$STORAGE_LOCAL_NET_IP/
4.6 创建account、container和object rings配置文件
swift@ubuntu:~$ cat>/etc/swift/account-server.conf <<EOF
[DEFAULT]
bind_ip = $STORAGE_LOCAL_NET_IP
workers = 2
[pipeline:main]
pipeline = account-server
[app:account-server]
use = egg:swift#account
[account-replicator]
[account-auditor]
[account-reaper]
EOF
swift@ubuntu:~$ cat>/etc/swift/container-server.conf <<EOF
[DEFAULT]
bind_ip = $STORAGE_LOCAL_NET_IP
workers = 2
[pipeline:main]
pipeline = container-server
[app:container-server]
use = egg:swift#container
[container-replicator]
[container-updater]
[container-auditor]
[container-sync]
EOF
swift@ubuntu:~$ cat>/etc/swift/object-server.conf <<EOF
[DEFAULT]
bind_ip = $STORAGE_LOCAL_NET_IP
workers = 2
[pipeline:main]
pipeline = object-server
[app:object-server]
use = egg:swift#object
[object-replicator]
[object-updater]
[object-auditor]
EOF
4.7 启动存储服务
swift@ubuntu:~$ sudo swift-init all start
或者单步执行,参照如下:
swift@ubuntu:~$ sudo swift-initobject-server start
swift@ubuntu:~$ sudo swift-initobject-replicator start
swift@ubuntu:~$ sudo swift-initobject-updater start
swift@ubuntu:~$ sudo swift-initobject-auditor start
swift@ubuntu:~$ sudo swift-initcontainer-server start
swift@ubuntu:~$ sudo swift-initcontainer-replicator start
swift@ubuntu:~$ sudo swift-initcontainer-updater start
swift@ubuntu:~$ sudo swift-initcontainer-auditor start
swift@ubuntu:~$ sudo swift-initaccount-server start
swift@ubuntu:~$ sudo swift-initaccount-replicator start
swift@ubuntu:~$ sudo swift-initaccount-auditor start
5 HTTP测试
5.1 获得X-Storage-Url和X-Auth-Token
swift@ubuntu:~$ curl -k -v -H'X-Storage-User: system:root' -H 'X-Storage-Pass: testpass' https://$PROXY_LOCAL_NET_IP:8080/auth/v1.0
5.2 检测是否可以使用HEAD命令查询account状态
命令格式如下:
curl -k -v -H 'X-Auth-Token:<token-from-x-auth-token-above>' <url-from-x-storage-url-above>
具体示例如下:
curl -k -v -H 'X-Auth-Token: AUTH_tk2e46a17833d5474cb29ea22720457ac1' https://$PROXY_LOCAL_NET_IP:8080/v1/AUTH_system
5.3 Swift常用命令
检测swift命令是否正常工作,预期输出应为zero containers、zero objects和zero bytes:
swift@ubuntu:~$ swift -Ahttps://$PROXY_LOCAL_NET_IP:8080/auth/v1.0 -U system:root -K testpass stat
新建一级子目录mycontainer1:
swift@ubuntu:~$ swift -Ahttps://$PROXY_LOCAL_NET_IP:8080/auth/v1.0 -U system:root -K testpass post mycontainer1
把本地指定文件上传到一级子目录mycontainer1中:
swift@ubuntu:~$ swift -Ahttps://$PROXY_LOCAL_NET_IP:8080/auth/v1.0 -U system:root -K testpass upload mycontainer1 /etc/swift/*.builder
列出根目录的细节:
swift@ubuntu:~$ swift -Ahttps://$PROXY_LOCAL_NET_IP:8080/auth/v1.0 -U system:root -K testpass list
列出一级子目录的细节:
swift@ubuntu:~$ swift -Ahttps://$PROXY_LOCAL_NET_IP:8080/auth/v1.0 -U system:root -K testpass list mycontainer1
删除一级子目录mycontainer1下的某个指定文件:
swift@ubuntu:~$ swift -Ahttps://$PROXY_LOCAL_NET_IP:8080/auth/v1.0 -U system:root -K testpass delete mycontainer1 etc/swift/account.builder
把一级子目录mycontainer1中的资源都下载到本地当前目录:
swift@ubuntu:~$ swift -Ahttps://$PROXY_LOCAL_NET_IP:8080/auth/v1.0 -U system:root -K testpass download mycontainer1
6 FTP测试
6.1 在ProxyNode上下载并安装ftp-cloudfs
方法一:
swift@ubuntu:~$ git clone https://github.com/cloudfs/ftp-cloudfs.git
swift@ubuntu:~$ cd ftp-cloudfs/
swift@ubuntu:~$ python setup.py install
swift@ubuntu:~$ sudo apt-get installpython-pip
swift@ubuntu:~$ pip install ftp-cloudfs
方法二:
swift@ubuntu:~$ sudo apt-get installpython-virtualenv
swift@ubuntu:~$ virtualenv ENV
swift@ubuntu:~$ source ENV/bin/activate
swift@ubuntu:~$ sudo apt-get installpython-pip
swift@ubuntu:~$ pip install --upgrade pip
swift@ubuntu:~$ pip install ftp-cloudfs
6.2 启动ftp-cloudfs服务
单用户情况下,可以使用如下命令启动ftp-cloudfs服务:
swift@ubuntu:~$ ftpcloudfs -b $PROXY_LOCAL_NET_IP -a https://$PROXY_LOCAL_NET_IP:8080/auth/v1.0 -f
多用户情况下,推荐使用如下命令启动ftp-cloudfs服务,性能会相对好些:
swift@ubuntu:~$ ftpcloudfs -b $PROXY_LOCAL_NET_IP -a https://$PROXY_LOCAL_NET_IP:8080/auth/v1.0 --memcache=$PROXY_LOCAL_NET_IP:11211--log-file /tmp/ftpcloufs.log
这里使用了Proxy Node的memcache作为共享缓存。此外,我们把FTP相关的log输出到/tmp/ftpcloufs.log中便于查看。如果作为产品发布,建议还是使用--syslog。
如果要停止ftp-cloudfs服务,可以使用这条命令:
swift@ubuntu:~$ kill `cat/tmp/ftpcloudfs.pid`
6.3 Windows客户端FTP访问
可以在Windows客户端安装FTP工具(例如FileZilla),或者直接通过IE浏览器简单访问ftp://172.17.10.14:2021。
主机:172.17.10.14
用户名:system:root
密码:testpass
端口:2021
预期可以访问成功,并能够正常地上传、下载、新建、删除、重命名文件和目录等。
6.4 Linux客户端FTP访问
swift@ubuntu:~$ ftp 172.17.10.14 2021
然后输入用户名密码,就可以访问成功并正常使用了。
常用的几个FTP命令如下:
cd remote-dir:进入远程主机目录。
ls [remote-dir] [local-file]:显示远程目录remote-dir,并存入本地文件local-file(和dir命令相同)。
mkdir dir-name:在远程主机中建一目录。
rmdir dir-name:删除远程主机目录。
rename [from] [to]:更改远程主机文件名。
delete remote-file:删除远程主机文件。
mdelete [remote-file]:删除远程主机文件。
get remote-file [local-file]:将远程主机文件remote-file传至本地文件local-file。
mget remote-files:传输多个远程文件。
put local-file [remote-file]:将本地文件local-file传送至远程主机。
mput local-file:将多个文件传输至远程主机。
pwd:显示远程主机的当前工作目录。
bye:退出ftp会话过程(和quit命令相同)。
7 调试手段
7.1 日志查询
Swift的相关日志会输出到var/log/syslog中。
7.2 增强日志
var/log/syslog可能日志太少影响定位问题,我们可以增强日志。参考http://docs.openstack.org/developer/swift/deployment_guide.html#account-server-configuration,可以在/etc/swift/proxy-server.conf等配置文件中设定log的输出等级为DEBUG。
例如,/etc/swift/proxy-server.conf文件中,[app:proxy-server]这一部分追加了setlog_level = DEBUG,[filter:tempauth]这一部分追加了set log_level = DEBUG。
7.3 查看端口
使用“telnet IPPORT”或者“lsof -i PORT”命令查看端口。Proxy Node上主要关注端口11211/8080/2021等,Storage Node上主要关注Ring的相关端口,如6000/6001/6002等。
8 小结
Swift牺牲一定程度的数据一致性,来达到高可用性和可伸缩性,支持多租户模式、容器和对象读写操作,适合解决互联网的应用场景下非结构化数据存储问题。
由于Swift的弱一致性,所以在刚刚新建或刚刚删除一个文件后,我们立即去查看,可能看到的结果不符合预期,稍等一会儿再查询,就正常了。