としたにあんの左脳

備忘録です.

E [glusterfsd-mgmt.c:621:mgmt_getspec_cbk] 0-glusterfs: XDR decoding error

[glusterfsdを起動して,クライアント側でマウントしようとして,何かうまくいってないっぽい.

/var/log/glusterfs/mnt-gfs.logをみてみる.

...
 E [glusterfsd-mgmt.c:621:mgmt_getspec_cbk] 0-glusterfs: XDR decoding error
...

って書いてある.

(ここ)http://lists.gnu.org/archive/html/gluster-devel/2012-04/msg00129.htmlによるとサーバとクライアントのバージョンが違うことが原因みたい.

ちなみに

server: 3.3.2
client: 3.2.5

だった.

クライアントのバージョンが古かったので,新しくしてマウントしたらうまくいった! これで快適glusterFS生活!

Vagrantでクリーンなマシンを手に入れる

ChefのクックブックやAnsibleのPlaybookを作る時,ミドルウェアの検証を行いたい時など,クリーンなマシンが必要となることが多くあると思います.

プライベートクラウドをもっているところならそれを使えばいいと思いますが,プライベートクラウド作るのは一手間かかります.

そこで,Vagrantでクリーンなマシンを作って検証を行える環境を作りたいと思います.

作成するマシンは

Ubuntu Server 12.04 LTS


boxファイルの追加

まず,boxファイルをvagrantに追加します.

追加するboxファイルはvagrant公式のものを使用します.

$ vagrant box add clean http://files.vagrantup.com/precise64.box

ダウンロードにしばらくかかるので辛抱強く待ちます.

仮想マシンの設定

作業ディレクトリに移動しVagrantfileを作成します.

$ mkdir  -p ~/vagrant/clean
$ cd ~/vagrant/clean
$ vagrant init clean

Vagrantfileができていると思います.

 # config.vm.network :private_network, ip: "192.168.33.10"

のコメントを消して,ホストマシン側からアクセスできるようにします.

仮想マシンの起動/sshログイン

仮想マシンを起動します.

$ vagrant up

vagrantの機能を使ってsshログインします.

$ vagrant ssh

通常のsshログインもできます.

ssh -i ~/.vagrant.d/insecure_private_key vagrant@192.168.33.10

これで,クリーンなマシンが手に入ったので,いろいろな検証が可能となりました.

クリーンな環境の復元

クリーンなマシンにいろいろなミドルウェアをインストールした結果,ライブラリやミドルウェア依存関係などがわからなくなることがあります.

そういう場合にはVagrantのdestroyコマンドを使ってマシンを最初の状態に戻すことができます.

virus.exeというファイルを作って,クリーンな環境を壊してみます.

$ vagrant ssh
$ touch ~/virus.exe
$ exit

現在の仮想マシンを壊して,クリーンな環境に戻します.

$ vagrant destroy
$ vagrant up
$ vagrant ssh

boxファイルの最初のクリーン状態に戻っています.

ある時点のマシンの状態を保存しておき,そこから再開する.

とりあえず最低限のライブラリやミドルウェアをインストールしたあとに,検証対象のミドルウェアをインストールしたいことがあります.

なおかつ,複数のバージョンをインストールしてみて,検証してみたい場合等も多いと思います.

こんな場合には,Vagrantのsandboxコマンドが便利です.

1st.txtというファイルが作ってある状態を保存しておき,その状態に戻れるようにします.

$ vagrant up
$ vagrant ssh
$ touch ~/1st.txt
$ exit

この状態のマシンのスナップショットを作成します.

$ vagrant sandbox on
$ vagrant sandbox commit

これで1st.txtが存在する状態のマシンのスナップショットが作成されました.

ここで2nd.txtを作成します.

$ vagrant ssh
$ touch ~/2nd.txt
$ exit

この状態ではマシンには1st.txt2nd.txtが存在します.

ここで,1st.txtが作成された直後の状態に戻してみます.

$ vagrant sandbox rollback
$ vagrant ssh

2nd.txtをつくる前の状態に戻りました.


これで,クリーン状態のマシンを手に入れることができました.

加えて,環境を壊した後でクリーンな状態に戻すこと,ある時点の環境へ戻ることが可能となりました.

気合を入れて構成管理の実験やミドルウェアの検証ができますね.

(Ansible Galaxy)https://galaxy.ansible.com/も始まったことですし,Ansible Playbookを作って公開していきたいものですね.

mongodbのObjectIdの生成規則

MongoDBのマイグレーションとかしてたら,MongoDBのObjectIdって本当にユニークだっけ?っていう疑問がわいた.

確かいろいろな要素を使って,ユニークになるようにできてたよなぁ...と思って,ちゃんと調べてみた.

とりあえず公式のObjectIdの説明.ObjectId - MongoDB Manual 2.4.9

  • 4バイトの,Unixエポックからの経過秒数(Unix時間)
  • 3バイトのマシンID
  • 2バイトのプロセスID
  • 3バイトのカウンタ(開始番号はランダム)

からできているらしい.

f:id:toshitanian:20140214011947p:plain

↑がんばって書いた.

実験!

同じマシンで生成してみる.

以下の2つのObjectIdは同じマシン上で生成したObjectId.

52fcf106 0af12b af9e 8d5bba
52fcf108 0af12b af9e 8d5bbb

確かに最初のUnix時間は2秒ずれていることがわかる.

マシンIDは同じ.

プロセスIDも同じ.

カウンタは1だけ上がっていることがわかる.

違うマシンで生成してみる.

今度は別のマシンで生成してみる.

確かにマシンIDプロセスIDが上のObjectIdとは違っている!

52fcebd1 9a5c4e a066 dbfa12

ちなみに,このObjectIdのUnix時間部分

52fcebd1(16進数) → 1392307153(10進数) → 2014/2/14 01:00:10

ちゃんとUnix時間になっていることがわかる.

マシンIDの仕組み

なんとなくユニークになるっぽいっていうのはわかった.

しかし,やはり疑問に思うのは,マシンIDって何だよ!って所だと思う.

Google Group-mongodb-user ›How to get machine id

で,このメーリングリストの投稿によると,マシンIDの生成はクライアント依存らしい.だけど,だいたいのクライアントではhostnameで決めてるらしい.

ということでpymongoの実装部分をみてみた.

ObjectIdの生成部分- pymongo

MachineIdの取得 - pymongo

マシンIDの生成にはhostnameを使っている...マシンIDに関して言えばユニークじゃないんだね.

もっとユニークなものを使ってマシンIDは生成されると思ってた...

だって,同じhostname持ってるマシンあるよ.ubuntuとかさ.

以下の2つはhostnameが同じ別のマシンでpymongoを使って生成したObejectId

確かにマシンIDは同じだ.

52fcf47b 1d41c8 2e90 e33611
52fcf461 1d41c8 75fe aff3e3

ただし,純正のmongoクライアントはhostnameでマシンIDを生成している訳では無いようで,マシンIDは異なるものになっていた.

ObjectIdは本当にユニークなのか?

ObjectIdの構成要素となっている4つの要素

  • Unix時間

  • マシンID

  • プロセスID

  • カウンタ

はそれぞれは十分重複する可能性があることがわかった.

しかし,これらが組み合わさるとユニークだと言える.

同一のmongoクライアントのプロセスではUnix時間カウンタがあるので重複することは不可能.

同一マシン上ではmongoクライアントのプロセスIDが異なるので不可能.

別マシン上ではマシンIDが異なるので不可能(hostnameが同じならば可能性がある).

重複するIDを生成するためには以下の条件が必要になる.

  • 同じ時刻の1秒間で,

  • 同じhostnameを持つマシンで,

  • 同じプロセスIDを持つmongoクライアントのプロセスを起動し,

  • 乱数を調整してカウンタをあわせる.

普通に使っている分にはユニークですね.

普通に使いましょう.

Ubuntu Firewall でudpを許可する

fluentdのforward input plugin を使用する際,受け取り側のホストでIP制限をしている場合,ポートを開放してあげる必要があります.

fluentdのforward input plugin はイベントの転送をUDPで行います.


今日,fluentdの設定をしていて,うまくフォワードできていないなーと思っていたら,

ファイヤーフォールでTCPしか許可しておらず,UDPは許可していなかったため,受け取り側のホストで受け取ることができていませんでした.

以下のコマンドでUbuntu FirewallではUDPを許可することができました.

$ sudo ufw allow proto udp  from xxx.xxx.xxx.xxx to any port 24224