Mirantis OpenStack (Neutron GRE)を組んでみた!

こんにちは。@jedipunkz です。

皆さん、Mirantis OpenStack はご存知ですか? OpenStack ディストリビューションの 1つです。以下、公式サイトです。

http://software.mirantis.com/main/

この Mirantis OpenStack を使って OpenStack Havana (Neutron GRE) 構成を作ってみ ました。その時のメモを書いていきたいと思います。

構成は?

構成は下記の通り。

※ CreativeCommon

特徴は

  • Administrative Network : Fuel Node, DHCP + PXE ブート用
  • Management Network : 各コンポーネント間 API 用
  • Public/Floating IP Network : パブリック API, VM Floating IP 用
  • Storage Network : Cinder 配下ストレージ <-> インスタンス間用
  • 要インターネット接続 : Public/Floating Networks
  • Neutron(GRE) 構成

です。タグ VLAN 使って物理ネットワークの本数を減らすことも出来るはずですが、僕 の環境では何故かダメだったので上記の4つの物理ネットワークを別々に用意しました。

Fuel ノードの構築

Fuel ノードとは、OpenStack の各ノードをデプロイするための管理ノードのことです。 DHCP + PXE を管理する Cobbler やデプロイツールの Puppet が内部で稼働し、 Administrative Network 上で稼働したノードを管理・その後デプロイします。

構築方法は…

下記の URL より ISO ファイルをダウンロード。

http://software.mirantis.com/main/

Administrative Network に NIC を出したノードを上記の ISO から起動。

Grub メニューが表示されたタイミングで “Tab” キーを押下。

上記画面にてカーネルオプションにて hostname, ip, gw, dns を修正。下記は例。

vmlinuz initrd=initrd.img biosdevname=0 ks=cdrom:/ks.cfg ip=10.200.10.76
gw=10.200.10.1 dns1=8.8.8.8 netmask=255.255.255.0 hostname=fuel.cpi.ad.jp
showmenu=no_

ブラウザで http://10.200.10.76:8080 (上記例)にアクセスし、新しい ‘OpenStack Environment’ を作成する。

Name : 任意
OpenStack Release : Havana on CentOS6.4

なお、Ubuntu 構成も組めるが、私の環境では途中でエラーが出力した。

Next を押下し、ネットワーク設定を行う。今回は ‘Nuetron GRE’ を選択。

‘Save Settings’ を押下し設定を保存。この時点では ‘Verify Networks’ は行えない。 少なくとも 2 ノードが必要。次のステップで2ノードの追加を行う。

ノードの追加

下記の4つのネットワークセグメントに NIC を出したノードを用意し、起動する。起動 すると Administrative Network 上で稼働している Cobbler によりノードが PXE 起動 しミニマムな OS がインストールされる。これは後に Fuel ノードよりログインがされ、 各インターフェースの Mac アドレス等の情報を知るためです。ネットワークベリファ イ等もこのミニマムな OS 越しに実施されます。

  • Administrative Network
  • Public/Floating IP Network
  • Storage Network
  • Management Network

ノードが稼働した時点で Fuel によりノードが認識されるので、ここでは2つのノード をそれぞれ

  • Controller ノード
  • Compute ノード

として画面上で割り当てます。

インターフェースの設定

http://10.200.10.76:8000/#cluster/1/nodes にログインし作成した Environment を選択。その後、’Nodes’ タブを押下。ノードを選択し、’Configure Interfaces’ を 選択。各ノードのインターフェースの Mac アドレスを確認し、各々のネットワークセ グメントを紐付ける。尚、Fuel ノードから ‘root’ ユーザで SSH(22番ポート) にノン パスフレーズで公開鍵認証ログインが可能となっている。Fuel ノードに対しては SSH (22番ポート) にて下記のユーザにてログインが可能です。

username : root
password : r00tme

ネットワークの確認

http://10.200.10.76:8000/#cluster/1/network にて ‘Networks’ タブを開き、’Verify Networks’ を押下。ネットワーク設定が正しく行われているか否かを確認。

デプロイ

http://10.200.10.76:8000/#cluster/1/nodes にて ‘Deploy Changes’ を押下しデプ ロイ開始。kickstart にて OS が自動でインストールされ puppet にて fuel ノードか ら自動で OpenStack がインストールされます。

OpenStack へのアクセス

SSH では下記のステップで OpenStack コントローラノードにログイン。

fuel ノード (SSH) -> node-1 (OpenStack コントローラノード)(SSH)

ブラウザで Horizon にアクセスするには

http://10.200.10.2

にアクセス。これは例。Administrative Network に接続している NIC の IP アドレス へ HTTP でログイン。

まとめ

Mirantis OpenStack Neutron (GRE) 構成が組めた。上記構成図を見て疑問に思ってい た “VM 間通信のネットワークセグメント” であるが、Administrative Network のセグ メントを用いている事が判った。これは利用者が意図しているとは考えづらいので、正 直、あるべき姿では無いように思える。が、上記構成図に VM ネットワークが無い理由 はこれにて判った。

下記はノード上で ovs-vsctl show コマンドを打った結果の抜粋です。

    Bridge "br-eth1"
        Port "br-eth1"
            Interface "br-eth1"
                type: internal
        Port "br-eth1--br-fw-admin"
            trunks: [0]
            Interface "br-eth1--br-fw-admin"
                type: patch
                options: {peer="br-fw-admin--br-eth1"}
        Port "eth1"
            Interface "eth1"

今回の構成は eth1 は Administrative Network に割り当てていました。

一昔前は OS のディストリビュータが有料サポートをビジネスにしていました。Redhat がその代表格だと思いますが、今は OS 上で何かを実現するにもソフトウェアの完成度 が高く、エンジニアが困るシチュエーションがそれほど無くなった気がします。そこで その OS の上で稼働する OpenStack のサポートビジネスが出てきたか!という印象で す。OpenStack はまだまだエンジニアにとって敷居の高いソフトウェアです。自らクラ ウドプラットフォームを構築出来るのは魅力的ですが、サポート無しに構築・運用する には、まだ難しい技術かもしれません。こういったディストリビューションが出てくる 辺りが時代だなぁと感じます。

尚、ISO をダウンロードして利用するだけでしたら無償で OK です。

Geard のポートマッピングについて調べてみた

こんにちは。@jedipunkz です。

今週 Redhat が ‘Redhat Enterprise Linux Atomic Host’ しましたよね。Docker を特 徴としたミニマムな OS だとのこと。その内部で用いられている技術 Geard について 少し調べてみました。複数コンテナの関連付けが可能なようです。ここでは調べた結果 について簡単にまとめていきます。

参考資料

http://openshift.github.io/geard/deploy_with_geard.html

利用方法

ここではホスト OS に Fedora20 を用意します。

まず Geard をインストール

% sudo yum install --enablerepo=updates-testing geard

下記の json ファイルを作成します。ここにはコンテナをデプロイするための情報と関 連付けのための情報を記します。

$ ${EDITOR} rockmongo_mongodb.json
{
  "containers":[
    {
      "name":"rockmongo",
      "count":1,
      "image":"derekwaynecarr/rockmongo",
      "publicports":[{"internal":80,"external":6060}],
      "links":[{"to":"mongodb"}]
    },
    {
      "name":"mongodb",
      "count":1,
      "image":"ccoleman/ubuntu-mongodb",
      "publicports":[{"internal":27017}]
    }
  ]
}

上記のファイルの解説。

  • コンテナ ‘rockmongo’ と ‘mongodb’ を作成
  • それぞれ1個ずつコンテナを作成
  • ‘image’ パラメータにて docker イメージの指定
  • ‘publicports’ パラメータにてコンテナ内部とホスト側のポートマッピングを行う
  • ‘links’ パラメータで ‘rockmongo’ を ‘mongodb’ に関連付け

では、デプロイ開始します。

$ sudo gear deploy rockmongo_mongo.json
2014/04/22 07:21:12 Deploying rockmongo_mongo.json.20140422-072112
2014/04/22 07:21:12 appending 27017 on rockmongo-1: &{PortPair:{Internal:27017 External:0} Target:127.0.0.1:27017} &{Id:rockmongo-1 Image:derekwaynecarr/rockmongo From:rockmongo On:0xc2100bb980 Ports:[{PortPair:{Internal:80 External:6060} Target::0}] add:true remove:false container:0xc21000be00 links:[]}
2014/04/22 07:21:12 ports: Releasing
2014/04/22 07:21:12 systemd: Reloading daemon
local PortMapping: 80 -> 6060
local Container rockmongo-1 is installed
2014/04/22 07:21:12 ports: Releasing
2014/04/22 07:21:12 systemd: Reloading daemon
local PortMapping: 27017 -> 4000
local Container mongodb-1 is installed
linking rockmongo: 127.0.0.1:27017 -> localhost:4000
local Links set on local
local Container rockmongo-1 starting
local Container mongodb-1 starting

ブラウザにてホスト OS に接続することで rockmongo の管理画面にアクセスが可能。

http://<ホストOSのIP:6060>/

ポートマッピング管理

デプロイが完了して、実際に RockMongo の管理画面にアクセス出来たと思います。 関連付けが特徴と言えそうなのでその解析をしてみました。

Geard のコンテナ関連付けはホストとコンテナのポート管理がキモとなっていることが 解ります。これを紐解くことで geard のコンテナ管理を理解します。

                        'rockmongo' コンテナ             'mongodb' コンテナ
+----------+        +--------------------------+        +-------------------+
|  Client  |->6060->|->80-> RockMongo ->27017->|->4000->|->27017-> Mongodb  |
+----------+        +--------------------------+        +-------------------+
                    |-------------------- docker ホスト --------------------|

上記 ‘gear deploy’ コマンド発行時のログと json ファイルにより上図のような構成 になっていることが理解できます。一つずつ読み解いていきましょう。

  • ‘rockmongo’ コンテナの内部でリスンしている 80 番ポートはホスト OS の 6060 番へ変換
  • ‘rockmongo’ コンテナ内で稼働する RockMongo の config.php から ‘127.0.0.1:27017’ でリスンしていることが解る

試しに ‘derekwaynecarr/rockmongo:latest’ に /bin/bash でログインし config.php を確認。

$ sudo docker run -i -t derekwaynecarr/rockmongo:latest /bin/bash
bash-4.1# grep mongo_host /var/www/html/config.php
$MONGO["servers"][$i]["mongo_host"] = "127.0.0.1";//mongo host
$MONGO["servers"][$i]["mongo_host"] = "127.0.0.1";
  • デプロイ時のログと json ファイルの ‘links’ パラメータより、ホストのポートに動的に(ここでは 4000番ポート) に変換されることが解ります。

    linking rockmongo: 127.0.0.1:27017 -> localhost:4000

  • ホストの 4000 番ポートは動的に ‘mongodb’ コンテナの内部ポート 27017 にマッピングされる

これらのポートマッピングによりそれぞれのコンテナの連携が取れている。

まとめと考察

Geard は下記の2つを特徴とした技術だと言えるとことがわかりました。

  • コンテナを json で管理しデプロイする仕組みを提供する
  • コンテナ間の関連付けをホスト OS のポートを動的に管理・マッピングすることで行う

同じような OS に CoreOS https://coreos.com/ がありますが、こちらも docker, sytemd 等を特徴としています。さらに etcd を使ってクラスタの構成等が可能になっ ていますが、Geard はホストのポートを動的に管理することで関連付けが可能なことが わかりました。

実際に触ってみた感覚から言えば、まだまだ実用化は厳しい状況に思えますが、今後へ の展開に期待したい技術です。

OpenStack Havana Cinder,Glance の分散ストレージ Ceph 連携

こんにちは!@jedipunkz です。

今回は Havana 版の OpenStack Glance, Cinder と分散ストレージの Ceph を連携させ る手順を書いていきます。元ネタはこちら。下記の Ceph の公式サイトに手順です。

https://ceph.com/docs/master/rbd/rbd-openstack/

この手順から下記の変更を行って、ここでは記していきます。

  • Nova + Ceph 連携させない
  • cinder-backup は今のところ動作確認出来ていないので省く
  • 諸々の手順がそのままでは実施出来ないので補足を入れていく。

cinder-backup は Cinder で作成した仮想ディスクのバックアップを Ceph ストレージ 上に取ることが出来るのですが、そもそも Ceph 上にある仮想ディスクを Ceph にバッ クアップ取っても意味が薄いですし、まだ動いていないので今回は省きます。LVM やそ の他ストレージを使った Cinder 連携をされている方にとっては cinder-backup の Ceph 連携は意味が大きくなってくると思います。

構成

下記の通りの物理ネットワーク6つの構成です。 OpenStack, Ceph 共に最小構成を前提にします。

                  +--------------------------------------------------------------------- external
                  |
+--------------+--(-----------+--------------+------------------------------------------ public
|              |  |           |              |
+------------+ +------------+ +------------+ +------------+ +------------+ +------------+
| controller | |  network   | |  compute   | |   ceph01   | |   ceph02   | |   ceph03   |
+------------+ +------------+ +------------+ +------------+ +------------+ +------------+
|  |           |  |           |  |  |        |  |  |        |  |  |        |  |  |
+--------------+--(-----------+--(-----------+--(--(--------+--(--(--------+--(--(------- management
   |              |              |  |           |  |           |  |           |  |
   |              +--------------+--(-----------(--(-----------(--(-----------(--(------- guest
   |                                |           |  |           |  |           |  |
   +--------------------------------+-----------+--(-----------+--(-----------+--(------- storage
                                                   |              |              |
                                                   +--------------+--------------+------- cluster

特徴

  • 最小構成 controller x 1 + network x 1 + compute x 1 + ceph x 3
  • OpenStack API の相互通信は management ネットワーク
  • OpenStack VM 間通信は guest ネットワーク
  • OpenStack 外部通信は public ネットワーク
  • OpenStack VM の floating-ip (グローバル) 通信は external ネットワーク
  • Ceph と OpenStack 間の通信は storage ネットワーク
  • Ceph の OSD 間通信は cluster ネットワーク
  • ここには記されていないホスト ‘workstation’ から OpenStack, Ceph をデプロイ

前提の構成

前提構成の OpenStack と Ceph ですが、ここでは構築方法は割愛します。OpenStack は rcbops/chef-cookbooks を。Ceph は ceph-deploy を使って自分は構築しました。 下記の自分のブログに構築手順が載っているので参考にしてみてください。

OpenStack 構築方法

http://jedipunkz.github.io/blog/2013/11/17/openstack-havana-chef-deploy/

Ceph 構築方法

http://jedipunkz.github.io/blog/2014/02/27/journal-ssd-ceph-deploy/

OpenStack + Ceph 連携手順

では実際に連携するための手順を記していきます。

rbd pool の作成

Ceph ノードの何れかで下記の手順を実施し rbd pool を作成する。

ceph01% sudo ceph osd pool create volumes 128
ceph01% sudo ceph osd pool create images 128
ceph01% sudo ceph osd pool create backups 128

ssh 鍵の配置

Ceph ノードから OpenStack の controller, compute ノードへ接続出来るよう鍵を配 布します。

ceph01% ssh-copy-id <username>@<controller_ip>
ceph01% ssh-copy-id <username>@<compute_ip>

sudoers の設定

controller, compute ノード上で sudoers の設定を予め実施する。 /etc/sudoers.d/ として保存する。

<username> ALL = (root) NOPASSWD:ALL

ceph パッケージのインストール

controller ノード, compute ノード上で Ceph パッケージをインストールする。

controller% wget -q -O- 'https://ceph.com/git/?p=ceph.git;a=blob_plain;f=keys/release.asc' | sudo apt-key add -
controller% echo deb http://ceph.com/debian/ $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/ceph.list
controller% sudo apt-get update && sudo apt-get install -y python-ceph ceph-common

compute% wget -q -O- 'https://ceph.com/git/?p=ceph.git;a=blob_plain;f=keys/release.asc' | sudo apt-key add -
compute% echo deb http://ceph.com/debian/ $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/ceph.list
compute% sudo apt-get update && sudo apt-get install -y python-ceph ceph-common

controller ノード, compute ノード上でディレクトリを作成する。

controller% sudo mkdir /etc/ceph
compute   % sudo mkdir /etc/ceph

ceph.conf を controller, compute ノードへ配布する。

ceph01% sudo -i
ceph01# ssh <controller_ip> sudo tee /etc/ceph/ceph.conf </etc/ceph/ceph.conf
ceph01# ssh <compute_ip> sudo tee /etc/ceph/ceph.conf </etc/ceph/ceph.conf

ceph 上にユーザを作成

Ceph 上に cinder, glance 用の新しいユーザを作成する。

ceph auth get-or-create client.cinder mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=volumes, allow rx pool=images'
ceph auth get-or-create client.glance mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=images'
ceph auth get-or-create client.cinder-backup mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=backups'

キーリングの作成と配置

client.cinder, client.glance, client.cinder-backup のキーリングを作成する。また作成したキーリングを controller ノードに配布する。

ceph01% sudo ceph auth get-or-create client.glance | ssh {your-glance-api-server} sudo tee /etc/ceph/ceph.client.glance.keyring
ceph01% ssh {your-glance-api-server} sudo chown glance:glance /etc/ceph/ceph.client.glance.keyring
ceph01% sudo ceph auth get-or-create client.cinder | ssh {your-volume-server} sudo tee /etc/ceph/ceph.client.cinder.keyring
ceph01% ssh {your-cinder-volume-server} sudo chown cinder:cinder /etc/ceph/ceph.client.cinder.keyring
ceph01% sudo ceph auth get-or-create client.cinder-backup | ssh {your-cinder-backup-server} sudo tee /etc/ceph/ceph.client.cinder-backup.keyring
ceph01% ssh {your-cinder-backup-server} sudo chown cinder:cinder /etc/ceph/ceph.client.cinder-backup.keyring

client.cinder のキーリングを compute ノードに配置する。

ceph01% sudo ceph auth get-key client.cinder | ssh {your-compute-node} tee client.cinder.key

libvirt への secret キー追加

compute ノード上で secret キーを libvirt に追加する。

compute% uuidgen
457eb676-33da-42ec-9a8c-9293d545c337

cat > secret.xml <<EOF
<secret ephemeral='no' private='no'>
  <uuid>457eb676-33da-42ec-9a8c-9293d545c337</uuid>
  <usage type='ceph'>
    <name>client.cinder secret</name>
  </usage>
</secret>
EOF
compute % sudo virsh secret-define --file secret.xml
Secret 457eb676-33da-42ec-9a8c-9293d545c337 created
compute% sudo virsh secret-set-value --secret 457eb676-33da-42ec-9a8c-9293d545c337 --base64 $(cat client.cinder.key) && rm client.cinder.key secret.xml

glance 連携手順

controller ノードの /etc/glance/glance-api.conf に下記を追記。 default_store=file と標準ではなっているので下記の通り rbd に書き換える。

default_store=rbd
rbd_store_user=glance
rbd_store_pool=images

cinder 連携手順

controller ノードの /etc/cinder/cinder.conf に下記を追記。 volume_driver は予め LVM の設定が入っていると思われるので書き換える。 また rbd_secret_uuid は先ほど生成した uuid を記す。

volume_driver=cinder.volume.drivers.rbd.RBDDriver
rbd_pool=volumes
rbd_ceph_conf=/etc/ceph/ceph.conf
rbd_flatten_volume_from_snapshot=false
rbd_max_clone_depth=5
glance_api_version=2
rbd_user=cinder
rbd_secret_uuid=457eb676-33da-42ec-9a8c-9293d545c337

ceph.conf への追記

上記で配布した ceph.conf にはキーリングのパスが記されていない。controller ノー ド上の /etc/ceph/ceph.conf に下記の通り追記する。

ここは公式サイトには印されていないのでハマりました。ポイントです。

[client.keyring]
  keyring = /etc/ceph/ceph.client.cinder.keyring

OpenStack のそれぞれのコンポーネントを再起動かける

controller% sudo glance-control api restart
compute   % sudo service nova-compute restart
controller% sudo service cinder-volume restart
controller% sudo service cinder-backup restart

動作確認

では動作確認を。Glance に OS イメージを登録。その後そのイメージを元にインスタ ンスを作成。Cinder 上に仮想ディスクを作成。その後先ほど作成したインスタンスに 接続しマウント。そのマウントした仮想ディスク上で書き込みが行えるか確認をします。

テストで Ubuntu Precise 12.04 のイメージを glance を用いて登録する。

controller% wget http://cloud-images.ubuntu.com/precise/current/precise-server-cloudimg-amd64-disk1.img
controller% glance image-create --name precise-image --is-public true --container-format bare --disk-format qcow2 < precise-server-cloudimg-amd64-disk1.img

テスト VM を稼働する。

controller% nova boot --nic net-id=<net_id> --flavor 2 --image precise-image --key_name novakey01 vm01
controller% cinder create --display-name vol01 1
controller% nova volume-attach <instance_id> <volume_id> auto

テスト VM へログインしファイルシステムを作成後、マウントする。

controller% ssh -i <key_file_path> -l ubuntu <instance_ip>
vm01% sudo mkfs -t ext4 /dev/vdb
vm01% sudo mount -t ext4 /dev/vdb /mnt

マウントした仮想ディスク上でデータを書き込んでみる。

vm01% sudo dd if=/dev/zero of=/mnt/500M bs=1M count=5000

まとめ

Ceph, Cinder の Ceph 連携が出来ました!

OpenStack Grizzly 版時代に Ceph 連携は取っていたのですが Havana では

  • cinder-bacup の Ceph 連携
  • nova の Ceph 連携

が追加されていました。Nova 連携をとるとインスタンスを稼働させる際に通常は controller ノードの /var/lib/nova 配下にファイルとしてインスタンスイメージが作 成されますが、これが Ceph 上に作成されるとのことです。Nova 連携は是非とってみ たいのですが、今のところ動いていません。引き続き調査を行います。

cinder-backup も少し連携取ってみましたが backup_driver に Ceph ドライバの指定 をしているにも関わらず Swift に接続しにいってしまう有り様でした..。こちらも引 き続き調査します。またステートが ‘in-use’ の場合バックアップが取れず ‘available’ なステートでないといけないようです。確かに書き込み中に操作が行われ てしまってもバックアップの整合性が取れないですし、ここは仕方ないところですね。

Rcbops/chef-cookbooks で Keystone 2013.2.2(Havana) + Swift 1.10.0 を構築

こんにちは。@jedipunkz です。

追記

2014/03/20 : 一旦削除していた記事なのですが、無事動作が確認出来たので再度アッ プします!

第17回 OpenStack 勉強会で rcbops/chef-cookbooks の話をしてきたのですが会場から 質問がありました。「Havana の Swift 構成を作る Cookbooks はどこにありますか?」 と。私が試したのが Grizzly 時代のモノで、よく rcbops/chef-cookbooks を見てみる と Havana ブランチ又は Havana に対応したリリースタグのファイル構成に Swift が 綺麗サッパリ消えているではありませんか・・!下記の Swift の Cookbooks は幸い github 上に残っていました。

https://github.com/rcbops-cookbooks/swift

が rcbops/chef-cookbooks との関連付けが切れています・・。ぐあぁ。

ということで Havana 構成の Keystone 2013.2.2 と Swift 1.10.0 の構成を Chef で 作らねば!と思い色々試していたら結構あっさりと出来ました。今回はその方法を書い ていきたいと思います!

構成

構成は…以前の記事 http://jedipunkz.github.io/blog/2013/10/27/swift-chef/ と同じです。

+-----------------+
|  load balancer  |
+-----------------+
|
+-------------------+-------------------+-------------------+-------------------+---------------------- proxy network
|                   |                   |                   |                   |                   
+-----------------+ +-----------------+ +-----------------+ +-----------------+ +-----------------+
|   chef server   | | chef workstation| |   swift-mange   | |  swift-proxy01  | |  swift-proxy02  | 
+-----------------+ +-----------------+ +-----------------+ +-----------------+ +-----------------+ ...> scaling
|                   |                   |                   |                   |                   
+-------------------+-------------------+-------------------+-------------------+-------------------+-- storage network
|                   |                   |                   |                   |                   |
+-----------------+ +-----------------+ +-----------------+ +-----------------+ +-----------------+ +-----------------+ 
| swift-storage01 | | swift-storage02 | | swift-storage03 | | swift-account01 | | swift-account02 | | swift-account03 |
+-----------------+ +-----------------+ +-----------------+ +-----------------+ +-----------------+ +-----------------+ ..> scaling

手順

では早速手順を記していきますね。毎回なのですが Chef ワークステーション・Chef サーバの環境構築については割愛します。オムニバスインストーラを使えば Chef サー バの構築は簡単ですし、ワークステーションの構築も Ruby インストール -> gem で Chef をインストール -> .chef 配下を整える、で出来ます。

rcbops/chef-cookbooks の取得。現在 Stable バージョンの refs/tags/v4.2.1 を用いる。

% git clone https://github.com/rcbops/chef-cookbooks.git ./chef-cookbooks-4.2.1
% cd ./chef-cookbooks-4.2.1
% git checkout -b v4.2.1 refs/tags/v4.2.1
% git submodule init
% git submodule sync
% git submodule update

ここで本家 rcbops/chef-cookbooks と関連付けが消えている rcbops-cookbooks/swift を cookbooks ディレクトリ配下にクローンします。あと念のため ‘havana’ ブランチ を指定します。コードを確認したところ何も変化はありませんでしたが。

% git clone https://github.com/rcbops-cookbooks/swift.git cookbooks/swift
% cd cookbooks/swift
% git checkout -b havana remotes/origin/havana
% cd ../..

cookbooks, roles の Chef サーバへのアップロードを行います。

% knife cookbook upload -o cookbooks -a
% knife role from file role/*.rb

今回の構成 (1クラスタ) 用の environments/swift-havana.json を作成します。json ファイルの名前は任意です。

{
  "name": "swift-havana",
  "description": "",
  "cookbook_versions": {
  },
  "json_class": "Chef::Environment",
  "chef_type": "environment",
  "default_attributes": {
  },
  "override_attributes": {
    "package_component": "havana",
    "osops_networks": {
      "management": "10.200.9.0/24",
      "public": "10.200.10.0/24",
      "swift": "10.200.9.0/24"
    },
    "keystone": {
      "pki": {
        "enabled": false
      },
      "admin_port": "35357",
      "admin_token": "admin",
      "admin_user": "admin",
      "tenants": [
        "admin",
        "service"
      ],
      "users": {
        "admin": {
          "password": "secrete",
          "roles": {
            "admin": [
              "admin"
            ]
          }
        },
        "demo": {
          "password": "demo",
          "default_tenant" : "service",
          "roles": {
            "admin": [ "admin" ]
          }
        }
      },
      "db": {
        "password": "keystone"
      }
    },
    "mysql": {
      "root_network_acl": "%",
      "allow_remote_root": true,
      "server_root_password": "secrete",
      "server_repl_password": "secrete",
      "server_debian_password": "secrete"
    },
    "monitoring": {
      "procmon_provider": "monit",
      "metric_provider": "collectd"
    },
    "vips": {
      "keystone-admin-api": "10.200.9.11",
      "keystone-service-api": "10.200.9.11",
      "keystone-internal-api": "10.200.9.11",
      "swift-proxy": "10.200.9.11",
      "config": {
        "10.200.9.112": {
          "vrid": 12,
          "network": "management"
        }
      }
    },
    "developer_mode": false,
    "swift": {
      "swift_hash": "307c0568ea84",
      "authmode": "keystone",
      "authkey": "20281b71-ce89-4b27-a2ad-ad873d3f2760"
    }
  }
}

作成した environment ファイル environments/swift-havana.json を chef-server へアップ ロードする。

% knife environment from file environments/swift-havana.json

Cookbooks の修正

swift cookbooks を修正します。havana からは keystone を扱うクライアントは keystone.middleware.auth_token でなく keystoneclient.middleware.auth_token を 使うように変更掛かっていますので、下記のように修正しました。

% cd cookbooks/swift/templates/default
% diff -u proxy-server.conf.erb.org proxy-server.conf.erb
--- proxy-server.conf.erb.org   2014-03-20 16:28:28.000000000 +0900
+++ proxy-server.conf.erb       2014-03-20 16:28:13.000000000 +0900
@@ -243,7 +243,8 @@
 use = egg:swift#keystoneauth

 [filter:authtoken]
-paste.filter_factory = keystone.middleware.auth_token:filter_factory
+#paste.filter_factory = keystone.middleware.auth_token:filter_factory
+paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory
 auth_host = <%= @keystone_api_ipaddress %>
 auth_port = <%= @keystone_admin_port %>
 auth_protocol = <%= @keystone_admin_protocol %>
% cd ../../../..

デプロイ

かきのとおり knife bootstrap する。

% knife bootstrap <manage_ip_addr> -N swift-manage -r 'role[base]','role[mysql-master]','role[keystone]','role[swift-management-server]' -E swift-havana --sudo -x thirai
% knife bootstrap <proxy01_ip_addr> -N swift-proxy01 -r "role[base]","role[swift-proxy-server]",'role[swift-setup]','role[openstack-ha]' -E swift-havana --sudo -x thirai
% knife bootstrap <proxy02_ip_addr> -N swift-proxy02 -r "role[base]","role[swift-proxy-server]",'role[openstack-ha]' -E swift-havana --sudo -x thirai
% knife bootstrap <storage01_ip_addr> -N swift-storage01 -r 'role[base]','role[swift-object-server]' -E swift-havana --sudo -x thirai
% knife bootstrap <storage02_ip_addr> -N swift-storage02 -r 'role[base]','role[swift-object-server]' -E swift-havana --sudo -x thirai
% knife bootstrap <storage03_ip_addr> -N swift-storage03 -r 'role[base]','role[swift-object-server]' -E swift-havana --sudo -x thirai
% knife bootstrap <account01_ip_addr> -N swift-account01 -r 'role[base]','role[swift-account-server]','role[swift-container-server]' -E swift-havana --sudo -x thirai
% knife bootstrap <account02_ip_addr> -N swift-account02 -r 'role[base]','role[swift-account-server]','role[swift-container-server]' -E swift-havana --sudo -x thirai
% knife bootstrap <account03_ip_addr> -N swift-account03 -r 'role[base]','role[swift-account-server]','role[swift-container-server]' -E swift-havana --sudo -x thirai

ここでバグ対策。Swift 1.10.0 にはバグがあるので下記の通り対処します。

keystone.middleware.s3_token に既知のバグがあり、下記のように対処します。この 状態ではバグにより swift-proxy が稼働してない状態ですが後の各ノードでの chef-client 実行時に稼働する予定です。

% diff /usr/lib/python2.7/dist-packages/keystone/exception.py.org /usr/lib/python2.7/dist-packages/keystone/exception.py 
--- exception.py.org    2014-03-12 16:45:00.181420694 +0900
+++ exception.py        2014-03-12 16:44:47.173177081 +0900
@@ -18,6 +18,7 @@

 from keystone.common import config
 from keystone.openstack.common import log as logging
+from keystone.openstack.common.gettextutils import _
 from keystone.openstack.common import strutils

上記のバグ報告は下記の URL にあります。

https://bugs.launchpad.net/ubuntu/+source/swift/+bug/1231339

zone 番号を付与します。

% knife exec -E "nodes.find(:name => 'swift-storage01') {|n| n.set['swift']['zone'] = '1'; n.save }"
% knife exec -E "nodes.find(:name => 'swift-account01') {|n| n.set['swift']['zone'] = '1'; n.save }"
% knife exec -E "nodes.find(:name => 'swift-storage02') {|n| n.set['swift']['zone'] = '2'; n.save }"
% knife exec -E "nodes.find(:name => 'swift-account02') {|n| n.set['swift']['zone'] = '2'; n.save }"
% knife exec -E "nodes.find(:name => 'swift-storage03') {|n| n.set['swift']['zone'] = '3'; n.save }"
% knife exec -E "nodes.find(:name => 'swift-account03') {|n| n.set['swift']['zone'] = '3'; n.save }"

zone 番号が付与されたこと下記の通りを確認します

account-server の確認

% knife exec -E 'search(:node,"role:swift-account-server") \
  { |n| z=n[:swift][:zone]||"not defined"; puts "#{n.name} has the role \
  [swift-account-server] and is in swift zone #{z}"; }'
swift-account01 has the role       [swift-account-server] and is in swift zone 1
swift-account02 has the role       [swift-account-server] and is in swift zone 2
swift-account03 has the role       [swift-account-server] and is in swift zone 3

container-server の確認

% knife exec -E 'search(:node,"role:swift-container-server") \
  { |n| z=n[:swift][:zone]||"not defined"; puts "#{n.name} has the role \
  [swift-container-server] and is in swift zone #{z}"; }'
swift-account01 has the role       [swift-container-server] and is in swift zone 1
swift-account02 has the role       [swift-container-server] and is in swift zone 2
swift-account03 has the role       [swift-container-server] and is in swift zone 3

object-server の確認

% knife exec -E 'search(:node,"role:swift-object-server") \
  { |n| z=n[:swift][:zone]||"not defined"; puts "#{n.name} has the role \
  [swift-object-server] and is in swift zone #{z}"; }'
swift-storage01 has the role   [swift-object-server] and is in swift zone 1
swift-storage02 has the role   [swift-object-server] and is in swift zone 2
swift-storage03 has the role   [swift-object-server] and is in swift zone 3

Chef が各々のノードに搭載された Disk を検知出来るか否かを確認する。

% knife exec -E \
  'search(:node,"role:swift-object-server OR \
  role:swift-account-server \
  OR role:swift-container-server") \
  { |n| puts "#{n.name}"; \
  begin; n[:swift][:state][:devs].each do |d| \
  puts "\tdevice #{d[1]["device"]}"; \
  end; rescue; puts \
  "no candidate drives found"; end; }'
    swift-storage02
            device sdb1
    swift-storage03
            device sdb1
    swift-account01
            device sdb1
    swift-account02
            device sdb1
    swift-account03
            device sdb1
    swift-storage01
            device sdb1

swift-manage ノードにて chef-client を実行し /etc/swift/ring-workspace/generate-rings.sh を更新します。

swift-manage% sudo chef-client

generate-rings.sh の ‘exit 0’ 行をコメントアウトし実行します。

swift-manage% sudo ${EDITOR} /etc/swift/ring-workspace/generage-rings.sh
swift-manage% sudo /etc/swift/ring-workspace/generate-rings.sh

この操作で /etc/swift/ring-workspace/rings 配下に account, container, object 用の Rings ファイル群が生成されたことを確認出来るはずです。これらを swift-manage 上で既に稼働している git サーバに push し管理します。

swift-manage# cd /etc/swift/ring-workspace/rings
swift-manage# git add account.builder container.builder object.builder
swift-manage# git add account.ring.gz container.ring.gz object.ring.gz
swift-manage# git commit -m "initial commit"
swift-manage# git push

各々のノードにて chef-client を実行することで git サーバ上の Rings ファイル群 を取得し、swift プロセスを稼働させます。

swift-proxy01# chef-client
swift-proxy02# chef-client
swift-storage01# chef-client
swift-storage02# chef-client
swift-storage03# chef-client
swift-account01# chef-client
swift-account02# chef-client
swift-account03# chef-client

3台のノードが登録されたかどうかを下記の通り確認行います。

swift-proxy01% sudo swift-recon --md5
[sudo] password for thirai:
===============================================================================
--> Starting reconnaissance on 3 hosts
===============================================================================
[2013-10-18 11:14:43] Checking ring md5sums
3/3 hosts matched, 0 error[s] while checking hosts.
===============================================================================

動作確認

構築が出来ました!ということで動作の確認をしてみましょう。

テストコンテナ ‘container01’ にテストファイル ‘test’ をアップロードしてみる。

swift-storage01% swift -V 2 -A http://<ip_addr_keystone>:5000/v2.0/ -U admin:admin -K secrete stat
swift-storage01% swift -V 2 -A http://<ip_addr_keystone>:5000/v2.0/ -U admin:admin -K secrete post container01
swift-storage01% echo "test" > test
swift-storage01% swift -V 2 -A http://<ip_addr_keystone>:5000/v2.0/ -U admin:admin -K secrete upload container01 test
swift-storage01% swift -V 2 -A http://<ip_addr_keystone>:5000/v2.0/ -U admin:admin -K secrete list
container01
swift-storage01% swift -V 2 -A http://<ip_addr_keystone>:5000/v2.0/ -U admin:admin -K secrete list container01 test

まとめ

前回「実用的な Swift 構成を Chef でデプロイ」の記事で記した内容とほぼ手順は変 わりませんでした。rcbops-cookbooks/rcbops-utils 内にソフトウェアの取得先レポジ トリを記すレシピが下記の場所にあります。

https://github.com/rcbops-cookbooks/osops-utils/blob/master/recipes/packages.rb

そして havana ブランチの attributes を確認すると Ubuntu Cloud Archive の URL が記されていることが確認出来ます。下記のファイルです。

https://github.com/rcbops-cookbooks/osops-utils/blob/havana/attributes/repos.rb

ファイルの中身の抜粋です。

1
2
3
4
5
6
7
"havana" => {
  "uri" => "http://ubuntu-cloud.archive.canonical.com/ubuntu",
  "distribution" => "precise-updates/havana",
  "components" => ["main"],
  "keyserver" => "hkp://keyserver.ubuntu.com:80",
  "key" => "EC4926EA"
},

これらのことより、rcbops-utils の attibutes で havana (実際には ‘havana-proposed’) をレポジトリ指定するように Cookbooks 構成を管理してあげれば Havana 構成の Keystone, Swift が構築出来ることになります。ちなみに havana-proposed で Swift や Keystone のどのバージョンがインストールされるかは、 下記の Packages ファイルを確認すると判断出来ます。

http://ubuntu-cloud.archive.canonical.com/ubuntu/dists/precise-proposed/havana/main/binary-amd64/Packages

以上です。

Sensu,Chef,OpenStack,Fog を使ったオレオレオートスケーラを作ってみた!

こんにちは。@jedipunkz です。

今まで監視システムの Sensu やクラウドプラットフォームの OpenStack、コンフィギュ レーションマネージメントツールの Chef やクラウドライブラリの Fog 等使ってきま したが、これらを組み合わせるとオレオレオートスケーラ作れるんじゃないか?と思い、 ちょろっと作ってみました。

ちなみに自分はインフラエンジニアでしかも運用の出身なので Ruby に関しては初心者 レベルです。Chef で扱っているのと Rails アプリを作った経験はありますが、その程 度。Fog というクラウドライブラリにコントリビュートしたことはアリますが..。ちな みに Fog のコントリビュート内容は OpenStack Neutron(当時 Quantum) の仮想ルータ の操作を行う実装です。

そんな自分ですが…設計1周間・実装1周間でマネージャと CLI が出来ました。 また暫く放置していたマネージャと CLI に WebUI くっつけようかなぁ?と思って sinatra の学習を始めたのですが、学習を初めて 1.5 日で WebUI が動くところまで行 きました。何故か?Ruby には有用な技術が揃っているから・・!(´;ω;`)ブワッ

オレオレオートスケーラ ‘sclman’ の置き場所

https://github.com/jedipunkz/sclman

スクリーンショット

構成は?

+-------------- public network                  +-------------+
|                                               |sclman-api.rb|
+----+----+---+                                 |  sclman.rb  |
| vm | vm |.. |                                 |sclman-cli.rb|
+-------------+ +-------------+ +-------------+ +-------------+
|  openstack  | | chef server | | sensu server| | workstation |
+-------------+ +-------------+ +-------------+ +-------------+
|               |               |               |
+---------------+---------------+---------------+--------------- management network

‘sclman’ っていう名前です。上図の workstation ノードで稼働します。処理の流れは

処理の流れ

  • 1) sclman-cli.rb もしくは WebUI から HTTP クラスタのセットを OpenStack 上に生成
  • 2) 生成された VM に対して Chef で nginx をインストール
  • 3) Chef の Roles である ‘LB’ と ‘Web” が同一 Envrionment になるようにブートストラップ
  • 4) LB VM のバックエンドに Web VM が指し示される
  • 5) bootstrap と同時に sensu-client をインストール
  • 6) Web VM の load を sensu で監視
  • 7) sclman.rb (マネージャ) は Sensu AP を定期的に叩いて Web VM の load を監視
  • 8) load が高い environment があれが該当 environment の HTTP クラスタに VM を追加
  • 9) LB VM は追加された VM へのリクエストを追加
  • 10) 引き続き監視し一定期間 load が上がらなけれ Web VM を削除
  • 11) LB VM は削除された VM へのリクエストを削除

といった感じです。要約すると CLI/WebUI から HA クラスタを作成。その時に LB, Web ミドルウェアと同時に sensu クライアントを VM に放り込む。監視を継続して負 荷が上昇すれば Web インスタンスの数を増加させ LB のリクエスト振り先にもその追 加した VM のアドレスを追加。逆に負荷が下がれば VM 削除と共にリクエスト振り先も 削除。この間、人の手を介さずに処理してくれる。です。

使い方

詳細な使い方は github の README.md を見て下さい。ここには簡単な説明だけ書いて おきます。

  • sclman を github から取得して bundler で必要な gems をインストールします。
  • chef-repo に移動して Berkshelf で必要な cookbooks をインストールします。
  • cookbooks を用いて sensu をデプロイします。
  • Omnibus インストーラーを使って chef サーバをインストールします。
  • OpenStack をインストールします。
  • sclman.conf を環境に合わせて修正します。
  • sclman.rb (マネージャ) を稼働します。
  • sclman-api.rb (WebUI/API) を稼働します。
  • sclman-cli.rb (CLI) もしくは WebUI から最小構成の HTTP クラスタを稼働します。
  • この状態で ‘Web’ Role のインスタンスに負荷が掛かると ‘Web’ Role のインスタンスの数が増加します。
  • また逆に負荷が下がるとインスタンス数が減ります。

負荷の増減のシビアさは sclman.conf のパラメータ ‘man_sensitivity’ で決定します。 値が長ければ長いほど増減のし易さは低下します。

まとめ

こんな僕でも Ruby の周辺技術使ってなんとなくの形が出来ましたー。ただまだまだ課 題はあって、インフラを制御するアプリってエラーハンドリングが難しいっていうこと です。帰ってくるエラーの一覧などがクラウドプラットフォーム・クラウドライブラリ のドキュメントにあればいいのだけど、まだそこまで行ってない。Fog もまだまだ絶賛 開発中と言うかクラウドプラットフォームの進化に必死で追いついている状態なので、 僕らがアプリを作るときには自分でエラーを全部洗い出す等の作業が必要になるかもし れない。大変だけど面白い所でもありますよね!これからも楽しみです。

Journal 用 SSD を用いた Ceph 構成の構築

こんにちは、@jedipunkz です。

前回、’Ceph のプロセス配置ベストプラクティス’ というタイトルで記事を書きました。

http://jedipunkz.github.io/blog/2014/01/29/ceph-process-best-practice/

今回はこの記事にあるポリシに従って下記のような特徴を持った構成を作る手順を具体 的に書いていきたいと思います。

  • ceph01 - ceph04 の4台構成
  • ノードに HDD 2台搭載されていることを前提 (/dev/sdb, /dev/sdc)
  • ノードに Journal 用 SSD 1台搭載されていることを前提 (/dev/ssd)
  • ceph04 は mds サービス稼働
  • ceph05 は ceph-deploy を実行するためのワークステーション
  • 最終的に ceph04 から Ceph をマウントする
  • mon は ノード単位で稼働
  • osd は HDD 単位で稼働
  • mds は ceph04 に稼働

構成 : ハードウェアとノードとネットワークの関係

                                                                                      public network
         +-------------------+-------------------+-------------------+-------------------+---------
         |                   |                   |                   |                   |
+--------+--------+ +--------+--------+ +--------+--------+ +--------+--------+ +--------+--------+
|      ceph01     | |      ceph02     | |      ceph03     | |      ceph04     | |      ceph05     |
| +-----+ +-----+ | | +-----+ +-----+ | | +-----+ +-----+ | |                 | |                 |
| | sdb | | sdc | | | | sdb | | sdc | | | | sdb | | sdc | | |                 | |                 |
| +-----+-+-----+ | | +-----+-+-----+ | | +-----+-+-----+ | |                 | |                 |
| |     ssd     | | | |     ssd     | | | |     ssd     | | |                 | |                 |
| +-------------+ | | +-------------+ | | +-------------+ | |                 | |                 |
+--------+--------+ +--------+--------+ +--------+--------+ +-----------------+ +-----------------+
         |                   |                   |                                    cluster network
         +-------------------+-------------------+-------------------------------------------------

構成 : プロセスとノードとネットワークの関係

                                                                                      public network
         +-------------------+-------------------+-------------------+-------------------+---------
         |                   |                   |                   |                   |
+--------+--------+ +--------+--------+ +--------+--------+ +--------+--------+ +--------+--------+
|      ceph01     | |      ceph02     | |      ceph03     | |      ceph04     | |      ceph05     |
| +-----+ +-----+ | | +-----+ +-----+ | | +-----+ +-----+ | | +-------------+ | |                 |
| | osd | | osd | | | | osd | | osd | | | | osd | | osd | | | |     mds     | | |                 |
| +-----+-+-----+ | | +-----+-+-----+ | | +-----+-+-----+ | | +-------------+ | |                 |
| |     mon     | | | |     mon     | | | |     mon     | | |                 | |                 |
| +-------------+ | | +-------------+ | | +-------------+ | |                 | |                 |
+--------+--------+ +--------+--------+ +--------+--------+ +-----------------+ +-----------------+
         |                   |                   |                                    cluster network
         +-------------------+-------------------+-------------------------------------------------

注意 : 上記の図だと ssd : mon が対に見えますが、そうではありません。

では構築方法について書いていきます。

作業用ホストの準備

ノンパスフレーズの SSH 公開鍵・秘密鍵を生成する。

% ssh-keygen

公開鍵をターゲットホスト (ceph01-03) に配置

% ssh-copy-id ceph@ceph01
% ssh-copy-id ceph@ceph02
% ssh-copy-id ceph@ceph03

ceph-deploy の取得を行う。

% git clone https://github.com/ceph/ceph-deploy.git ~/ceph-deploy

‘python-virtualenv’ パッケージをインストールする。

% sudo apt-get update ; sudo apt-get -y install python-virtualenv

ceph-deploy をブートストラップする

% cd ~/ceph-deploy
% ./bootstrap

PATH を通す。下記は例。

% ${EDITOR} ~/.zshrc
export PATH=$HOME/ceph-deploy:$PATH

ホスト名の解決を行う。IP アドレスは例。

% sudo ${EDITOR} /etc/hosts
10.200.10.11    ceph01
10.200.10.12    ceph02
10.200.10.13    ceph03
10.200.10.14    ceph04
10.200.10.15    ceph05

上記の構成の構築方法

以前の記事同様に ceph-deploy をデプロイツールとして用いる。

ceph-deploy に関しては下記の URL を参照のこと。

https://github.com/ceph/ceph-deploy

下記の手順でコンフィギュレーションと鍵の生成を行う。またこれからの操作はすべて public network 上の ceph-deploy 専用 node からの操作とする。

% mkdir ~/ceph-work
% cd ~/ceph-work
% ceph-deploy --cluster cluster01 new ceph01 ceph02 ceph03 ceph04

~/ceph-work ディレクトリ上に cluster01.conf が生成されているので下記の通り cluster network を扱う形へと追記を行う。

public network = <public_network_addr>/<netmask>
cluster network = <cluster_network_addr>/<netmask>

[mon.a]
    host = ceph01
    mon addr = <ceph01_ip_addr>:6789

[mon.b]
    host = ceph02
    mon addr = <ceph02_ip_addr>:6789

[mon.c]
    host = ceph03
    mon addr = <ceph03_ip_addr>:6789

[osd.0]
    public addr = <ceph01_public_ip_addr>
    cluster addr = <ceph01_cluster_ip_addr>

[osd.1]
    public addr = <ceph01_public_ip_addr>
    cluster addr = <ceph01_cluster_ip_addr>

[osd.2]
    public addr = <ceph01_public_ip_addr>
    cluster addr = <ceph01_cluster_ip_addr>

[mds.a]
    host = ceph04

ceph の各 nodes へのインストールを行う。ceph はワークステーションである ceph05 にも インストールしておきます。後に Ceph ストレージをマウントするためです。

% ceph-deploy --cluster cluster01 install ceph01 ceph02 ceph03 ceph04 ceph04

mon プロセスを各 nodes で稼働する。

% ceph-deploy --cluster cluster01 mon create ceph01 ceph02 ceph03

鍵の配布を各 nodes に行う。

% ceph-deploy --cluster cluster01 gatherkeys ceph01 ceph02 ceph03 ceph04 ceph05

disk のリストを確認。

各 node 毎に用いることが可能は disk の一覧を確認する。

% ceph-deploy --cluster cluster01 disk list ceph01
% ceph-deploy --cluster cluster01 disk list ceph02
% ceph-deploy --cluster cluster01 disk list ceph03

disk の初期化を行う。この作業を行うと指定ディスク上のデータは消去される。

% ceph-deploy --cluster cluster01 disk zap ceph01:/dev/sdb ceph01:/dev/sdc
% ceph-deploy --cluster cluster01 disk zap ceph02:/dev/sdb ceph02:/dev/sdc
% ceph-deploy --cluster cluster01 disk zap ceph03:/dev/sdb ceph03:/dev/sdc

journal 用の ssd のパーティションを切る。ここでは 10GB 毎に切った /dev/ssd1, /dev/ssd2 が存在することを前提に記す。ceph と同時にインストールされた gdisk を用いる。

% sudo gdisk /dev/ssd

(注意) 下記の公式ドキュメントでは osd prepare, osc activate の手順が掲載されて いるがその後の osd create のコマンドにて prepare が実行されるようでこれら2つの 手順を行うと正常に osd create コマンドが実行できなかった。よってこのタイミング にて osd create を行うものとする。

2 つの disk に対してそれぞれ osd を稼働させる。

% ceph-deploy --cluster cluster01 osd create ceph01:sdb:/dev/ssd1 ceph02:sdb:/dev/ssd1 ceph03:sdb:/dev/ssd1
% ceph-deploy --cluster cluster01 osd create ceph01:sdc:/dev/ssd2 ceph02:sdc:/dev/ssd2 ceph03:sdc:/dev/ssd2

mds の稼働を行う。ここでは1号機にのみ稼働を行う。

% ceph-deploy --cluster cluster01 mds create ceph04

クライアントからのマウント方法各種

上記で構築した Ceph ストレージを利用する方法を3つ説明する。先に述べたように POSIX 互換 filesystem として利用が可能。それぞれ mds が稼働しているホストに対 して接続を行う。

Block Device としてマウントする方法

ストレージ上に block device を生成しそれをマウントする

cephclient% rbd create foo --size 4096
cephclient% sudo modprobe rbd
cephclient% sudo rbd map foo --pool rbd --name client.admin
cephclient% sudo mkfs.ext4 -m0 /dev/rbd/rbd/foo
cephclient% sudo mkdir /mnt/myrbd
cephclinet% sudo mount /dev/rbd/rbd/foo /mnt/myrbd

Kernel Driver を用いてマウントする方法

kernel Driver を用いてストレージをマウントする

cephclient% sudo mkdir /mnt/mycephfs
cephclient% sudo mount -t ceph 10.200.10.26:6789:/ /mnt/mycephfs -o \
            name=admin,secret=`sudo ceph-authtool -p /etc/ceph/cluster01.client.admin.keyring`

Fuse Driver (ユーザランド) を用いてマウントする方法

ユーザランドソフトウェア FUSE を用いてマウントする方法

cephclient% sudo mkdir /home/<username>/cephfs
cephclient% sudo ceph-fuse -m 10.200.10.26:6789 /home/<username>/cephfs

Ceph のプロセス配置ベストプラクティス

Ceph はブロック型の分散ストレージファイルシステムです。POSIX のファイルシステ ムとしてマウント出来ます。Linux の Kernel ドライバや FUSE ドライバを用いてマウ ントします。またブロックデバイスとしてマウントする方法もあります。

だいぶ前ですが、Ceph に関する記事を以前下記の通り書きました。

Ceph の構築方法について記したブログだったのですが、今まで mon, osd, mds の各プ ロセスをそれぞれ何台のノードに対して配置し、またそれぞれのプロセス幾つを何に対 して配置するのか?という疑問が付きまとわっていました。node, disk, process のそ れぞれの数の関係について知りたいなぁと思っていました。幾つかのドキュメントを読 んでいて、ぼんやり見えてきた事があるのでそれを今回はまとめたいと思います。

また、皆さん気になるトコロだと思われる容量設計についても軽く触れたいと思います。

参考資料

各要素の数の関係

ハードウェア要素である node, disk(hdd), ssd そしてソフトウェア要素である mon, osd, mds の数の関係はどのようにするべきか?基本となる関係は

  • 1 mds process / node
  • 1 mon process / node
  • 1 osd process / disk
  • n jornal ssd device / disk / node

だと考えられます。僕が今のところ理想かなぁと思っている構成をまとめたいと思いま す。

下記の図がそれです。

+------------------------+
|         client         |
+------------------------+
|
+--------------------------+--------------------------+-------------------------------+-------------------------
|                          |                          |                               |            public network
+------------------------+ +------------------------+ +------------------------+      +------------------------+
|          mon           | |          mon           | |          mon           |      |          mds           |
+------+ +------+ +------+ +------+ +------+ +------+ +------+ +------+ +------+      +------------------------+
| osd  | | osd  | | osd  | | osd  | | osd  | | osd  | | osd  | | osd  | | osd  |      |                        |
+------+ +------+ +------+ +------+ +------+ +------+ +------+ +------+ +------+      |                        |
| disk | | disk | | disk | | disk | | disk | | disk | | disk | | disk | | disk |....> |                        |
+------+ +------+ +------+ +------+ +------+ +------+ +------+ +------+ +------+scale |          node          |
|          ssd           | |          ssd           | |          ssd           |      |                        |
+------------------------+ +------------------------+ +------------------------+      |                        |
|          node          | |          node          | |          node          |      |                        |
+------------------------+ +------------------------+ +------------------------+      +------------------------+
|                          |                          |                               |
+--------------------------+--------------------------+-------------------------------+-------------------------
                                                                                                  cluster network

mds と node の関係

mds はリモートクライアントへのファイルシステムサービスの提供を行うことや特性が 全く異なることから別ノードに切り出しました。また mds は幾つかのノードで稼働さ せる事も可能。が、mds はそれぞれのサービスを HA 組む仕組みは持っていないので どれか一方の mds をクライアントは指し示す必要があり、その mds が停止すれば直 ちに障害に発展します。

mon と node の関係

mon は比較的少量のリソースで稼働します。今回 osd と同じノードの搭載しましたが 別ノードに切り出すことも勿論可能です。mon は CRUSH Maps アルゴリズムの元に連携 が取れますので複数のプロセスを稼働することが推奨されていることからも、比較的少 ないノード数のクラスタの場合は osd と同ノードに搭載するのが容易かなと考えまし た。

osd と node の関係

1 osd プロセスに対して 1 disk が基本となります。osd は実データのレプリケーショ ンを行うことからコンフィギュレーションに対して上図の様にクラスタ用のネットワー クを紐付け、高トラヒックに対応する必要があります。また osd 用の disk device で すが RAID を組まないことが推奨されています。CEPH 自体に HA の仕組みがあること、 また RAID 構成にもよりますがディスクアクセスが遅くなることは Ceph にとってボト ルネックを早く招くことになりますし、小さいディスク容量しか扱えなくなることは Ceph にとって不利になると思います。

journal 用の ssd device と disk, node の関係

現在の Stable Release 版の Ceph は journal を用いてメタデータを管理します。各 osd の disk 単位に journal 用の disk device を指定出来るようになっています。メ タデータですので実データ用の disk よりだいぶ小さな容量で構わないこと、また比較 的高速なアクセスを要求されることからも SSD を選択することが推奨されつつあるよ うです。実際にストアされるデータの特性にもよりますが 1 node に対して 1 ssd device を配置すれば十分かと思います。また osd のプロセスの数 (disk の数) に対 して一つのパーティションを切ることで対応出来るかと思います。

設定方法の例を記します。ここに ceph01-03 の3台のノードがありそれぞれ 2 disk, 1 ssd が搭載されているとします。/dev/ssd は gdisk 等を用いて2つ以上のパーティショ ンに切り分けます。

下記のように /dev/sdb (hdd) に対して /dev/ssd1 (ssd), /dev/sdc (hdd) に対して /dev/ssd2 (ssd) を割り当てることが出来ます。

% ceph-deploy --cluster cluster01 osd create ceph01:sdb:/dev/ssd1 ceph02:sdb:/dev/ssd1 ceph03:sdb:/dev/ssd1
% ceph-deploy --cluster cluster01 osd create ceph01:sdc:/dev/ssd2 ceph02:sdc:/dev/ssd2 ceph03:sdc:/dev/ssd2

Ceph ストレージ全体の容量設計と mon の ratio の関係

3TB のディスクを持ったノードが 33 台並んでいるとします。各ノードには osd プロ セスが1つ稼働します。合計容量は 99 TB となりますが mon が持っているコンフィギュ レーションである full ratio というパラメータがありデフォルト値が 0.95 となって います。よってこのクラスタで扱える全体のディスク容量は 95TB となります。

また、ラックに数台のノードを積むのが通常ですが、電源故障等で一気にラック単位で 障害が発生したとします。この場合 Ceph はすべてのデータに関してレプリカを取り復 旧作業を行います。しかしながら停止するノード数によってはストレージ全体の扱える 容量をオーバーすることも懸念されます。これに対応するために先ほど登場した ratio パラメータを調整することが出来ます。

[global]

mon osd full ratio = .80
mon osd nearfull ratio = .70

上記の例では full ステートの ratio が 0.80, nearfull ステートの ratio が 0.70 となります。想定の障害ノード数を考慮し ratio パラメータにてその台数分を減算す れば良いわけです。

まとめ

前述した通り上図は比較的少ないノード数のクラスタを組む場合を想定しています。ノー ド数が増える場合は mon は mds, osd とも必要とするリソースの特性が異なりますの で別ノードに切り出すことも考えたほうが良さそうです。2014年の2月には Firefly と いう新しいリリース版が出ます。ここでのブループリント(設計書)を確認すると…

http://wiki.ceph.com/Planning/Blueprints/Firefly/osd%3A_new_key%2F%2Fvalue_backend

journal に変わる新たなメタデータ管理方法として KVS データベースを扱うことも視 野に入っているようです。上記の URL 見る限りでは Facebook がオープンソースにし た rocksdb や fusionio の nvmkv, seagate の kinetic 等が挙がっています。2月に 期待しましょう!

第17回 OpenStack 勉強会で話してきました

こんにちは。@jedipunkz です。

昨晩、第17回 OpenStack 勉強会が開催されました

http://connpass.com/event/4545/

ここで発表をしてきましたぁ!発表タイトルは “rcbops/chef-cookbooks” です。

何を発表したかと言うと詳しくは上記のスライドを見ていただくとして、簡単に言うと “RackSpace 社のエンジニアが管理している Chef Cookbooks でOpenStack 構成を作ろ う” ってことです。

今日知ったのですがどうも昨晩は初心者向けの勉強会という位置付けだったらしく..少 しだけディープな話題を話してしまったかもしれません!すいません!><

でもとても楽しく発表出来ましたし、逆に質問のコーナーで最新の情報も教えてもらえ たり!なんと Havana 対応の v4.2.0 以降では Swift の Cookbooks が消えてしまった とか!… 皆 Swift 好きくないの?…; ;

rcbops/chef-cookbooks はずっと追っていますが、ものすごいスピードで開発進んでい るので、今後ぜひみなさん使ってみて下さいー。

最後に詳しい利用方法を記した僕のブログの URL を貼り付けておきます。

  • OpenStack Havana を Chef でデプロイ

http://jedipunkz.github.io/blog/2013/11/17/openstack-havana-chef-deploy/

  • Swift HA 構成を Chef でデプロイ

http://jedipunkz.github.io/blog/2013/07/26/swift-ha-chef-deploy/

  • 実用的な Swift 構成を Chef でデプロイ

http://jedipunkz.github.io/blog/2013/10/27/swift-chef/

Chef で自律的クラスタを考える

こんにちは。@jedipunkz です。

Serf の登場があったり、ここ最近オーケストレーションについて考える人が増えた気 がします。システムをデプロイしてその後各ノード間の連結だったりも同じ Chef, Puppet 等のコンフィギュレーションツールで行うのか?全く別のツールで?..

最近 Serf というツールの登場がありました。

僕も Serf を触ってつい先日ブログに書きました。有用なツールだと思います。シ ンプルだからこそ応用が効きますし、リアルタイム性もあり、将来的に異なるネットワー クセグメント上のノードとも連結出来るようになりそうですし、とても期待です。

話が少し飛びますが..

いつも Rebuild.fm を楽しく聞いているのですが Immutable Infrastructure の話題の 時にオーケストレーションの話題になって、どうも ‘Chef でも自律的なクラスタを組 むことが認知されていないのでは?’ と思うようになりました。もちろん Chef でやる べき!とは言い切りませんし、今後どうなるかわかりません。Opscode の中の人も ‘オー ケストレーションは自分でやってね’ というスタンスだったとずいぶん前ですが聞きま した。Serf を等のオーケストレーションツールを使う使わないの話は今回はしないの ですが Chef でも自律的クラスタを組むことは出来ますよ〜というのが今回の話題。

まえがきが長くなりました。

今回は Chef で自律的クラスタを構成する方法を記したいと思います。

haproxy 等を利用すれば尚良いと思いますが、よりクラスタを組むのが簡単な nginx を今回は利用したいと思います。

https://github.com/opscode-cookbooks/nginx

構成

‘web’ という Role 名と ‘lb’ という Role 名で単純な HTTP サーバとしての nginx ノードを複数台と、ロードバランサとしての nginx ノードを1台でクラスタを構成しま す。また共に environment 名は同じものを利用します。別の environment 名の場合は 別クラスタという区切りです。

  • ‘lb’ node x 1 + ‘web’ node x n (‘foo’ environment)
  • ‘lb’ node x 1 + ‘web’ node x n (‘bar’ environment)

‘lb’ nginx ロードバランサのレシピ

下記が ‘lb’ Role の recipes/cmomnos_conf.rb の修正した内容です。

1
2
3
4
5
6
7
8
9
10
11
12
13
environment = node.chef_environment
webservers = search(:node, "role:web AND chef_environment:#{environment}")

template "#{node['nginx']['dir']}/sites-available/default" do
  source "default-site.erb"
  owner "root"
  group "root"
  mode 00644
  notifies :reload, 'service[nginx]'
    variables ({
      :webservers => webservers
    })
end

何をやっているかと言うと、environment という変数に自ノードの environment 名を。 webservers という変数に role 名が ‘web’ で尚且つ自ノードと同じ environment 名 が付いたノード名を入れています。これで自分と同じ environment に所属している ‘web’ Role なノードを Chef サーバに対して検索しています。また、template 内で webservers という変数をそのまま利用できるように variables で渡しています。

‘lb’ nginx ロードバランサのテンプレート

下記が webservers 変数を受け取った後の template 内の処理です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<% if @webservers and ( @webservers != [] ) %>
upstream backend {
<% @webservers.each do |hostname| -%>
  server <%= hostname['ipaddr'] -%>;
<% end -%>
}
<% end %>
  
server {
  listen   80;
  server_name  <%= node['hostname'] %>;
    
  access_log  <%= node['nginx']['log_dir'] %>/localhost.access.log;
    
  location / {
    <% if @webservers and ( @webservers != [] ) %>
    proxy_pass http://backend;
    <% else %>
    root   /var/www/nginx-default;
    index  index.html index.htm;
    <% end %>
  }
}

upstream backend { … は皆さん見慣れた記述だと思うのですが、バックエンドの HTTP サーバの IP アドレスを一覧化します。each で回しているので台数分だけ server ; の記述が入ります。

chef-client をデーモン稼働しておけば、新規に Chef サーバに登録された ‘web’ Role の HTTP サーバを自動で ‘lb’ Role のロードバランサが組み込む、つまり自律的 なクラスタが組めることになります。もちろんこの間の手作業は一切ありません。

ちなみに chef-client をデーモン稼働するには

recipe[chef-client::service]

というレシピをノードに割り当てることで可能です。

まとめ

Chef でも自律的なクラスタが組めました。もちろん chef-client の稼働間隔があるの でリアルタイム性はありません。chef-client の稼働間隔は ‘chef-client’ レシピの attributes で調整出来ます。その点は serf のほうが確実に勝っていると見るべきで しょう。冒頭に記したようにこの辺りの操作を Chef で行うのか別のツールを使うのか はまだまだ模索が必要そう。ただ、私がいつも使っている ‘OpenStack を Chef で構成 する Cookbooks’ 等は複数台構成を Chef で構成しています。なので僕にとってはこの 辺りの話は当たり前だと思っていたのだけど、どうも勉強会に出たりすると “Chef は 複数台構成を作るのが苦手だ” って話があがってくるので気になっていました。

CoreOS Etcd のクラスタとその応用性

こんにちは。@jedipunkz です。

皆さん CoreOS は利用されたことありますか?CoreOS は軽量な docker との相性の良 い OS です。下記が公式サイト。

http://coreos.com/

特徴としては下記の3つがあります。

  • etcd
  • systemd
  • docker

ここではこの中の etcd について注目していきたいと思います。etcd はクラスタエイ ブルな KVS データベースです。コンフィギュレーションをクラスタ間で共有すること がなので、オーケストレーションの分野でも期待出来るのでは?と個人的に感じていま す。今回は etcd のクラスタ構成構築の手順とその基本動作の確認、またどう応用出来 るのか?について記していきたいと思います。

参考 URL

ビルド

go 1.1 or later をインストールして etcd のコンパイル準備を行います。Ubuntu Saucy のパッケージを用いると容易に行えます。

% apt-get -y install golang

coreos/etcd を取得しビルド

% git clone https://github.com/coreos/etcd
% cd coreos
% ./build
% ./etcd --version
v0.2.0-rc1-60-g73f04d5

CoreOS の用意

ここではたまたま手元にあった OpenStack を用いて CoreOS のイメージを登録してい みます。ベアメタルでも可能ですのでその場合は手順を読み替えて作業してみてくださ い。OpenStack 等クラウドプラットフォームを利用する場合は metadata サービスが必 須となるので注意してください。

% wget http://storage.core-os.net/coreos/amd64-generic/dev-channel/coreos_production_openstack_image.img.bz2
% bunzip2 coreos_production_openstack_image.img.bz2
% glance image-create --name coreos-image --container-format ovf \
  --disk-format qcow2 --file coreos_production_openstack_image.img

nova boot にて CoreOS を起動します。(下記は例)

% nova keypair-add testkey01 > testkey01.pem
% nova boot --nic net-id .... --image coreos-image --flavor 1 --key_name testkey01 coreos01

CoreOS 上での etcd クラスタ起動

上記でコンパイルした etcd のバイナリを起動したインスタンス (CoreOS) に転送しま す。scp 等で転送してください。

ここでは 1 node 上で複数のポート番号を用いて 3 つの etcd を稼働することでクラ スタを構築します。

7002 番ポートを peer addr として master を起動。listen ポートは 4002

% ./etcd -peer-addr 127.0.0.1:7002 -addr 127.0.0.1:4002 -data-dir machines/machine1 -name machine1

上記の master を参照する slaves (残り2台) を起動。

% ./etcd -peer-addr 127.0.0.1:7003 -addr 127.0.0.1:4003 -peers 127.0.0.1:7002 -data-dir machines/machine2 -name machine2
% ./etcd -peer-addr 127.0.0.1:7004 -addr 127.0.0.1:4004 -peers 127.0.0.1:7002 -data-dir machines/machine3 -name machine3

クラスタ構成内のノード情報を確認する。

% curl -L http://127.0.0.1:4002/v2/machines
[etcd] Dec  4 03:46:44.153 INFO      | URLs: machine1 / machine1 (http://127.0.0.1:4002,http://127.0.0.1:4003,http://127.0.0.1:4004)
http://127.0.0.1:4002, http://127.0.0.1:4003, http://127.0.0.1:4004

leader (master) 情報を確認する。

% curl -L http://127.0.0.1:4002/v2/leader
http://127.0.0.1:7002

上記で起動した master プロセスが leader (master) になっていることを確認出来る と思います。

キーの投入と参照

テストでキーと値を入力してみましょう。’foo’ キーに ‘bar’ という値を投入てくだ さい。

% curl -L http://127.0.0.1:4002/v2/keys/foo -XPUT -d value=bar

クラスタ内全てのプロセスから上記のキーの取得できることを確認します。

% curl -L http://127.0.0.1:4002/v2/keys/foo
{"action":"get","node":{"key":"/foo","value":"bar","modifiedIndex":4,"createdIndex":4}}
% curl -L http://127.0.0.1:4003/v2/keys/foo
{"action":"get","node":{"key":"/foo","value":"bar","modifiedIndex":4,"createdIndex":4}}
% curl -L http://127.0.0.1:4004/v2/keys/foo
{"action":"get","node":{"key":"/foo","value":"bar","modifiedIndex":4,"createdIndex":4}}

master のシャットダウンと master 選挙後の動作確認

テストで master のプロセスをシャットダウンしてみます。

master プロセスのシャットダウン

% kill <master プロセスの ID>

その他 2 つのプロセスから ‘foo’ キーの確認を行う。

% curl -L http://127.0.0.1:4004/v2/keys/foo
{"action":"get","node":{"key":"/foo","value":"bar","modifiedIndex":4,"createdIndex":4}}
% curl -L http://127.0.0.1:4003/v2/keys/foo
{"action":"get","node":{"key":"/foo","value":"bar","modifiedIndex":4,"createdIndex":4}}

勿論、旧 master からは確認出来ない。

% curl -L http://127.0.0.1:4002/v2/keys/foo
curl: (7) Failed connect to 127.0.0.1:4002; Connection refused

新 master の確認を行う。選挙の結果 3 つ目のプロセスが master に昇格しているこ とが確認出来る。

% curl -L http://127.0.0.1:4003/v2/leader
http://127.0.0.1:7004

考察とその応用性について

とてもシンプルな KVS ではあるけど大きな可能性を秘めていると思っています。オー ケストレーション等への応用です。お互いのノード (今回はプロセス) 間で情報をやり とりできるので自律的なクラスタの構築も可能になるのでは?と思っています。

‘etcenv’ という @mattn さんが開発したツールを見てみましょう。

https://github.com/mattn/etcdenv

下記、README から引用。

$ curl http://127.0.0.1:4001/v1/keys/app/db -d value="newdb"
$ curl http://127.0.0.1:4001/v1/keys/app/cache -d value="new cache"

$ curl http://localhost:4001/v1/keys/app
[{"action":"GET","key":"/app/db","value":"newdb","index":4},{"action":"GET","key":"/app/cache","value":"new cache","index":4}]

$ etcdenv -key=/app/
DB=newdb
CACHE=new cache

$ etcdenv -key=/app/ ruby web.rb

クラスタ間の情報を環境変数に落としこむツールです。自ノードの環境変数まで落ちれ ば、クラスタ構築も色々想像出来るのではないでしょうか?

軽量で docker との相性も良くて etcd 等の仕組みも持っている CoreOS にはこれから も期待です。