「CoreOS + Vagrant に etcd を使ってクラスタを構築する」を試してみた

# 2014-04-12追記：元記事はうまく行かなかった報告ですが、うまく行った報告を別記事に書きましたのでそちらをご参照ください
[Vagrant上のCoreOSでetcdを動かして別の3台でクラスタリングしてみた - Qiita](http://qiita.com/hnakamur/items/bccac980bef68642a814)

# ここから以下は元の記事

[CoreOS + Vagrant に etcd を使ってクラスタを構築する - Qiita](http://qiita.com/voluntas/items/fb4174b4327c539e1fe7)を試してみたメモです。@voluntas さん、CoreOSの一連の記事ありがとうございます！CoreOSやetcdは気になっていたのでありがたいです。

この記事は、よくわからないまま試してみて一旦動いたみたい、でもまた動かなくなった、という報告です。あまり参考にならない気もしますが、一応情報共有ということで。他の方が元記事を読んで追試されるのを期待しています。

# 確認した環境

* OS X 10.8.5
* VirtualBox 4.3.10
* vagrant 1.5.1
* go 1.2.1 (homebrewでbottled版をインストール)

# 試行錯誤したメモ

よくわかってない状態でとりあえず試してみたメモです。

## 172.12.8.1のネットワークについて

172.12.8.1のネットワークは最初はifconfigしても見当たりませんでした。私の環境ではvboxnet0〜2までしかなく、そのどれもIPアドレスはついていませんでした。

https://github.com/coreos/coreos-vagrant.git
のVagrantfileでvagrant upすると作られるので、etcdを172.12.8.1のアドレスで起動する前に、vagrant upする必要がありました。

VagrantfileのNUM_INSTANCESの行を

```
NUM_INSTANCES = 3
```

と1から3に変えてからvagrant upしました。

ちなみにVagrantfileの
https://github.com/coreos/coreos-vagrant/blob/26aad5eea7e61fd5f434340f1ad5ae38b1e5692a/Vagrantfile#L33-L34
にこのアドレスが指定されています。

```
      ip = "172.12.8.#{i+100}"
      config.vm.network :private_network, ip: ip
```

一度vagrant upしてしまえば、その後vagrant haltで止めた後でも、ifconfigで172.17.8.1のアドレスが表示されました。ちなみに私の環境ではvboxnet3になっていました。

```shell-session
$ ifconfig
(...snip...)
vboxnet0: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether 0a:00:27:00:00:00
vboxnet1: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether 0a:00:27:00:00:01
vboxnet2: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether 0a:00:27:00:00:02
vboxnet3: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether 0a:00:27:00:00:03
	inet 172.12.8.1 netmask 0xffffff00 broadcast 172.12.8.255
```

が、vagrantでcoreosを起動していない状態でetcdを172.12.8.1:4001のアドレス指定で起動しても、127.0.0.1:7001にされてしまいました。

```shell-session
$ bin/etcd -addr 172.12.8.1:4001 -v
[etcd] Mar 31 02:59:57.748 WARNING   | Using the directory nakamura-mac.local.etcd as the etcd curation directory because a directory was not specified.
[etcd] Mar 31 02:59:57.748 INFO      | etcd server [name nakamura-mac.local, listen on :4001, advertised url http://172.12.8.1:4001]
[etcd] Mar 31 02:59:57.749 DEBUG     | nakamura-mac.local finished load snapshot
[etcd] Mar 31 02:59:57.752 DEBUG     | Register: nakamura-mac.local
[etcd] Mar 31 02:59:57.756 INFO      | URLs: /_etcd/machines:  / nakamura-mac.local (http://127.0.0.1:7001)
[etcd] Mar 31 02:59:57.756 DEBUG     | Entire cluster is down! %v will restart the cluster.nakamura-mac.local
[etcd] Mar 31 02:59:57.756 INFO      | nakamura-mac.local: state changed from 'initialized' to 'follower'.
[etcd] Mar 31 02:59:57.756 INFO      | peer server [name nakamura-mac.local, listen on :7001, advertised url http://127.0.0.1:7001]
```

別ターミナルでcurlを実行してetcdのバージョンを確認してみたら、「2」となりましたがよくわかりません。

```shell-session
$ curl http://172.12.8.1:4001/version
^C (←反応がないのでCtrl-Cで止めた)
$ curl http://127.0.0.1:7001/version
2
```

なお、この時点では
user-dataファイルはuser-data.sampleからコピーしたまま変更なしで、etcdのdiscoveryの行はコメントアウトされた状態でした。その後その行を

```text:user-data
      discovery: http://172.12.8.1:4001/v2/keys/machines
```

と書き換えて、vagrant upした後にetcdを172.12.8.1:4001のアドレス指定で起動してみました。

```shell-session
$ bin/etcd -addr 172.12.8.1:4001 -v
[etcd] Mar 31 03:06:41.899 WARNING   | Using the directory nakamura-mac.local.etcd as the etcd curation directory because a directory was not specified.
[etcd] Mar 31 03:06:41.899 INFO      | etcd server [name nakamura-mac.local, listen on :4001, advertised url http://172.12.8.1:4001]
[etcd] Mar 31 03:06:41.900 DEBUG     | nakamura-mac.local finished load snapshot
[etcd] Mar 31 03:06:41.902 DEBUG     | Register: nakamura-mac.local
[etcd] Mar 31 03:06:41.912 INFO      | URLs: /_etcd/machines:  / nakamura-mac.local (http://127.0.0.1:7001)
[etcd] Mar 31 03:06:41.912 DEBUG     | Entire cluster is down! %v will restart the cluster.nakamura-mac.local
[etcd] Mar 31 03:06:41.912 INFO      | nakamura-mac.local: state changed from 'initialized' to 'follower'.
[etcd] Mar 31 03:06:41.912 INFO      | peer server [name nakamura-mac.local, listen on :7001, advertised url http://127.0.0.1:7001]
[etcd] Mar 31 03:06:42.128 INFO      | nakamura-mac.local: state changed from 'follower' to 'candidate'.
[etcd] Mar 31 03:06:42.128 INFO      | nakamura-mac.local: state changed from 'candidate' to 'leader'.
[etcd] Mar 31 03:06:42.128 INFO      | nakamura-mac.local: leader changed from '' to 'nakamura-mac.local'.
```

起動ログを見ると http://127.0.0.1:7001 と出るところは同じなのですが、別ターミナルからcurlでetcdのバージョン確認をしてみると今度は良さそうでした。

```shell-session
$ curl http://172.12.8.1:4001/version
etcd 0.3.0+git
```

## fleetctlの出力結果について

```shell-session
vagrant ssh core-01
```

でログインして下記のコマンドを実行してみるとMACHINEは1つしか表示されませんでした。

```shell-session
core@core-01 ~ $ fleetctl list-machines -l
MACHINE					IP		METADATA
f5ba5325-00b6-4417-aaf9-752521f6e2ff	172.12.8.101	-
```

別ターミナルでcore-02にログインして同じコマンドを実行してみると、こちらは0件です。

```shell-session
core@core-02 ~ $ fleetctl list-machines -l
MACHINE	IP	METADATA
```

core-03では1件でした。

```shell-session
core@core-03 ~ $ fleetctl list-machines -l
MACHINE					IP		METADATA
5fd5b527-5a60-4c66-89b7-38ab8d7e8aac	172.12.8.103	-
```

環境が収束するのに少し時間がかかるのかな？と思って、この後再度core-02でfleetctl list-machines -lを再度実行してみましたが0件のままでした。

うーん、よくわからん、ということで、etcdを起動したまま、vagrant reloadしてcore-01〜03を再起動してみました。その後3台でそれぞれ上記のコマンドを実行してみると以下のようになりました。

```shell-session
core@core-01 ~ $ fleetctl list-machines -l
MACHINE					IP		METADATA
b1a72fae-7a15-449e-a1b1-abdf5ceeec05	172.12.8.101	-
```

```shell-session
core@core-02 ~ $ fleetctl list-machines -l
MACHINE					IP		METADATA
6d37f2e2-900f-4e4a-81c6-c4c435ffcc18	172.12.8.102	-
```

```shell-session
core@core-03 ~ $ fleetctl list-machines -l
MACHINE	IP	METADATA
```

今度は、core-01とcore-02が1台でcore-03が0台になってしまいました。3台表示されるのが期待される結果なので、いずれにしてもうまくクラスタリングできてないようです。

vagrant reloadしたときにログに以下のように出ていたので、プロビジョニングで何か設定をしているようです。

```shell-session
==> core-03: VM already provisioned. Run `vagrant provision` or use `--provision` to force it
```

と思ってVagrantfileを見ると以下の様な記述がありました。

```text:https://github.com/coreos/coreos-vagrant/blob/26aad5eea7e61fd5f434340f1ad5ae38b1e5692a/Vagrantfile#L39-L42
      if File.exist?(CLOUD_CONFIG_PATH)
        config.vm.provision :file, :source => "#{CLOUD_CONFIG_PATH}", :destination => "/tmp/user-data"
        config.vm.provision :shell, :inline => "mkdir -p /var/lib/coreos-vagrant && mv /tmp/user-data /var/lib/coreos-vagrant", :privileged => true
      end
```

そこで--provision付きで再度vagrant reloadしてみました。

```shell-session
$ vagrant reload --provision
```

しかし、core-01にログインしてまたfleetctlで確認してみると0台とおかしいままです。

```shell-session
core@core-01 ~ $ fleetctl list-machines -l
MACHINE	IP	METADATA
```

そこで、vagrant destroyでVMを一旦破棄して、vagrant upで作り直してみました。

その後core-01にログインしてfleetctlで確認してみると、今度は3台表示されました！core-02、core-03でも同じ結果でした。

```shell-session
core@core-01 ~ $ fleetctl list-machines -l
MACHINE					IP		METADATA
5586647b-207b-4396-8f30-63e26e50a7be	172.12.8.101	-
0cb4a815-0a23-4639-bdce-396d6ac5ebbd	172.12.8.102	-
3775ead9-486c-4154-a1ee-ee0e69136a0a	172.12.8.103	-
```

が、etcdは起動したまま、vagrant reloadしてみると今度はcore-01〜03でfleetctl list-machines -lの結果が全て0件になってしまいました。

etcdのログに

```
[etcd] Mar 31 03:58:06.781 DEBUG     | Key already exists
[etcd] Mar 31 03:58:06.782 DEBUG     | Key already exists
[etcd] Mar 31 03:58:06.785 DEBUG     | Key already exists
```

とか

```
[etcd] Mar 31 04:01:57.674 DEBUG     | [recv] PUT http://172.12.8.1:4001 /v2/keys/machines/d805794c8ea746128e08c738b6431310 [172.12.8.101:53750]
[etcd] Mar 31 04:01:57.675 DEBUG     | [recv] PUT http://172.12.8.1:4001 /v2/keys/machines/_state [172.12.8.101:53750]
[etcd] Mar 31 04:01:57.675 DEBUG     | Key already exists
[etcd] Mar 31 04:01:57.675 DEBUG     | Return error: Key already exists
```

とか出ていたので、なにかうまく行ってないようです。

試行錯誤しているうちに、vagrant haltでVMを止めた状態でetcdを一旦止めて起動しても http://172.12.8.1:4001/ で稼働できるようになっていました（別ターミナルでcurlでこのアドレスにアクセスしてバージョン確認が正しく出来ました）

```shell-session
$ curl http://172.12.8.1:4001/version
etcd 0.3.0+git
```

vagrantのcoreosは止めた状態でuser-dataのdiscoveryに書いたURLにcurlでアクセスしてみると、以下の様な結果になりました。valueのIPアドレスが同じものが重複しているのが問題ないのか気になりますがよくわかりません。

```
$ curl -s http://172.12.8.1:4001/v2/keys/machines | jq .
{
  "node": {
    "createdIndex": 3,
    "modifiedIndex": 3,
    "nodes": [
      {
        "createdIndex": 7,
        "modifiedIndex": 7,
        "ttl": 603370,
        "expiration": "2014-04-07T03:53:20.3276731+09:00",
        "value": "http://172.12.8.101:7001",
        "key": "/machines/1508d424a7474c9e9614b65812aad9d7"
      },
      {
        "createdIndex": 5,
        "modifiedIndex": 5,
        "ttl": 602555,
        "expiration": "2014-04-07T03:39:45.628778729+09:00",
        "value": "http://172.12.8.102:7001",
        "key": "/machines/538f8ec4679f4af5b5de7f3b8d2f21d4"
      },
      {
        "createdIndex": 6,
        "modifiedIndex": 6,
        "ttl": 602578,
        "expiration": "2014-04-07T03:40:08.544650045+09:00",
        "value": "http://172.12.8.103:7001",
        "key": "/machines/92602f13da6a455ab71f599b2d9539fd"
      },
      {
        "createdIndex": 42,
        "modifiedIndex": 42,
        "ttl": 604781,
        "expiration": "2014-04-07T04:16:51.710339854+09:00",
        "value": "http://172.12.8.101:7001",
        "key": "/machines/d805794c8ea746128e08c738b6431310"
      },
      {
        "createdIndex": 43,
        "modifiedIndex": 43,
        "ttl": 604787,
        "expiration": "2014-04-07T04:16:57.172410835+09:00",
        "value": "http://172.12.8.102:7001",
        "key": "/machines/65166b81ef944e18b500a4e04a7e8bd6"
      },
      {
        "createdIndex": 41,
        "modifiedIndex": 41,
        "ttl": 604776,
        "expiration": "2014-04-07T04:16:46.270296638+09:00",
        "value": "http://172.12.8.103:7001",
        "key": "/machines/267296ea07344fe280eb509e26dfed19"
      }
    ],
    "dir": true,
    "key": "/machines"
  },
  "action": "get"
}
```

# 試行錯誤の結果を踏まえて、最短手順を予想してみる

1. https://github.com/coreos/coreos-vagrant.gitをclone
2. VagrantfileでNUM_INSTANCESを3に変える
3. user-data.sampleをuser-dataにコピーしてetcdのdiscoveryの設定を上記のように変更する
4. vagrant upを実行してcore-01〜03を起動し172.12.8.1のアドレスを使えるようにする
5. git@github.com:coreos/etcd.gitをclone
6. etcdをbuildして172.12.8.1:4001のアドレスで実行
7. vagrant destroy -fでcore-01〜03を破棄
8. vagrant upでcore-01〜03を作り直して起動

なお、まっさらな環境でこの手順でOKかは検証していません。

# いつかまた試します

変な時間に寝て夜中に目が覚めたのでちょっと試してみたのですが、そろそろ寝たほうがいいので今回はこのへんにします。
etcdとfleetctlについてもうちょっと理解してから、再度時間をとって試してみたいと思います。ただ、しばらく忙しくなりそうなので、少し先になるかもしれません。