版权声明:本博客欢迎转载,转载时请以超链接形式标明文章原始出处!谢谢!
博客地址:http://blog.csdn.net/i_chips
Ubuntu下Swift异地多节点部署指导书
崔炳华
2013年12月30日
1 环境准备
1.1 部署目的
本指导书的目的是部署一个支持多租户的异地多节点的对象存储系统(OpenStack Swift),认证采用LDAP + OpenStack Keystone,仪表盘采用OpenStack Horizon。
1.2 版本
- Linux系统版本:Ubuntu Server 12.04.1 LTS;
- Python版本:2.7.3(稍后安装);
- OpenStack Swift版本:Storage Node为1.0,ProxyNode为1.8.0(稍后安装);
- Python-swiftclient版本:Storage Node为1.3.0,ProxyNode为1.8.0(稍后安装)。
- OpenStack Keystone版本:0.4.1(稍后安装);
- Python-keystoneclient版本:0.4.1(稍后安装);
- OpenStack Horizon版本:Master版本(稍后安装);
注意,python-keystoneclient与Keystone的版本需要统一,否则可能会出现版本兼容性问题,采用依赖项的方式安装python-keystoneclient,可确保不会出现版本兼容性问题。
1.3 节点IP
- Proxy Node IP/Auth Node IP:192.168.1.75(主机名:proxy.openstack.org);
- Storage Node (zone 1) IP:192.168.1.72(有2个2T的存储设备);
- Storage Node (zone 2) IP:192.168.1.73(有1个2T的存储设备);
- Storage Node (zone 3) IP:125.70.12.85(异地存储节点,VPN拨号后IP会变为192.168.0.25;有1个10G的存储设备)。
1.4 替换镜像(可选步骤)
“网速较慢”或者“安装软件失败”的情况下,可以考虑替换成国内的镜像:
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.5 系统时间
vsroot@ubuntu:~$ date #查看系统时间是否正确,正确的话则忽略下面两步
vsroot@ubuntu:~$ sudo date -s"2013-11-04 15:05:57" #设置系统时间
vsroot@ubuntu:~$ sudo hwclock –w #写入硬件时间
1.6 关闭防火墙
请确保已关闭SELinux。另外,建议关闭防火墙:
vsroot@ubuntu:~$ sudo ufw disable #关闭防火墙
2 异地存储节点配置
2.1 安装拨号软件
vsroot@ubuntu:~$ sudo apt-get install pptp-linux
2.2 用pptpsetup命令建立VPN连接
使用如下命令可以建立VPN连接:
sudo pptpsetup --create <VPN_NAME>--server <VPN_SERVER_IP> --username <USERNAME> --password <PASSWORD> --encrypt --start
其中,--encrypt表示加密,--start表示启动。
本例中,由于没有对VPN加密,所以命令如下:
vsroot@ubuntu:~$ sudo pptpsetup --create vpn_tfxg --server 125.70.0.76 --username fhyxj --password fhyxj --start
2.3 启动和断开VPN连接
启动VPN的命令如下,建议采用后台命令(nohup<command> &):
vsroot@ubuntu:~$ sudo pon vpn_tfxg debug dump logfd 2 nodetach
另外,断开VPN的命令如下:
vsroot@ubuntu:~$ sudo poff vpn_tfxg
断开全部VPN的命令如下:
vsroot@ubuntu:~$ sudo poff -a
2.4 添加路由
使用ifconfig查看,可以看到新增了ppp0这个路由,内网IP为192.168.0.25,网关为192.168.0.254。我们还需要添加路由,才能正常访问。
一种添加路由的方法如下:
vsroot@ubuntu:~$ sudo route add default dev ppp0
上面这条命令有可能导致以后只能访问192.168.0.25,而无法访问125.70.12.85,进而导致“启动VPN”进程随时可能中断。
解决办法是:“增加路由”采用后台命令(nohup<command> &)。
另一种添加路由的方法如下(推荐):
vsroot@ubuntu:~$ sudo route add192.168.1.72 gw 192.168.0.254
vsroot@ubuntu:~$ sudo route add192.168.1.73 gw 192.168.0.254
vsroot@ubuntu:~$ sudo route add192.168.1.75 gw 192.168.0.254
这样,就可以确保125.70.12.85和192.168.0.25都能ping通Swift的所有节点。
接下来就可以直接访问192.168.0.25了。
3 通用的OS配置
3.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
3.2 在每个节点上安装Swift库
swift@ubuntu:~# sudo apt-get install python-software-properties
swift@ubuntu:~# sudo add-apt-repository ppa:swift-core/release #忽略这步报错
swift@ubuntu:~# sudo add-apt-repository cloud-archive:grizzly #也可选择H版等
swift@ubuntu:~# sudo apt-get update
swift@ubuntu:~# sudo apt-get install swift python-swiftclient openssh-server
3.3 在每个节点上创建Swift工作目录
swift@ubuntu:~# sudo mkdir -p /etc/swift
swift@ubuntu:~# sudo chown -R swift:swift/etc/swift/
3.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 192.168.0.25:/etc/swift/
3.5 在每个节点上设置IP的环境变量
在所有的Storage Node上根据自身真实IP设置如下:
swift@ubuntu:~# export STORAGE_LOCAL_NET_IP=192.168.0.25
在所有的Proxy Node上根据自身真实IP设置如下:
swift@ubuntu:~# export PROXY_LOCAL_NET_IP=192.168.1.75
考虑到export命令只对当前用户的当前会话生效,也可以考虑将环境变量写到bashrc中:
swift@ubuntu:~# sudo su
root@ubuntu:~# vim ~/.bashrc #设置IP的环境变量
root@ubuntu:~# . ~/.bashrc #使之立即生效
root@ubuntu:~# su swift
现在,输入命令echo $STORAGE_LOCAL_NET_IP或者echo $PROXY_LOCAL_NET_IP就可以查看到正确结果了。
3.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
4 配置Proxy Node
4.1 安装swift-proxy库
swift@ubuntu:~# sudo apt-get install swift-proxy memcached
4.2 配置memcached并重启服务
swift@ubuntu:~# sudo perl -pi -e "s/-l127.0.0.1/-l $PROXY_LOCAL_NET_IP/" /etc/memcached.conf
swift@ubuntu: ~# sudo service memcached restart
最好检查一下memcached服务是否已经正常启动。
4.3 创建Proxy服务器配置文件
swift@ubuntu:~# cat >/etc/swift/proxy-server.conf <<EOF
[DEFAULT]
bind_port= 8080
workers =8
user =swift
[pipeline:main]
pipeline= healthcheck cache 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:healthcheck]
use =egg:swift#healthcheck
[filter:cache]
use =egg:swift#memcache
memcache_servers= $PROXY_LOCAL_NET_IP:11211
EOF
4.4 创建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小时之后才能被移动。
4.5 让ring记录每个Storage Node的存储设备
export ZONE=1
export STORAGE_LOCAL_NET_IP=192.168.1.72
export WEIGHT=100
export DEVICE=sdb1
sudo swift-ring-builder account.builder add z$ZONE-$STORAGE_LOCAL_NET_IP:6002/$DEVICE $WEIGHT
sudo swift-ring-builder container.builder add z$ZONE-$STORAGE_LOCAL_NET_IP:6001/$DEVICE $WEIGHT
sudo swift-ring-builder object.builder add z$ZONE-$STORAGE_LOCAL_NET_IP:6000/$DEVICE $WEIGHT
export ZONE=1
export STORAGE_LOCAL_NET_IP=192.168.1.72
export WEIGHT=100
export DEVICE=sdc1
sudo swift-ring-builder account.builder add z$ZONE-$STORAGE_LOCAL_NET_IP:6020/$DEVICE $WEIGHT
sudo swift-ring-builder container.builder add 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=192.168.1.73
export WEIGHT=100
export DEVICE=sdb1
sudo swift-ring-builder account.builder add z$ZONE-$STORAGE_LOCAL_NET_IP:6002/$DEVICE $WEIGHT
sudo swift-ring-builder container.builder add z$ZONE-$STORAGE_LOCAL_NET_IP:6001/$DEVICE $WEIGHT
sudo swift-ring-builder object.builder add z$ZONE-$STORAGE_LOCAL_NET_IP:6000/$DEVICE $WEIGHT
export ZONE=3
export STORAGE_LOCAL_NET_IP=192.168.0.25
export WEIGHT=1
export DEVICE=sdb1
sudo swift-ring-builder account.builder add z$ZONE-$STORAGE_LOCAL_NET_IP:6002/$DEVICE $WEIGHT
sudo swift-ring-builder container.builder add z$ZONE-$STORAGE_LOCAL_NET_IP:6001/$DEVICE $WEIGHT
sudo swift-ring-builder object.builder add z$ZONE-$STORAGE_LOCAL_NET_IP:6000/$DEVICE $WEIGHT
注意,这里需要根据StorageNode的存储设备实际情况来设定:
- DEVICE需要根据StorageNode上的/etc/rsyncd.conf中的path来设置,例如path为/srv/node/,查看/srv/node/下存在目录sdb1上的话,则DEVICE值为sdb1;
- ZONE从1开始计数,逐次加1;当一个StorageNode存在多个DEVICE时,可以设为同一个ZONE(推荐),也可以设为多个ZONE;
- 每个挂载分区的大小都一样的话,WEIGHT(权重)不妨均设置成100。
4.6 确认ring 的内容是否正确并平衡(Rebalance)ring
swift-ring-builder account.builder
swift-ring-builder container.builder
swift-ring-builder object.builder
sudo swift-ring-builder account.builder rebalance
sudo swift-ring-builder container.builder rebalance
sudo swift-ring-builder object.builder rebalance
4.7 拷贝ring到其它所有节点
swift@ubuntu:~# scp /etc/swift/*.ring.gz 192.168.1.72:/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
4.8 开启Proxy 服务
swift@ubuntu:~# sudo swift-init proxy start
5 配置Storage Node
5.1 在所有StorageNode上安装库
swift@ubuntu:~# sudo apt-get install swift-account swift-container swift-object xfsprogs
5.2 为StorageNode的每个存储设备安装XFS逻辑卷
需要根据StorageNode的存储设备实际情况,为每个存储设备安装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
5.3 创建rsync配置文件
swift@ubuntu:~# sudo su
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
5.4 修改rsync标签
swift@ubuntu:~# sudo perl -pi -e's/RSYNC_ENABLE=false/RSYNC_ENABLE=true/' /etc/default/rsync
5.5 启动rsync服务
swift@ubuntu:~# sudo service rsync restart
如果服务不能正常启动,请检查rsync配置文件。
确认rsync是否已连接所有服务:
swift@ubuntu:~# rsyncrsync://pub@$STORAGE_LOCAL_NET_IP/
5.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
5.7 启动存储服务
swift@ubuntu:~# sudo swift-init all start
或者单步执行,参照如下:
swift@ubuntu:~# sudo swift-init object-server start
swift@ubuntu:~# sudo swift-init object-replicator start
swift@ubuntu:~# sudo swift-init object-updater start
swift@ubuntu:~# sudo swift-init object-auditor start
swift@ubuntu:~# sudo swift-init container-server start
swift@ubuntu:~# sudo swift-init container-replicator start
swift@ubuntu:~# sudo swift-init container-updaterstart
swift@ubuntu:~# sudo swift-init container-auditor start
swift@ubuntu:~# sudo swift-init account-server start
swift@ubuntu:~# sudo swift-init account-replicator start
swift@ubuntu:~# sudo swift-init account-auditor start
6 配置Keystone
Keystone的相关组件,均配置在认证节点(本文中和代理节点相同)上。
6.1 安装相关库
swift@ubuntu:~# sudo su
root@ubuntu:~# sudo apt-get install python-dev libxml2-dev libxslt1-dev libsasl2-dev libsqlite3-dev libssl-dev libldap2-dev python-pip
6.2 安装Keystone库
root@ubuntu:~# mkdir -p /opt/stack
root@ubuntu:~# cd /opt/stack
root@ubuntu:/opt/stack# git clone https://github.com/openstack/keystone.gitroot@ubuntu:/opt/stack# cd keystone
root@ubuntu:/opt/stack/keystone# python tools/install_venv.py #需要虚拟环境的话,才执行这步(推荐)
root@ubuntu:/opt/stack/keystone# sudo pip install -r requirements.txt #安装Keystone依赖库,如果出现超时,则需要多操作几次
root@ubuntu:/opt/stack/keystone# sudo pipinstall -r test-requirements.txt #同上
root@ubuntu:/opt/stack/keystone# sudo pythonsetup.py install
以下两条命令可以激活虚拟环境:
root@ubuntu:/opt/stack/keystone# source.venv/bin/activate
root@ubuntu:/opt/stack/keystone# python
6.3 配置Keystone
root@ubuntu:/opt/stack/keystone# mkdir -p /etc/keystone
root@ubuntu:/opt/stack/keystone#cp ~/keystone/etc/* /etc/keystone/
root@ubuntu:/opt/stack/keystone# mv /etc/keystone/keystone.conf.sample /etc/keystone/keystone.conf
root@ubuntu:/opt/stack/keystone# mv /etc/keystone/logging.conf.sample /etc/keystone/logging.conf
Keystone的核心配置文件是/etc/keystone/keystone.conf,如果不希望采用默认值,可对其手动设置,例如:
public_bind_host = 192.168.1.75
admin_bind_host = 192.168.1.75
6.4 启动Keystone服务
初始化并同步数据库schema,Keystone会自动连接数据库,完成Table创建等工作(该命令在哪个目录执行,keystone.db就在哪里生成,并会同步到/etc/keystone/下):
root@proxy:~/keystone# keystone-manage db_sync
初始化证书到/etc/keystone/ssl(以哪个用户来配置的keystone,就写哪个用户):
root@ubuntu:/opt/stack/keystone# keystone-manage pki_setup --keystone-user root --keystone-group root
启动Keystone服务,建议采用后台命令(nohup<command> &):
root@ubuntu:/opt/stack/keystone# sudo keystone-all
注意,上面这条命令必须在~/keystone这个目录下以root身份执行,否则后续使用keystoneuser-list等命令时,可能会报如下错:An unexpected error prevented the server fromfulfilling your request. (OperationalError) no such table: domain u'SELECTdomain.id AS domain_id, domain.name AS domain_name, domain.enabled ASdomain_enabled, domain.extra AS domain_extra \nFROM domain \nWHERE domain.id =?' ('default',) (HTTP 500)。
6.5 导入环境变量
root@ubuntu:/opt/stack/keystone# exportSERVICE_TOKEN=ADMIN
root@ubuntu:/opt/stack/keystone# exportSERVICE_ENDPOINT=http://$PROXY_LOCAL_NET_IP:35357/v2.0
root@ubuntu:/opt/stack/keystone# vim ~/.bashrc
export SERVICE_TOKEN=ADMIN
export SERVICE_ENDPOINT=http://$PROXY_LOCAL_NET_IP:35357/v2.0
root@ubuntu:/opt/stack/keystone# . ~/.bashrc #使之立即生效
以上操作避免了在后续的每条keystone命令中都得加上--token ADMIN --endpoint http://$PROXY_LOCAL_NET_IP:35357/v2.0。
6.6 Keystone常用查看命令
现在就可以使用以下的常用查看命令了:
root@ubuntu:/opt/stack/keystone# keystone tenant-list
root@ubuntu:/opt/stack/keystone# keystone user-list
root@ubuntu:/opt/stack/keystone# keystone role-list
root@ubuntu:/opt/stack/keystone# keystone service-list
root@ubuntu:/opt/stack/keystone# keystone endpoint-list
6.7 Keystone常用创建命令
新建租户adminTenant,会生成相应的Tenant id:
root@ubuntu:/opt/stack/keystone# keystone tenant-create --name adminTenant --description "Admin Tenant" --enabled true
新建用户admin,需要用到上一步的Tenant id:
root@ubuntu:/opt/stack/keystone# keystone user-create --tenant_id 1ba28c96213b4db48d70a1de287931c4 --name admin --pass openstack --enabled true
新建管理角色admin,会生成相应的Role id:
root@ubuntu:/opt/stack/keystone# keystone role-create --name admin
为admin用户增加管理角色,将刚才创建的User、Tenant和Role关联起来:
root@ubuntu:/opt/stack/keystone# keystone user-role-add \
--user-id 8c6129dcbd5e48f1bf2b6046e0d3a96b \
--tenant-id 1ba28c96213b4db48d70a1de287931c4\
--role-id d27809c045a043b0aa2bbfc73752706a
注意,如果要考虑多租户情况,我们还需要再重复一遍上面的这几步操作,否则可以忽略以下步骤:
新建租户testTenant,会生成相应的Tenant id:
root@ubuntu:/opt/stack/keystone# keystone tenant-create --name testTenant --description "Test Tenant" --enabled true
新建用户test,需要用到上一步的Tenant id:
root@ubuntu:/opt/stack/keystone# keystone user-create --tenant_id ca53971497f5482aa9d583cdba70f627 --name test --pass openstack --enabled true
新建普通角色swiftoperator,会生成相应的Role id:
root@ubuntu:/opt/stack/keystone# keystone role-create --name swiftoperator
为test用户增加普通角色,将刚才创建的User、Tenant和Role关联起来:
root@ubuntu:/opt/stack/keystone# keystone user-role-add \
--user-id 9eb28546f6654bfdab834f80f8f94e86 \
--tenant-id ca53971497f5482aa9d583cdba70f627\
--role-id ab94f65ba0474b5bb5d3be489af8e644
6.8 访问Keystone获取Token
访问认证授权地址,预期都会成功获取授权:
root@ubuntu:/opt/stack/keystone# curl -d'{"auth": {"tenantName": "adminTenant","passwordCredentials":{"username": "admin", "password":"openstack"}}}' -H"Content-type: application/json" http://$PROXY_LOCAL_NET_IP:35357/v2.0/tokens |python -mjson.tool
root@ubuntu:/opt/stack/keystone# curl -d'{"auth": {"tenantName": "adminTenant","passwordCredentials":{"username": "admin", "password":"openstack"}}}' -H"Content-type: application/json" http://$PROXY_LOCAL_NET_IP:5000/v2.0/tokens |python -mjson.tool
7 Swift和Keystone的调试
Swift需要通过Keystone来完成用户的身份认证与权限控制,而不是采用自带的TempAuth。
7.1 修改Swift配置文件
修改Swift中的proxy-server配置文件/etc/swift/proxy-server.conf。在其中添加authtoken与keystoneauth组件,并将pipeline中的tempauth改为authtoken与keystoneauth,表示采用Keystone而不是TempAuth来完成用户身份认证和权限控制。
authtoken是python-keystoneclient中的组件,用于访问Keystone;keystoneauth是Swift中的组件,用于一些附加的条件设置。
root@ubuntu:/opt/stack/keystone# cat > /etc/swift/proxy-server.conf<<EOF
[DEFAULT]
bind_port = 8080
workers = 8
user = swift
[pipeline:main]
pipeline = healthcheck cache authtoken keystoneauth proxy-logging proxy-server
[app:proxy-server]
use = egg:swift#proxy
allow_account_management = true
account_autocreate = true
set log_level = DEBUG
set log_name = proxy-server
[filter:proxy-logging]
use = egg:swift#proxy_logging
[filter:authtoken]
paste.filter_factory =keystoneclient.middleware.auth_token:filter_factory
auth_host = $PROXY_LOCAL_NET_IP
auth_port = 35357
auth_protocol = http
service_host = $PROXY_LOCAL_NET_IP
service_port = 5000
admin_token = ADMIN
# set log_level = DEBUG
# set log_name = authtoken
[filter:keystoneauth]
use = egg:swift#keystoneauth
operator_roles = admin, swiftoperator
reseller_prefix = AUTH_
set log_level = DEBUG
set log_name = keystoneauth
[filter:healthcheck]
use = egg:swift#healthcheck
[filter:cache]
use = egg:swift#memcache
memcache_servers = $PROXY_LOCAL_NET_IP:11211
EOF
7.2 重启Swift服务
root@ubuntu:/opt/stack/keystone# sudo swift-init proxy restart
7.3 创建Service和Endpoint
为Swift创建Service,会生成相应的Service id:
root@ubuntu:/opt/stack/keystone# keystone service-create --name=Swift --type=object-store --description="Swift Object Store Service"
为Swift创建Endpoint,会用到Swift这个Service对应的Service id,以及adminTenant这个Tenant对应的Tenant id:
root@ubuntu:/opt/stack/keystone# keystone endpoint-create --region RegionOne \
--service_id b645a621b27b476ea897cc51563ee73e --publicurl \
http://192.168.1.75:8080/v1/AUTH_1ba28c96213b4db48d70a1de287931c4 \
--adminurl http://192.168.1.75:8080 --internalurl \
http://192.168.1.75:8080/v1/AUTH_1ba28c96213b4db48d70a1de287931c4
考虑到多租户情况,Swift的Endpoint可以简单地创建如下:
root@ubuntu:/opt/stack/keystone# keystone endpoint-create --region RegionOne \
--service_id b645a621b27b476ea897cc51563ee73e --publicurl \
'http://192.168.1.75:8080/v1/AUTH_$(tenant_id)s' \
--adminurl http://192.168.1.75:8080 --internalurl \
'http://192.168.1.75:8080/v1/AUTH_$(tenant_id)s'
注意,上面这条命令中的两个$符号也可以替换成%,效果是一样的。
此外,考虑到稍后我们还会运行Horizon,所以我们需要为我们的Keystone也创建一个Service以及相应的Endpoint。否则,Horizon将无法通过Keystone来获得Keystone的服务端口。
为Keystone创建Service,会生成相应的Serviceid:
root@ubuntu:~/keystone# keystone service-create --name=Keystone --type=identity --description="KeystoneIdentity Service"
为Keystone创建Endpoint,会用到Keystone这个Service对应的Serviceid:
root@ubuntu:~/keystone# keystone endpoint-create --region RegionOne \
--service-id 8ffef26fe4544cb7803c299bee2aadfc \
--publicurl http://controller:5000/v2.0 \
--internalurl http://controller:5000/v2.0 \
--adminurl http://controller:35357/v2.0
7.4 测试curl命令
这一步会获取到Token id:
root@ubuntu:/opt/stack/keystone# curl -d'{"auth": {"tenantName": "adminTenant","passwordCredentials":{"username": "admin", "password":"openstack"}}}' -H"Content-type: application/json" http://$PROXY_LOCAL_NET_IP:5000/v2.0/tokens |python -mjson.tool
接着就可以用获取到的Token id和Endpoint访问Swift服务了。
7.5 Swift常用命令
检测swift命令是否正常工作,预期输出应为zerocontainers、zero objects和zero bytes:
root@ubuntu:~# swift -V 2 -A http://$PROXY_LOCAL_NET_IP:5000/v2.0 -U adminTenant:admin -K openstack stat
新建容器(一级子目录)mycontainer1:
root@ubuntu:~# swift -V 2 -A http://$PROXY_LOCAL_NET_IP:5000/v2.0 -U adminTenant:admin -K openstack post mycontainer1
把本地指定文件上传到一级子目录mycontainer1中:
root@ubuntu:~# swift -V 2 -A http://$PROXY_LOCAL_NET_IP:5000/v2.0 -U adminTenant:admin -K openstack upload mycontainer1 /etc/swift/*.builder
列出根目录的细节:
root@ubuntu:~# swift -V 2 -A http://$PROXY_LOCAL_NET_IP:5000/v2.0 -U adminTenant:admin -K openstack list
列出一级子目录的细节:
root@ubuntu:~# swift -V 2 -A http://$PROXY_LOCAL_NET_IP:5000/v2.0 -U adminTenant:admin -K openstack list mycontainer1
删除一级子目录mycontainer1下的某个指定文件:
root@ubuntu:~# swift -V 2 -A http://$PROXY_LOCAL_NET_IP:5000/v2.0 -U adminTenant:admin -K openstack delete mycontainer1 etc/swift/account.builder
把一级子目录mycontainer1中的资源都下载到本地当前目录:
root@ubuntu:~# swift -V 2 -A http://$PROXY_LOCAL_NET_IP:5000/v2.0 -U adminTenant:admin -K openstack download mycontainer1
8 安装LDAP
OpenStack在Grizzly版本上对LDAP验证机制已经有非常好的支持,但对LDAP服务有较为严苛的要求。
OpenStackKeystone利用现有的LDAP后端进行账户验证时,LDAP服务需要满足Keystone的一些较为严苛的需求,主要有以下几点:
- 用户和租户分别存储在不同的子树中。
- 角色必须作为用户及租户的一个属性记录在相应的子树中。
- 拥有LDAP服务的写权限,并且提前写入各个服务帐号(Nova、Glance、Cinder、Swift、Neutron、Ceilometer等组件)以及各组件所在的服务租户(即Service租户)。
8.1 安装LDAP库
root@ubuntu:~# apt-get install ldap-utils
root@ubuntu:~# apt-get install slapd #这一步执行过程中会要求输入Administrator的密码,不妨设为openstack
另外,附上完全移除LDAP的命令:apt-getpurge slapd。
8.2 验证LDAP登录
查看hosts信息:
root@ubuntu:~# cat /etc/hosts
127.0.0.1 localhost
192.168.1.75 proxy.openstack.org proxy
# The following lines are desirable forIPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
根据以上信息可知,这个环境上的登录DN(Distinguished Name)为 cn=admin,dc=openstack,dc=org。
使用如下命令可以验证是否配置成功:
root@ubuntu:~# ldapsearch -x -LLL -H ldap:/// -b d dc=openstack,dc=org dn
结果如下:
dn: dc=openstack,dc=org
dn: cn=admin,dc=openstack,dc=org
8.3 修改LDAP的默认schema
LDAP的默认schema不能直接和OpenStack配合使用,默认schema中缺少有些OpenStack的用户、角色、租户需要的属性,例如:enable、description等等,需要修改;其次,需要添加存储OpenStack相关模型(user、tenant、group、role、domain)的dn,以便保存数据。
下面新建两个ldif文件,以便分别完成上面的两件事情。
modify.ldif的内容为如下:
root@ubuntu:~# mkdir -p /opt/stack/ldap
root@ubuntu:~# cat > /opt/stack/ldap/modify.ldif <<EOF
dn: cn={0}core,cn=schema,cn=config
changetype: modify
add: olcAttributeTypes
olcAttributeTypes: {52}( 2.5.4.66 NAME 'enabled' DESC 'RFC2256: enabled of a group' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
dn: cn={0}core,cn=schema,cn=config
changetype: modify
delete: olcObjectClasses
olcObjectClasses: {7}( 2.5.6.9 NAME 'groupOfNames' DESC 'RFC2256: a group of names (DNs)' SUP top STRUCTURAL MUST ( member $ cn ) MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description ) )
-
add: olcObjectClasses
olcObjectClasses: {7}( 2.5.6.9 NAME 'groupOfNames' DESC 'RFC2256: a group of names (DNs)' SUP top STRUCTURAL MUST ( member $ cn ) MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description $ enabled) )
dn: cn={3}inetorgperson,cn=schema,cn=config
changetype: modify
delete: olcObjectClasses
olcObjectClasses: {0}( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' DESC 'RFC2798: Internet Organizational Person' SUP organizationalPerson STRUCTURAL MAY ( audio $ businessCategory $ carLicense $ departmentNumber $ displayName $ employeeNumber $ employeeType $ givenName $ homePhone $ homePostalAddress $ initials $ jpegPhoto $ labeledURI $ mail $ manager $ mobile $ o $ pager $ photo $ roomNumber $ secretary $ uid $ userCertificate $ x500uniqueIdentifier $ preferredLanguage $ userSMIMECertificate $ userPKCS12 ) )
-
add: olcObjectClasses
olcObjectClasses: {0}( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' DESC 'RFC2798: Internet Organizational Person' SUP organizationalPerson STRUCTURAL MAY ( audio $ businessCategory $ carLicense $ departmentNumber $ displayName $ employeeNumber $ employeeType $ givenName $ homePhone $ homePostalAddress $ initials $ jpegPhoto $ labeledURI $ mail $ manager $ mobile $ o $ pager $ photo $ roomNumber $ secretary $ uid $ userCertificate $ x500uniqueIdentifier $ preferredLanguage $ userSMIMECertificate $ userPKCS12 $ description $ enabled $ email ) )
EOF
将以上内容保存到对应的文件之后,执行如下命令:
root@ubuntu:~# ldapmodify -c -Y EXTERNAL -H ldapi:/// -f /opt/stack/ldap/modify.ldif
add.ldif的内容为如下:
root@ubuntu:~# cat > /opt/stack/ldap/add.ldif <<EOF
dn: ou=users,dc=openstack,dc=org
objectClass: top
objectClass: organizationalUnit
dn: ou=projects,dc=openstack,dc=org
objectClass: top
objectClass: organizationalUnit
dn: ou=roles,dc=openstack,dc=org
objectClass: top
objectClass: organizationalUnit
dn: ou=groups,dc=openstack,dc=org
objectClass: top
objectClass: organizationalUnit
dn: ou=domains,dc=openstack,dc=org
objectClass: top
objectClass: organizationalUnit
EOF
将以上内容保存到对应的文件之后,执行如下命令:
root@ubuntu:~# ldapadd -x -c -D "cn=admin,dc=openstack,dc=org" -w"openstack" -f /opt/stack/ldap/add.ldif
注意,上面的命令中,openstack是安装LDAP的时候给Administrator设置的密码。
8.4 修改Keystone配置文件
需要为Keystone配置文件新增如下部分配置:
root@ubuntu:~# vim /etc/keystone/keystone.conf
[identity]
driver = keystone.identity.backends.ldap.Identity
[ldap]
url = ldap://localhost
user = cn=admin,dc=openstack,dc=org
password = openstack
suffix = dc=openstack,dc=org
use_dumb_member = True
allow_subtree_delete = False
user_tree_dn = ou=users,dc=openstack,dc=org
tenant_tree_dn =ou=projects,dc=openstack,dc=org
role_tree_dn = ou=roles,dc=openstack,dc=org
group_tree_dn = ou=groups,dc=openstack,dc=org
domain_tree_dn =ou=domains,dc=openstack,dc=org
配置完成之后,需要重启Keystone服务,建议采用后台命令(nohup<command> &):
root@ubuntu:~# cd /opt/stack/keystone
root@ubuntu:/opt/stack/keystone# sudo keystone-all
8.5 初始化Keystone的基本用户
由于Keystone被重新配置,User、Role、Tenant等也需要重新创建。在~/keystone目录下创建一个脚本,名字为keystone_for_ldap.sh,内容如下:
#!/bin/sh
#
# Keystone basic configuration
ADMIN_PASSWORD=openstack
TEST_PASSWORD=openstack
get_id () {
echo `$@ | awk '/ id / { print $4 }'`
}
# Tenants
ADMIN_TENANT=$(get_id keystone tenant-create --name=adminTenant)
TEST_TENANT=$(get_id keystone tenant-create --name=testTenant)
# Users
ADMIN_USER=$(get_id keystone user-create --name=admin --pass="$ADMIN_PASSWORD" --email=admin@domain.com)
TEST_USER=$(get_id keystone user-create --name=test --pass="$TEST_PASSWORD" --email=test@domain.com)
# Roles
ADMIN_ROLE=$(get_id keystone role-create --name=admin)
SWIFT_ROLE=$(get_id keystone role-create --name=swiftoperator)
# Add Roles to Users in Tenants
keystone user-role-add --user-id $ADMIN_USER --role-id $ADMIN_ROLE --tenant-id $ADMIN_TENANT
keystone user-role-add --user-id $TEST_USER --role-id $SWIFT_ROLE --tenant-id $TEST_TENANT注意到,上面这个脚本,我们为adminTenant这个租户创建了用户admin,为testTenant这个租户创建了用户test。
接着,就可以执行这个脚本:
root@ubuntu:~# sh /opt/stack/ldap/keystone_for_ldap.sh
此外,需要使用keystone命令检查一下Swift和Keystone的Service和Endpoint是否正常。
由于Service没有发生变化,不用重新创建。Keystone的Endpoint也不用重新创建。而Swift的Endpoint已经考虑到了多租户情况的话,也不用重新创建。
8.6 重启Swift服务
root@ubuntu:~# sudo swift-init proxy restart
8.7 测试swift命令
我们用adminTenant这个租户下的admin用户来访问,预期可以成功:
root@ubuntu:~# swift -V 2 -A http://$PROXY_LOCAL_NET_IP:5000/v2.0 -U adminTenant:admin -K openstack stat
我们用testTenant这个租户下的test用户来访问,预期也可以成功:
root@ubuntu:~# swift -V 2 -A http://$PROXY_LOCAL_NET_IP:5000/v2.0 -U testTenant:test -K openstack stat
8.8 下载LDAP软件
Windows下有很多LDAP软件。一款比较小巧的软件:LDAP Browser,主要用于查看LDAP数据;另外,再介绍一款比较强大的软件:JXplorer,可以读写LDAP数据(需要先安装JDK)。
8.9 登录LDAP软件
按照如下配置,就可以在Windows客户端成功登录LDAP Browser并查看LDAP中的数据结构:
- Host:192.168.1.75
- Port:389
- Protocol:3
- Base DN:dc=openstack,dc=org(点击"Fetch DNs"可以自动获取DN)
- User:cn=admin,dc=openstack,dc=org
- Password:openstack
按照如下配置,就可以在Windows客户端成功登录JXplorer并查看LDAP中的数据结构:
- 主机:192.168.1.75
- 端口:389
- 协定:LDAP v3
- 基底DN:dc=openstack,dc=org
- 层级:用户+密码
- 使用者DN:cn=admin,dc=openstack,dc=org
- 密码:openstack
在JXplorer中的树形结构中可以看到:
- DC(Domain Component,域名)嵌套了两层,依次是org和openstack。
- openstack这个DC下有若干个OU(Organizational Unit,组织单元),依次是groups、projects、roles、users。
- users这个OU下有若干个CN(Common Name,常用名称),列出了所有的普通用户。
- roles这个OU下有若干个CN,列出了所有的角色。
- projects(相当于Tenant)这个OU下嵌套了有两层CN,第一层CN列出了所有的租户;每个租户下又列出了和该租户相关联的所有角色;在每个角色中的属性类型里,使用roleOccupant记录了和该租户的该角色相关联的所有用户。
如果我们想通过JXplorer来新增一个OpenStack用户,可以按照如下步骤操作:
- 选中users这个OU,单击右键菜单中的“新增”。
- 在弹出的“设定项目对象类别”的对话框中,在“输入RDN”不妨填写cn=testusercn(对应着Keystone中的User ID),然后单击“确定”。
- 在“表格编辑器”中,为sn(对应着Keystone中的User Name)这个属性类型设置一个用户名,例如:testuser;为enabled这个属性类型选择TRUE值;为userpassword这个属性类型设置密码,例如:openstack;然后单击“送出”,testuser这个用户就被创建成功了。
- 选中projects这个OU,再选中期望的租户,再选择期望的角色;在该角色的“表格编辑器”中,选中任一个roleOccupant属性类型,单击右键菜单中的“新增另一个值”,在value栏填写:cn=testusercn,ou=users,dc=openstack,dc=org,然后单击“送出”,testuser这个用户就被成功地加入到相应的租户和相应的角色了。
现在,用户testuser就可以正常访问Swift了。
9 安装Horizon
9.1 安装相关库
root@ubuntu:~# sudo apt-get install gcc python-dev libxml2-dev libxslt1-dev apache2
9.2 安装Horizon库
root@ubuntu:~# cd /opt/stack
root@ubuntu:/opt/stack# git clonehttps://github.com/openstack/horizon.git
root@ubuntu:/opt/stack# cd horizon
root@ubuntu:/opt/stack/horizon#./run_tests.sh #激活虚拟环境
root@ubuntu:/opt/stack/horizon # sudo pip install -r requirements.txt #安装Horizon依赖库,如果出现超时,则需要多操作几次
root@ubuntu:/opt/stack/horizon # sudo pip install -r test-requirements.txt #同上
9.3 配置Horizon
root@ubuntu:/opt/stack/horizon# cp openstack_dashboard/local/local_settings.py.example openstack_dashboard/local/local_settings.py
root@ubuntu:/opt/stack/horizon# sudo perl -pi -e"s/"127.0.0.1"/"$PROXY_LOCAL_NET_IP"/" openstack_dashboard/local/local_settings.py# 把OPENSTACK_HOST的默认IP改成自己的IP
9.4 修改Horizon代码
通过IE浏览器访问,虽然可以通过Keystone认证,但还是会抛出诸如此类的异常:ServiceCatalogException和Invalid servicecatalog service: compute。
接下来,我们需要修改Horizon代码,屏蔽掉其对Nova的调用,才能够解决上面这个问题。
首先,需要为/opt/stack/horizon/openstack_dashboard/usage/base.py中的get_limits和summarize两个函数增加一个return语句(相当于空函数),以避免后续调用Nova时抛出异常。
def get_limits(self):
return
def summarize(self, start, end):
return
其次,需要为/opt/stack/horizon/openstack_dashboard/usage/views.py中的get_context_data函数屏蔽掉和api.nova.extension_supported相关的两行代码,以避免后续调用Nova时抛出异常。
def get_context_data(self,**kwargs):
context = super(UsageView,self).get_context_data(**kwargs)
context['table'].kwargs['usage'] =self.usage
context['form'] = self.usage.form
context['usage'] = self.usage
# context['simple_tenant_usage_enabled']= \
# api.nova.extension_supported('SimpleTenantUsage', self.request)
return context
9.5 启动Horizon服务
由于Swift服务已经占用了8080端口,所以作为同一个节点上的Horizon服务,就不能再使用8080端口了,这里不妨改成8088端口,建议采用后台命令(nohup<command> &):
root@ubuntu:~/horizon# tools/with_venv.sh./manage.py runserver $PROXY_LOCAL_NET_IP:8088
接下来,就可以通过IE浏览器访问:
- 链接:http://192.168.1.75:8088
- 用户名:admin或者test(这两个用户分别来自不同的租户)
- 密码:openstack
效果如下图所示:
现在,我们就可以通过“项目/块存储/容器”来对Swift进行管控,例如Container和Object的增删改查等。
10 调试手段
10.1 日志查询
Swift的相关日志会输出到var/log/syslog中。
10.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]这一部分追加了setlog_level = DEBUG。
10.3 查看端口
使用“telnet IPPORT”或者“lsof -i PORT”命令查看端口。ProxyNode上主要关注端口11211/8080/2021等,StorageNode上主要关注Ring的相关端口,如6000/6001/6002等。
10.4 问题解决
- 问题一现象:pip从1.0版本升级到最新的1.5版本后,pip命令无法正常工作,出现如下提示:Wheel installs require setuptools >= 0.8 fordist-info support. pip's wheel support requires setuptools >= 0.8 fordist-info support.
- 问题一分析:根据提示可知,setuptools版本过低。经查询,setuptools当前版本是0.6。
- 问题一解决:解决办法参考:http://stackoverflow.com/questions/20905350/latest-pip-fails-with-requires-setuptools-0-8-for-dist-info,可以使用如下命令来升级版本:sudo pip install setuptools --no-use-wheel --upgrade。
- 问题二现象:安装mysql-python时,出现系统报错:EnvironmentError:mysql_config not found。
- 问题二分析:根据提示可知,没有mysql_config这个文件。执行find /-name mysql_config,没有任何数据,表明系统中确实没有mysql_config这个文件。
- 问题二解决:解决办法是执行如下命令:sudo apt-get install libmysqld-dev。
11 小结
Swift牺牲一定程度的数据一致性,来达到高可用性和可伸缩性,支持多租户模式、容器和对象读写操作,适合解决互联网的应用场景下非结构化数据存储问题。
由于Swift的弱一致性,所以在刚刚新建或刚刚删除一个文件后,我们立即去查看,可能看到的结果不符合预期,稍等一会儿再查看,就正常了。
11 参考资料
1) 《Instructions for aMultiple Server Swift Installation (Ubuntu)》,http://docs.openstack.org/developer/swift/howto_installmultinode.html
2) 《Quick Start》,https://github.com/cloudfs/ftp-cloudfs/wiki/QuickStart
3) 《Rackspace CloudFiles: Upload Files Using Secure FTP (SFTP) Client [ sftp-cloudfs ]》,http://www.cyberciti.biz/faq/rackspace-openstack-cloud-upload-files-using-sftp-cloudfs-proxy/
4) 《在Ubuntu下使用命令行进行vpn拨号》,http://blog.chinaunix.net/uid-26760055-id-3689701.html
5) 《Setting up aKeystone development environment》,http://docs.openstack.org/developer/keystone/setup.html
6) 《Developing with Keystone》,http://docs.openstack.org/developer/keystone/developing.html
7) 《OpenStack Keystone安装部署流程》,http://www.cnblogs.com/fczjuever/p/3278072.html
8) 《OpenStack Swift集群与Keystone的整合使用说明》,http://www.cnblogs.com/fczjuever/p/3278138.html
9) 《Openstack KeystoneLDAP后端配置》,http://blog.csdn.net/u011196209/article/details/10197725
10) 《Openstack Keystone LDAP Redux》,http://adam.younglogic.com/2012/02/openstack-keystone-ldap-redux/
11) 《Horizon Quickstart》,http://docs.openstack.org/developer/horizon/quickstart.html