###更新履歴
2014/10/11 cephx auth無効化しないでmap imageできたので、修正しました
Docker環境ではDBファイル等を保存する永続データストアは、各ホストのローカルストレージに置いてしまうとコンテナがホストを移動できなくなってしまうので、外部共有ストレージを使う必要があります。AWS/GCP等のパブリッククラウドでは、目的に応じてストレージサービスを選べばいい訳ですが、ローカル環境では耐障害性を考慮した外部共有ストレージを用意する必要があります。
高価なNAS/SANストレージにかわる共有ストレージとして注目されている、CephをCoreOS上のDockerコンテナからマウントできるか試してみました。
Cephを使用する方法として、オブジェクトストレージ(AWS S3/Openstack SWIFT互換 REST API)、POSIXファイルシステム、ブロックデバイスの3通りの方法が可能です。
一番簡単なのは、Ceph-FUSEを使ってPOSIXファイルシステムとして直接マウントする方法ですが、CoreOSでは423.0.0からCephブロックデバイスカーネルモジュールが追加されたので、実際にコンテナからマウントできるか試してみました。
##構築環境
CoreOSは、現在stableチャネルは410.2.0のため、betaチャネルを使用します。
$ cat /etc/os-release
NAME=CoreOS
ID=coreos
VERSION=444.3.0
VERSION_ID=444.3.0
BUILD_ID=
PRETTY_NAME="CoreOS 444.3.0"
ANSI_COLOR="1;32"
HOME_URL="https://coreos.com/"
BUG_REPORT_URL="https://github.com/coreos/bugs/issues"
念のためceph-rbdのカーネルモジュールがあるか確認します。
$ find /lib/ -type f | egrep 'ceph|rbd'
/lib/modules/3.16.2+/kernel/net/ceph/libceph.ko
/lib/modules/3.16.2+/kernel/drivers/block/rbd.ko
Cephは、CoreOSクラスタとは別に構築したCephクラスタ(Firefly)を使用します。
# ceph -v
ceph version 0.80.5
##クライアント環境の作成
まずCoreOS上に/etc/cephディレクトリを作成し、Cephに接続するための構成ファイルとキーファイルをCephクラスタからコピーします。
$ sudo mkdir /etc/ceph
$ sudo scp root@<cephノードアドレス>:/etc/ceph/ceph.conf root@<cephノードアドレス>:/etc/ceph/ceph.client.<cephユーザ>.keyring /etc/ceph/
$ sudo mkdir /mnt/ceph
Cephマウント用として/mnt/cephデイレクトリも作成しておき、コンテナ実行時に/etc/cephと/mnt/cephを-vオプションでコンテナにマウントします。
CoreOS自身にはなにもインストールできないので、Cephのクライアント(ceph-common)はコンテナにインストールする必要があります。コンテナはCephを標準でサポートしているUbuntu14.04で作成します。
注:ここでは予め作成しておいたsshサーバがインストールされて、rootログインできるコンテナを使っています。いきなり下記コマンドでコンテナ作成してもsshログインできません。
コンテナは、--privilegedモードで実行しないとエラーになります。
$ docker run --privileged -v /etc/ceph:/etc/ceph -v /mnt/ceph:/mnt/ceph -d -p 1022:22 ossl/ubuntu /usr/sbin/sshd -D
コンテナが起動されたことを確認して、sshログインします。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
974c0461a790 ossl/ubuntu1:0.1 "/usr/sbin/sshd -D" 15 hours ago Up 15 hours 0.0.0.0:1022->22/tcp distracted_brown
$ ssh -p 1022 root@<coreosホストアドレス>
Cephのクライアント(ceph-common)をインストールし、Cephへの接続確認をします。
root@974c0461a790:~# apt-get install ceph-common
root@974c0461a790:~# ceph -s
cluster d3270e97-4b31-4c7b-9ca7-08d0672889c9
health HEALTH_OK
monmap e2: 3 mons at {EXFS1=192.168.0.1:6789/0,EXFS2=192.168.0.2:6789/0,EXFS3=192.168.0.3:6789/0}, election epoch 66, quorum 0,1,2 EXFS1,EXFS2,EXFS3
mdsmap e120: 1/1/1 up {0=EXFS2=up:active}, 2 up:standby
osdmap e244: 3 osds: 3 up, 3 in
pgmap v11119: 296 pgs, 16 pools, 10332 kB data, 108 objects
41007 MB used, 610 GB / 685 GB avail
296 active+clean
上記のようにCephクラスタの状態が表示されればOKですので、あとはコンテナからCephのRBDコマンドを使ってプールとイメージを作成します。
# pool作成
root@974c0461a790:~# rados mkpool test-pool
root@974c0461a790:~# rados lspools
# image作成
# - sizeの単位はMB
root@974c0461a790:~# rbd --pool test-pool create --size 1024 test-image
root@974c0461a790:~# rbd --pool test-pool ls -l
次にローカルデバイスにmapすれば良いのですが、残念ながら現行バージョンでは rbd map コマンドにバグがあり使えません。
上記バグを回避するには、Cephクラスタの認証を無効にします。クライアントとクラスタ全ノードのceph.confファイルの[global]セクションを下記のように変更し、再起動します。
※Ceph公式ドキュメントにあるように、本番環境で認証を無効化することはお勧めできません。
次にCoreOS上でkernel object operationを実行します。
$ sudo modprobe rbd
$ echo "{mon-ip-address} name={user-name},secret={keyringファイル内のkey = 以降の文字列} {pool-name} {image-name}" | sudo tee /sys/bus/rbd/add
例
echo "192.168.100.1,192.168.100.2,192.168.100.3 name=admin,secret=XQDPptNTKBAOBRAA2+OX4mz1Bw+YeEhBdd4xOg== test-pool test-image"|sudo tee /sys/bus/rbd/add
再度コンテナを起動しsshログイン後、mapを確認します。
root@974c0461a790:~# rbd showmapped
id pool image snap device
0 test-pool test-image - /dev/rbd0
確認後、フォーマットしマウントします。
root@974c0461a790:~# mkfs.btrfs /dev/rbd0
root@974c0461a790:~# mount /dev/rbd0 /mnt/ceph
root@974c0461a790:~# df -Th
Filesystem Type Size Used Avail Use% Mounted on
/dev/vda9 btrfs 7.4G 1.8G 5.4G 25% /
tmpfs tmpfs 500M 0 500M 0% /dev
shm tmpfs 64M 0 64M 0% /dev/shm
/dev/vda9 btrfs 7.4G 1.8G 5.4G 25% /etc/ceph
/dev/rbd0 btrfs 1.0G 256K 894M 1% /mnt/ceph
これで書き込める状態になりました。
とりあえず、きょうはここまで。