HashiCorpのnomadのチュートリアルを実施するときの注意点

# HashiCorpのnomadのチュートリアルを実施するときの注意点

全国3000万のnomadフリークの皆様。やっぱり正月は、nomadでも素振りしようと思いますよね。
nomadの素振りを実施しました。チュートリアル自体はとても簡単で、nomadのシンプルさ、それでいてローリングアップデートもしてくれる気の利いている感じを体験していただけると思います。

是非、次のチュートリアルをやってみてください！

[Nomad / Getting Started](https://www.nomadproject.io/intro/getting-started/install.html)

チュートリアルはシンプルで、VagrantさえインストールされていたらUbuntu14.04+nomadが起動してくれて、遊べる素晴らしいものですが、しょうもないところで、つまづきポイントがありますので、共有しておきます。

## nomadのチュートリアルの日本語サマリ

読める人は是非上記の英文を読んで楽しんでいただきたいですが、苦手な人ためにサマリだけ書いておきます。Vagrantと、VirtualBoxは起動している前提です。ただし、これはスナップショットですので、将来の変更には追従しませんw
英語版にチャレンジしたい人は、Tips.1まで読み飛ばしてください。

### 1. Vagrantfileの取得

下記のVagrantfileを取得してください。ダウンロードしたら、Tips.1で説明している、Vagrantfileのメモリ増強をしておくのをお勧めします。
[Vagrantfile](https://raw.githubusercontent.com/hashicorp/nomad/master/demo/vagrant/Vagrantfile)
### 2. インスタンスの起動とログイン

多少エラーが出ますが、nomadのチュートリアルという意味では影響ありませんので、無視して、進んでください。

```
$ vagrant up
$ vagrant ssh
vagrant@nomad:~$ 
```

### 3. nomadのAgentの起動

vagrant sshした、ターミナルから、agentを起動します。これで、nomadのサーバとクライアントが両方立ち上がります。

```
vagrant@nomad:~$ sudo nomad agent -dev
```

このターミナルは、このまま置いておいて、別のターミナルから`vagrant ssh`をかけて続行しましょう。
終わらせたいときは`ctr+c`で終了させることができます。

### 3. ジョブの実行

先ほど設定した、nomadのサーバやクライアントは次のコマンドで確認できます。

```
vagrant@nomad:~$ nomad server-members
Name          Addr       Port  Status  Proto  Build     DC   Region
nomad.global  127.0.0.1  4648  alive   2      0.1.0dev  dc1  global
```

さて、とうとうジョブを実行します。

Jobの実行は、[Document](https://www.nomadproject.io/docs/jobspec/)に記述されたJSON形式のファイルを実行するとよいです。このひな形を生成します。

```
vagrant@nomad:~$ nomad init
```

これで、example.nomadというジョブのJSONファイルが作成されます。さて、これを実行してみましょう。

```
vagrant@nomad:~$ nomad run example.nomad
==> Monitoring evaluation "3d823c52-929a-fa8b-c50d-1ac4d00cf6b7"
    Evaluation triggered by job "example"
    Allocation "85b839d7-f67a-72a4-5a13-104020ae4807" created: node "2512929f-5b7c-a959-dfd9-bf8a8eb022a6", group "cache"
    Evaluation status changed: "pending" -> "complete"
==> Evaluation "3d823c52-929a-fa8b-c50d-1ac4d00cf6b7" finished with status "complete"
```

これが実行後のステータスです。ジョブが正しく実行されているのがわかります。initで作ったサンプルではredisが実行されるようになっています。

```
vagrant@nomad:~$ nomad status example
ID          = example
Name        = example
Type        = service
Priority    = 50
Datacenters = dc1
Status      = <none>

==> Evaluations
ID                                    Priority  TriggeredBy   Status
3d823c52-929a-fa8b-c50d-1ac4d00cf6b7  50        job-register  complete

==> Allocations
ID                                    EvalID                                NodeID                                TaskGroup  Desired  Status
85b839d7-f67a-72a4-5a13-104020ae4807  3d823c52-929a-fa8b-c50d-1ac4d00cf6b7  2512929f-5b7c-a959-dfd9-bf8a8eb022a6  cache      run      running
```

チュートリアルでは、ここからさらにジョブの数を増やしたり、少なくしたり、クラスターを実際に組んでみたりと面白いところが続きます。是非続きはWEBで。Mesosで同じような事を実施したときよりもかなり軽快にできますね！

では、素晴らしいチュートリアルをスムースに実行するための、Tipsをどうぞ

## Tips.1: メモリが初期設定では動かない

チュートリアルの通りの、Vagrantファイルを使うと、メモリ不足が発生します。下記の部分を変更してみてください。

Vagrantfile

```
  # Increase memory for Virtualbox
  config.vm.provider "virtualbox" do |vb|
        vb.memory = "2048"
  end
```

これぐらいに増やしておけば問題ありません。

## Tips.2: Vagrantを再起動すると、タスク実行がfailになる

上記の設定を実施すると、Vagrantで作成したインスタンスは再起動する必要が生じます。再起動をすると、今まで動いていたタスク実行が動かなくなります。`nomad run example.nomad`などを実行後にステータスを見ると、失敗するようになります。

```
vagrant@nomad:~$ nomad status example
 : 中略
==> Allocations
ID                                    EvalID                                NodeID                                TaskGroup  Desired  Status
6a4a97f0-41c5-6383-089f-79cbe2a75bf6  530a2b68-e169-1732-3742-e1b44ff42939  ac897bc7-c986-1224-cf64-b8eb773d4122  cache      run      failed
946739fb-f2ff-2b85-09f8-185b79ff5a7e  530a2b68-e169-1732-3742-e1b44ff42939  ac897bc7-c986-1224-cf64-b8eb773d4122  cache      run      failed
fcad4d12-ab25-d915-54c5-a09571b67434  530a2b68-e169-1732-3742-e1b44ff42939  ac897bc7-c986-1224-cf64-b8eb773d4122  cache      run      failed
```

これは`sudo nomad agent -dev`のログを見ればすぐわかるのですが、原因は、iptablesがクリアされてしまうことにあります。

```
vagrant@nomad:~$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination     
```

もともとは、Docker用の設定が入るのですが、これがクリアされているようです。このインスタンスはvagrantのdocker provisionerを使って、dockerをインストール・設定していますが、iptablesの設定がインスタンスの再起動でクリアされます。

```
vagrant@nomad:~$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain DOCKER (1 references)
target     prot opt source               destination  
```

これは、Ubuntu14.04のiptablesを設定する`/etc/iptables/`の下にある、`rules.v4`などにクリアの設定が入っているため、起動時にこれが自動的に読み込まれるためです。

/etc/iptables/rules.v4

```
# Generated by iptables-save v1.4.21 on Tue Dec  1 17:19:05 2015
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
# Completed on Tue Dec  1 17:19:05 2015
```

対策としては簡単で、最初に起動して、iptablesの変更が正しくされているときにの次のコマンドを打っておけば、iptablesの内容が
保存されるので、何回再起動しても大丈夫になります。このコマンドを発行すると、上記の`/etc/iptables/rules.v4`と`/etc/iptables/rules.v6`
に内容が反映されます。

```
vagrant@nomad:~$ sudo invoke-rc.d iptables-persistent save
```
参考 [How To Set Up a Firewall Using Iptables on Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-using-iptables-on-ubuntu-14-04)

ではよいnomadライフを。

# 補足

私は上記の原因と回避策に関しては、すぐにわかったのですが、再起動するとiptablesがクリアされる件は手間取りました。
というのも、Ubuntuの[IptablesHowTo](https://help.ubuntu.com/community/IptablesHowTo)を読むと、`/etc/network/if-post-down`に内容が反映されます。設定を保存するスクリプトを書いて、`/etc/network/if-pre-up.d`に読み込むスクリプトを書く方法が出てきます。

これらのファイルはちゃんと動作しますし、`/etc/init.d/networking restart`などを実行して、ネットワークを再起動するとそのときはちゃんと有効になります。

問題は、上記で記述したとおりですが`/etc/iptables/rules.v4`がこのBOXではデフォルトでクリアされるような設定ファイルになっているため、このような結果になってしまいます。

インターネットで検索するとこの方法がたくさん出てきますので、ちゃんと、Ubuntu14.04での方法を調査しましょう。Ubuntuは、バージョンによって操作方法が変わる場合も多いですので、何かを調べるときはバージョン指定で調べるべきというのが今回の学びでした。

以上です