vagrantで複数VMを起動して、serfのjoinとevent通知をやってみたいと思います。最終的にVMを動的に生成しserfの環境構築からクラスタへの参加を自動化してみます。
環境構築
vagrantの環境
tree-no-iMac:vagrant tree$ vagrant version Installed Version: 1.7.1
Vagrantfile
2台構成で、今回は最新のCentOS7を使います。
記憶が定かではありませんが、使用したBOXは以下だったと思います。
http://www.vagrantbox.es
CentOS7.0 x86_64 minimal (VirtualBoxGuestAddtions 4.3.14)
メモリ割り当てを1台1Gにしてますが、256Mとかでも全然余裕です。
# -*- mode: ruby -*- # vi: set ft=ruby : VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.define :node1 do |node| node.vm.box = "centos7.0-min" node.vm.network :private_network, ip: "192.168.33.11" node.vm.provider "virtualbox" do |v| v.customize ["modifyvm", :id, "--memory", 1024, "--cpus", 1] end node.vm.provision :shell, path: "provision.sh" end config.vm.define :node2 do |node| node.vm.box = "centos7.0-min" node.vm.network :private_network, ip: "192.168.33.12" node.vm.provider "virtualbox" do |v| v.customize ["modifyvm", :id, "--memory", 1024, "--cpus", 1] end node.vm.provision :shell, path: "provision.sh" end end
プロビジョニング
Vagrantfileの以下に指定している部分です。
node.vm.provision :shell, path: "provision.sh"
provision.sh
#!/bin/sh # ファイヤーウォールを停止する systemctl stop firewalld # serfをDL DL_DIR="/home/vagrant" FILE="0.6.3_linux_amd64.zip" DL_PATH="$DL_DIR/$FILE" test -f $DL_PATH && rm -rfv $DL_PATH wget -P $DL_DIR https://dl.bintray.com/mitchellh/serf/$FILE unzip -o $DL_PATH rm -rfv $DL_PATH chown vagrant:vagrant $DL_DIR/serf
今回はテストなのでファイヤーウォールを停止させます。
CentOS7の場合iptablesでは無いので注意!!
その後、ホームにserfをDLしてzipを解凍します。すると「serf」単一のバイナリが出てきます。バイナリ1個で動いちゃうところがいいですね。
VMの起動
provisionオプションを付けて起動します。以下の例ではreloadですが、vagrant upの時でもprovisionプションは有効です。
どうやら現在のバージョンではprovisionオプション無しでも勝手にprovisionが実行されるようです。
tree-no-iMac:vagrant tree$ vagrant reload ==> node1: Attempting graceful shutdown of VM... ==> node1: Clearing any previously set forwarded ports... ==> node1: Fixed port collision for 22 => 2222. Now on port 2200. ==> node1: Clearing any previously set network interfaces... ==> node1: Preparing network interfaces based on configuration... ・・・中略・・・ node1: Running: /var/folders/mc/np8x4g8j70n00ptjk75vz3lm0000gn/T/vagrant-shell20150214-24978-5fzsfw.sh ==> node1: --2015-02-14 08:16:59-- https://dl.bintray.com/mitchellh/serf/0.6.3_linux_amd64.zip ==> node1: dl.bintray.com (dl.bintray.com) をDNSに問いあわせています... ==> node1: 108.168.194.91, 108.168.194.92 ==> node1: dl.bintray.com (dl.bintray.com)|108.168.194.91|:443 に接続しています... ==> node1: 接続しました。 ==> node1: HTTP による接続要求を送信しました、応答を待っています... ==> node1: 302 ・・・中略・・・ ==> node1: d29vzk4ow07wi7.cloudfront.net (d29vzk4ow07wi7.cloudfront.net) をDNSに問いあわせています... ==> node1: 54.192.144.235, 54.192.144.231, 54.192.146.106, ... ==> node1: d29vzk4ow07wi7.cloudfront.net (d29vzk4ow07wi7.cloudfront.net)|54.192.144.235|:443 に接続しています... ==> node1: 接続しました。 ==> node1: HTTP による接続要求を送信しました、応答を待っています... ==> node1: 200 OK ==> node1: 長さ: 3002701 (2.9M) [application/unknown] ==> node1: `/home/vagrant/0.6.3_linux_amd64.zip' に保存中 ・・・中略・・・ ==> node1: 2015-02-14 08:17:18 (239 KB/s) - `/home/vagrant/0.6.3_linux_amd64.zip' へ保存完了 [3002701/3002701] ==> node1: Archive: /home/vagrant/0.6.3_linux_amd64.zip ==> node1: inflating: serf ==> node1: `/home/vagrant/0.6.3_linux_amd64.zip' を削除しました
こんな感じにVM起動後、VM上にserfをDLして解凍し、zipを削除しserfがchownされました。
実践
serfのクラスタ構築からイベント通知までをGIFアニメで見る
今回初めてGIFアニメを使ってみたのですが、思ったより容量を喰うので、相当急ぎ足でコマンドを実行しています。
クラスタを生成して自動で参加する
./serf agent -iface=enp0s8 -discover=cluster1 &
こうすることで、serf join 192.168.xxx.xxx のようにしなくても、自動でクラスを探して参加してくれます。
agentコマンドで他マシンと通信するためには実はいくつか必須の設定があります。
iface= enp0s8
これを指定しないとserfはうまく動いてくれず、joinする事ができません。
指定する値はipconfig(CentOS7では ip addr show)で表示されるネットワーク名ですね。
[vagrant@node1 ~]$ ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 08:00:27:85:cd:fb brd ff:ff:ff:ff:ff:ff inet 192.168.33.11/24 brd 192.168.33.255 scope global enp0s8 valid_lft forever preferred_lft forever inet6 fe80::a00:27ff:fe85:cdfb/64 scope link valid_lft forever preferred_lft forever
ここまでの作業を自動化する
前述の例ではわざわざVMにsshしてserfを起動していましたが、今回はプロビジョニングで完全に自動化してみます。
VMのノード生成も自動化します。
Vagrantfile
# -*- mode: ruby -*- # vi: set ft=ruby : VAGRANTFILE_API_VERSION = "2" # 生成するVM数 VM_NUMBER = 2 Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "centos7.0-min" # ノードを動的に複数台生成 (1..VM_NUMBER).each do |vmNumber| # ノード(ホスト)名 nodeName = "node#{vmNumber}" # 付与するIPの末尾 ipNumber = 10 + vmNumber config.vm.define nodeName do |node| node.vm.hostname = nodeName node.vm.network :private_network, ip: "192.168.33.#{ipNumber}" node.vm.provider "virtualbox" do |v| v.customize ["modifyvm", :id, "--memory", 256, "--cpus", 1] end node.vm.provision :shell, path: "provision.sh" end end end
VM_NUMBERの数値を増やすと生成するVMの数を増やせます。ipNumberは私の環境では11から始めていますが、適宜修正して下さい。
provision.sh
#!/bin/sh # ファイヤーウォールを停止する systemctl stop firewalld # serfをDL DL_DIR="/home/vagrant" FILE="0.6.3_linux_amd64.zip" DL_PATH="$DL_DIR/$FILE" test -f $DL_PATH && rm -rfv $DL_PATH wget -P $DL_DIR https://dl.bintray.com/mitchellh/serf/$FILE unzip -o $DL_PATH rm -rfv $DL_PATH # 権限を付与してパスが通る場所に移動 chown vagrant:vagrant $DL_DIR/serf mv $DL_DIR/serf /usr/local/bin # serfを起動してクラスタに参加する su vagrant -c "nohup /usr/local/bin/serf agent -iface=enp0s8 -node=`hostname` -discover=cluster1 0<&- &>/dev/null &"
プロビジョンがrootユーザで行われるので、vagrantユーザでserfを起動しています。
serf agentの末尾の「0<&- &>/dev/null &」の部分ですが、これはvagrant側のバグで、こうしないとプロビジョニングからアプリが起動できないためです。
Shell provisioning fails to exit · Issue #1553 · hashicorp/vagrant · GitHub
vagrant sshしてmembersを実行してみる
プロビジョニング後のnode1でserf membersしてみます。
tree-no-iMac:vagrant tree$ vagrant ssh node1 Last login: Sat Feb 14 09:48:25 2015 from 10.0.2.2 [vagrant@node1 ~]$ serf members node1 192.168.33.11:7946 alive node2 192.168.33.12:7946 alive
うむ。できてますね。ここまで自動化できるといいですね。
雑感
今回はserfを起動して適当なイベントを飛ばしただけですが、本当に必要なのはこの先ですね。例えばjoinした時にmuninノードを追加したりしないと、オーケストレーションする意味がありませんね。。。
とりあえず動かしてみたかっただけなので、今回はここまでです。
やるおよ、なんでdockerでやらないんだ?
dockerの方が起動速いだろ?
・・・・・・・・・・え?ごめん聞こえなかった。なんて?
いや、なんでもないよ。vagrantいいよな。
(dockerの学習が追いついてないんだな・・・)
しかしこういう記事書くと最近のqiitaみたいだよなあ。
「僕は新人です!課題でこんな事やってみました!とりあえず動かしてみました!」的な。
qiitaのとりあえず動かしてみました!を脱却するため、vm自動生成とプロビジョニングまでしてみた(震え声
とかいいつつ今回の記事は以下を参考にさせて頂きました。http://blog.pg1x.com/entry/2014/07/21/231327
やらないお「dockerでやる時は自力でやろうな。英語ドキュメント見てさ。」
やるお「頑張るよ。(qiitaでdockerの記事探してこよ・・)」
- 作者: 新原雅司
- 出版社/メーカー: 技術評論社
- 発売日: 2013/09/12
- メディア: Kindle版
- この商品を含むブログ (5件) を見る
Docker入門 Immutable Infrastructureを実現する
- 作者: 松原豊,米林正明
- 出版社/メーカー: 技術評論社
- 発売日: 2014/04/25
- メディア: Kindle版
- この商品を含むブログ (5件) を見る
[改訂新版] シェルスクリプト基本リファレンス ??#!/bin/shで、ここまでできる (WEB+DB PRESS plus)
- 作者: 山森丈範
- 出版社/メーカー: 技術評論社
- 発売日: 2011/04/27
- メディア: 単行本(ソフトカバー)
- 購入: 9人 クリック: 119回
- この商品を含むブログ (11件) を見る