OpenStack Manila with ZFSonLinux を試す -1

本稿は、OpenStack Days 2016 Tokyo で発表させてもらった中で試した **ZFSonLinux** をバックエンドとして試した詳細を何回かに分けて記載します。今回初回なので、まずファイルシェアが出来き、マウントするまでです。

# OpenStack Manila 概要
OpenStack の中でファイルサーバを提供するプロジェクトです。アーキテクチャは **Cinder** と非常に良く似ているので考え方構成などは理解しやすいと思われる。

単品で試す場合はこちら。[OpenStack Manila on RDO](http://qiita.com/tksarah/items/3368b6e502ce5092340b)

# ZFSonLinux
ZFSは元々Solarisで実装されていたファイルシステムでしたが、Linux上でも使えるようにしたのがこれ。ここからは**2016年7月時点**での個人的見解ではあるが、使い勝手も楽で非常にストレージとして多機能であるため、OpenStackのバックエンドとして利用するには商用（エンタープライズストレージ）に引けをとらないということもあり今回選択した。技術者としてはいろいろ試せる方が面白いというのもある。

Manilaでサポートされている機能一覧としてはこちらを参照。[Manila share features support mapping](http://docs.openstack.org/developer/manila/devref/share_back_ends_feature_support_mapping.html)

# 評価環境
## 評価マシン 
OpenStack , ZFSonLinux 共に、
**CentOS Linux release 7.2.1511 (Core)**

## OpenStack Mitaka Release (centos-release-openstack-mitaka-1-3.el7)
openstack-manila-2.0.0-1.el7.noarch
openstack-manila-ui-2.1.0-1.el7.noarch
python-manila-2.0.0-1.el7.noarch
openstack-manila-share-2.0.0-1.el7.noarch
python-manilaclient-1.8.1-1.el7.noarch

## ZFS
zfs-release.el7.noarch.rpm
dkms-2.2.0.3-34.git.9e0394d.el7.noarch.rpm


# 評価項目
下記の機能を評価

* Create Share
* Delete Share
* Allow NFS Share access
* Deny NFS Share access
* Create Snapshot
* Delete Snapshot
* Create share from snapshot
* Extend Share
* Shrink Share


# 構成イメージ
今回、ZFSonLinux サーバは別建てしている。

![zfsonlinux-manila-image.jpg](https://qiita-image-store.s3.amazonaws.com/0/75458/e3588bcc-d4b5-17ce-af7a-1374d32240c4.jpeg)

# ファイルシェア（ここではファイルサーバ）が出来るまでの流れ

1. manila-api リクエスト
2. manila-scheduler スケジューリング
3. manila-share 処理
    1. 処理をする過程として、SSH経由でZFSonLinuxに接続する（パスワード、鍵認証）
    2. ZFSonLinux サーバ側はプールからボリュームを切り出す
    3. 切りだされたプールをエクスポートする
4. manila-share 完了

# 構築手順
前提として、OpenStack Manila の導入そのものは終わっているものとする。この部分については**参考**につけているページを参照。

## ZFS構成と設定
### ZFSの導入

* https://github.com/zfsonlinux/zfs/wiki/RHEL-%26-CentOS

```shell-session
# yum update
# yum groupinstall "Development tools"
# yum install epel-release
# yum localinstall --nogpgcheck http://archive.zfsonlinux.org/epel/zfs-release$(rpm -E %dist).noarch.rpm
# gpg --quiet --with-fingerprint /etc/pki/rpm-gpg/RPM-GPG-KEY-zfsonlinux
# yum install kernel-devel zfs
```
### ZPool 作成
このZFSonLinuxのサーバには10GBのHDDを外付けで**4つ**つけており、それを今回ZPoolとして割り当てる。RAIDとして**raidz3**を指定し、「**trank**」というプール名で作成。


```shell-session
# modrobe zfs
# cat /proc/filesystems |grep zfs
nodev   zfs

# zpool create trank raidz3 /dev/sdb /dev/sdc /dev/sdd /dev/sde -f 

# zpool status
  pool: trank
 state: ONLINE
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        trank       ONLINE       0     0     0
          raidz3-0  ONLINE       0     0     0
            sdb     ONLINE       0     0     0
            sdc     ONLINE       0     0     0
            sdd     ONLINE       0     0     0
            sde     ONLINE       0     0     0

errors: No known data errors

# zpool list
NAME    SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
trank  39.8G   256K  39.7G         -     0%     0%  1.00x  ONLINE  -

# LANG=C df -h
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   18G  1.8G   16G  10% /
devtmpfs                 911M     0  911M   0% /dev
tmpfs                    921M     0  921M   0% /dev/shm
tmpfs                    921M  8.6M  912M   1% /run
tmpfs                    921M     0  921M   0% /sys/fs/cgroup
trank                    9.7G     0  9.7G   0% /trank                  <= これ
/dev/sda1                497M  167M  331M  34% /boot
tmpfs                    185M     0  185M   0% /run/user/0
```

### NFS Server を起動
していなければ起動。

```shell-session
# systemctl start nfs-server
# systemctl enable nfs-server
```

### SSHユーザの作成
manila-share で処理されるためのアクセスユーザとして、「**zfsuser**」を作る。
>今回の環境では、OpenStack Manila 側では、manila-share が manila ユーザで動いているので、この manila ユーザが ssh を叩いて ZFSonLinux サーバに処理依頼。鍵を作って、秘密鍵を manila-share が稼働している所定の場所に配置する。（今回は、/etc/manila/nonpass.key 属性は 0440 とした）

また、zfsuser ユーザで ZFSの管理コマンドは実行できないので、sshでアクセス後は、sudo により ZFS 管理コマンドを実行する。ここでも sudo でノンパスで実行できるように設定をしてく。（visudo実行による）

```{file:/etc/sudoers}
%zfsuser        ALL=(ALL)       NOPASSWD: ALL
```

### manila create 時のエラーに対してのワークアラウンド
主にマニュアルに記載されてなかったり、試して気づいたところの回避策。

* **「sorry, you must have a tty to run sudo」**

ssh した後の sudo 実行を許可するためにするために「Defaults requiretty」はコメントアウト。

```{file:/etc/sudoers}
#Defaults    requiretty
```


* **ZFSonLinux で exportfs がないとエラーがでた処理**
/usr/local/bin , /usr/bin へ exportfs を探しにいっているようだったので、今回の環境ではシンボリックリンクで対応。

```shell-session
#  ln -s /usr/sbin/exportfs /usr/local/bin/exportfs
```

* **クライアントアクセスの許可（Allow IPアドレス）でエラーになる件**

エラーをドリルダウンしていくと、使っているZFSがFuse実装なのかkernelモジュール実装なのかで export する際にオプションを変える分岐があり、そこで使っている modinfo の呼び出し部分で「modinfo」が見つからないため失敗してる。単に modinfo 使うために **sudo** 忘れているだけ。
/usr/lib/python2.7/site-packages/manila/share/drivers/zfsonlinux/utils.py を修正

```shell-session
# pwd
/usr/lib/python2.7/site-packages/manila/share/drivers/zfsonlinux/utils.py

# diff back.utils.py utils.py
176c176,177
<                 self.execute('modinfo', 'zfs')
---
>                 self.execute('sudo','modinfo', 'zfs')
>                 #self.execute('modinfo', 'zfs')

# python -m compileall utils.py

# systemctl restart openstack-manila-share
```

## Manila構成と設定
### manila.conf 設定
設定の中心は「manila.conf」です。「ZFSをバックエンドで使う」ための情報を入れる。具体的にはセクションの追加と、有効化。


```{manila.conf}

enabled_share_backends = generic , zfs

[zfs]
share_driver = manila.share.drivers.zfsonlinux.driver.ZFSonLinuxShareDriver
driver_handles_share_servers = False
zfs_share_export_ip = 192.168.0.4
zfs_service_ip = 192.168.0.4
zfs_zpool_list = trank
zfs_share_helpers = NFS=manila.share.drivers.zfsonlinux.utils.NFSviaZFSHelper
zfs_use_ssh = True
zfs_ssh_username = zfsuser
#zfs_ssh_user_password = password
zfs_ssh_private_key_path = /etc/manila/nonpass.key
zfs_dataset_creation_options = dedup=off
share_backend_name = zfs
```

* ZFSonLinux サーバの宛先を指定
* 事前に作成したプール名を指定
* SSHのユーザ名を指定（今回は鍵を使ってノンパスアクセス）

オプションの詳細 [ZFSonLinux-Driver](http://docs.openstack.org/mitaka/config-reference/shared-file-systems/drivers/zfs-on-linux-driver.html)

設定が終わったら Manila サービスを再起動、manila service-list で確認。

```
# systemctl restart openstack-manila-api.service
# systemctl restart openstack-manila-scheduler.service
# systemctl restart openstack-manila-share.service

# manila service-list
+----+------------------+-------------------------+------+---------+-------+----------------------------+
| Id | Binary           | Host                    | Zone | Status  | State | Updated_at                 |
+----+------------------+-------------------------+------+---------+-------+----------------------------+
| 1  | manila-scheduler | akira.tk.net            | nova | enabled | up    | 2016-07-02T02:04:35.000000 |
| 2  | manila-share     | akira.tk.net@generic    | nova | enabled | up    | 2016-07-02T02:04:30.000000 |
| 3  | manila-share     | akira.tk.net@akira      | nova | enabled | down  | 2016-06-30T04:26:48.000000 |
| 4  | manila-share     | akira.tk.net@locallvm   | nova | enabled | up    | 2016-07-02T02:04:31.000000 |
| 5  | manila-share     | akira.tk.net@zfs        | nova | enabled | up    | 2016-07-02T02:04:31.000000 |
+----+------------------+-------------------------+------+---------+-------+----------------------------+


```

上記で言うと、エントリ「5」のところが追加したところであり、Status : enabled 、 State : up となっていればOK。


### タイプ設定

タイプとそれに紐づくバックエンドを設定する。

>ここは、Cinder の時とと同じように作る。

```shell-session
(admin) # manila type-create zfs False
(admin) # manila type-list
+--------------------------------------+--------------------+------------+------------+--------------------------------------+-------------------------+
| ID                                   | Name               | visibility | is_default | required_extra_specs                 | optional_extra_specs    |
+--------------------------------------+--------------------+------------+------------+--------------------------------------+-------------------------+
| 617d0932-7904-4229-ad5d-cf23df2cf2e1 | akira              | public     | -          | driver_handles_share_servers : False | snapshot_support : True |
| e0a86b9b-63ff-48a9-a689-d6f667ec5e94 | default_share_type | public     | -          | driver_handles_share_servers : True  | snapshot_support : True |
| ec19ec3e-de2e-464c-b5f7-354b1c0c8a03 | zfs                | public     | -          | driver_handles_share_servers : False | snapshot_support : True |
+--------------------------------------+--------------------+------------+------------+--------------------------------------+-------------------------+

(admin) # manila type-key zfs set share_backend_name=zfs 
(admin) # manila extra-specs-list
+--------------------------------------+--------------------+--------------------------------------+
| ID                                   | Name               | all_extra_specs                      |
+--------------------------------------+--------------------+--------------------------------------+
| 617d0932-7904-4229-ad5d-cf23df2cf2e1 | akira              | snapshot_support : True              |
|                                      |                    | share_backend_name : locallvm        |
|                                      |                    | driver_handles_share_servers : False |
| e0a86b9b-63ff-48a9-a689-d6f667ec5e94 | default_share_type | snapshot_support : True              |
|                                      |                    | driver_handles_share_servers : True  |
| ec19ec3e-de2e-464c-b5f7-354b1c0c8a03 | zfs                | snapshot_support : True              |
|                                      |                    | share_backend_name : zfs             |
|                                      |                    | driver_handles_share_servers : False |
+--------------------------------------+--------------------+--------------------------------------+

```

# シェアの作成（ファイルサーバ）

タイプとして、NFSシェアを試みる。

```shell-session
(demo) # manila create NFS 5 --name zfsvol --share-type zfs
+-----------------------------+--------------------------------------+
| Property                    | Value                                |
+-----------------------------+--------------------------------------+
| status                      | creating                             |
| share_type_name             | zfs                                  |
| description                 | None                                 |
| availability_zone           | None                                 |
| share_network_id            | None                                 |
| host                        |                                      |
| access_rules_status         | active                               |
| snapshot_id                 | None                                 |
| is_public                   | False                                |
| task_state                  | None                                 |
| snapshot_support            | True                                 |
| id                          | 77309678-c7b8-45d0-83c1-a6f7b4b545d8 |
| size                        | 5                                    |
| name                        | zfsvol                               |
| share_type                  | ec19ec3e-de2e-464c-b5f7-354b1c0c8a03 |
| has_replicas                | False                                |
| replication_type            | None                                 |
| created_at                  | 2016-09-11T05:01:18.000000           |
| share_proto                 | NFS                                  |
| consistency_group_id        | None                                 |
| source_cgsnapshot_member_id | None                                 |
| project_id                  | 7116ec60ce72461fa4a12f567a8eb4eb     |
| metadata                    | {}                                   |
+-----------------------------+--------------------------------------+
(demo) # manila list
+--------------------------------------+--------+------+-------------+----------+-----------+-----------------+------------------------+-------------------+
| ID                                   | Name   | Size | Share Proto | Status   | Is Public | Share Type Name | Host                   | Availability Zone |
+--------------------------------------+--------+------+-------------+----------+-----------+-----------------+------------------------+-------------------+
| 77309678-c7b8-45d0-83c1-a6f7b4b545d8 | zfsvol | 5    | NFS         | creating | False     | zfs             | akira.tk.net@zfs#trank | nova              |
+--------------------------------------+--------+------+-------------+----------+-----------+-----------------+------------------------+-------------------+
(demo) # manila list
+--------------------------------------+--------+------+-------------+-----------+-----------+-----------------+------------------------+-------------------+
| ID                                   | Name   | Size | Share Proto | Status    | Is Public | Share Type Name | Host                   | Availability Zone |
+--------------------------------------+--------+------+-------------+-----------+-----------+-----------------+------------------------+-------------------+
| 77309678-c7b8-45d0-83c1-a6f7b4b545d8 | zfsvol | 5    | NFS         | available | False     | zfs             | akira.tk.net@zfs#trank | nova              |
+--------------------------------------+--------+------+-------------+-----------+-----------+-----------------+------------------------+-------------------+

```

ZFSonLinux 側はどうかというと、以下のようにプールからボリュームが切りだされている。

```shell-session
(ZFSonLinux) # zfs list
NAME                                                      USED  AVAIL  REFER  MOUNTPOINT
trank                                                     239K  9.63G    19K  /trank
trank/manila_share_bff9e10d_37e4_4d33_ab5d_b8d7baaae4d1    19K  5.00G    19K  /trank/manila_share_bff9e10d_37e4_4d33_ab5d_b8d7baaae4d1

(ZFSonLinux) # df -k
ファイルシス                                            1K-ブロック    使用   使用可 使用% マウント位置
/dev/mapper/centos-root                                    18307072 1796672 16510400   10% /
devtmpfs                                                     932192       0   932192    0% /dev
tmpfs                                                        942252       0   942252    0% /dev/shm
tmpfs                                                        942252    8780   933472    1% /run
tmpfs                                                        942252       0   942252    0% /sys/fs/cgroup
trank                                                      10094336       0 10094336    0% /trank
/dev/sda1                                                    508588  169996   338592   34% /boot
tmpfs                                                        188452       0   188452    0% /run/user/0
tmpfs                                                        188452       0   188452    0% /run/user/1000
trank/manila_share_bff9e10d_37e4_4d33_ab5d_b8d7baaae4d1     5242880     128  5242752    1% /trank/manila_share_bff9e10d_37e4_4d33_ab5d_b8d7baaae4d1

```

これだけだと、NFSクライアントは繋げられないので、許可設定をする。

```shell-session

(demo) # manila access-allow zfsvol ip 192.168.0.154
+--------------+--------------------------------------+
| Property     | Value                                |
+--------------+--------------------------------------+
| share_id     | 77309678-c7b8-45d0-83c1-a6f7b4b545d8 |
| access_type  | ip                                   |
| access_to    | 192.168.0.154                        |
| access_level | rw                                   |
| state        | new                                  |
| id           | c59bf658-8bc2-4b4a-ad91-c9c5bd1d47ee |
+--------------+--------------------------------------+

(demo) # manila access-list zfsvol
+--------------------------------------+-------------+---------------+--------------+--------+
| id                                   | access_type | access_to     | access_level | state  |
+--------------------------------------+-------------+---------------+--------------+--------+
| c59bf658-8bc2-4b4a-ad91-c9c5bd1d47ee | ip          | 192.168.0.154 | rw           | active |
+--------------------------------------+-------------+---------------+--------------+--------+
```

すると ZFSonLinux では、以下のようにエクスポートされている。

```shell-session
(ZFSonLinux) # exportfs
/trank/manila_share_bff9e10d_37e4_4d33_ab5d_b8d7baaae4d1
                192.168.0.154
```

実際にNFSマウントしてみる。

マウントポイントを改めて確認。

```shell-session
(demo) # manila share-export-location-list zfsvol
+--------------------------------------+----------------------------------------------------------------------+-----------+
| ID                                   | Path                                                                 | Preferred |
+--------------------------------------+----------------------------------------------------------------------+-----------+
| 12ad1380-fff4-4bb0-aa4a-455550a4fa52 | 192.168.0.4:/trank/manila_share_bff9e10d_37e4_4d33_ab5d_b8d7baaae4d1 | False     |
+--------------------------------------+----------------------------------------------------------------------+-----------+
```

クライアントからマウント。

```shell-session
(Client) # mount 192.168.0.4:/trank/manila_share_bff9e10d_37e4_4d33_ab5d_b8d7baaae4d1 /mnt
(Client) # df -h
Filesystem                                                            Size  Used Avail Use% Mounted on
/dev/vda1                                                              40G  6.2G   34G  16% /
devtmpfs                                                              1.9G     0  1.9G   0% /dev
tmpfs                                                                 1.9G     0  1.9G   0% /dev/shm
tmpfs                                                                 1.9G   17M  1.9G   1% /run
tmpfs                                                                 1.9G     0  1.9G   0% /sys/fs/cgroup
tmpfs                                                                 380M     0  380M   0% /run/user/1000
192.168.0.4:/trank/manila_share_bff9e10d_37e4_4d33_ab5d_b8d7baaae4d1  5.0G     0  5.0G   0% /mnt

(Client) # echo "Hellow World" >> /mnt/testfile

(Client) # more /mnt/testfile
Hellow World
```

# シェアの削除

クライアントからアンマウントしておく。

```shell-session
(demo) # manila delete zfsvol

(demo) # manila list
+----+------+------+-------------+--------+-----------+-----------------+------+-------------------+
| ID | Name | Size | Share Proto | Status | Is Public | Share Type Name | Host | Availability Zone |
+----+------+------+-------------+--------+-----------+-----------------+------+-------------------+
+----+------+------+-------------+--------+-----------+-----------------+------+-------------------+
```

ZFSonLinux 側も削除される。

```shell-session
(ZFSonLinux) # zfs list
NAME    USED  AVAIL  REFER  MOUNTPOINT
trank   223K  9.63G    19K  /trank

(ZFSonLinux) # exportfs
(ZFSonLinux) #
```

# 参考

* [ZFSonLinux](http://zfsonlinux.org/)
* [OpenStack Days](http://openstackdays.com/) 講演資料アリ
* [Manila share features support mapping](http://docs.openstack.org/developer/manila/devref/share_back_ends_feature_support_mapping.html)
* [Manila を RDO で試してみる（準備編）](http://qiita.com/tksarah/items/dca0ee806779540a90c6)