概要
ConsulやVaultのクラスタ構成をしていると
- bind address
- advertise address
という2つのアドレスを設定する必要が出てきます。
この2つをしっかり理解しておかないとクラスタ構成で思わぬ落とし穴にハマったりするので今回はこれを紹介します。
bindアドレスって?
サーバを立ち上げる時に指定するアドレスです。
これまではふわっとした知識で
127.0.0.1
だとローカルからのみアクセスできる0.0.0.0
だとどこからでもアクセスできる- Elasticsearchとかはデフォルトは
127.0.0.1
になってる
くらいの理解でした。
bindアドレスは名札みたいなもの
例えば「田中」という名札をしていれば、「田中」と呼ばれれば返事しますが「山田」と呼ばれても返事しませんよね。
番号②という名札をもらったら、「②番の方〜」と呼ばれれば返事しますが、「①番の方〜」と呼ばれても返事しませんよね。
そんな感じでbindアドレスを127.0.0.1
と設定すれば
$ curl 127.0.0.1
ではレスポンスを返しますが、仮にそのマシンがローカルアドレス192.168.1.10
を持っていたとしても
$ curl 192.168.1.10
ではレスポンスを返しません。
0.0.0.0
はワイルドカード
ただしそれだとどのIPが割り振られるか分からない環境では不便なので、どんな呼ばれ方でも返事するワイルドカード的なアドレスが0.0.0.0
です。
この場合はLANに加えてWANwww.hoge.com
みたいなアドレスを持っていたとしても
$ curl 127.0.0.1 $ curl 192.168.1.10 $ curl www.hoge.com
のどれでもレスポンスを返します。
検証
Goで簡単に検証してみます。
package main import ( "fmt" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, World") } func main() { http.HandleFunc("/", handler) http.ListenAndServe("BIND_ADDR:8080", nil) }
こんな感じのコードを用意して、BIND_ADDR
を変えてみます。
127.0.0.1
まずはループバックアドレスを設定してみます。
$ curl 127.0.0.1:8080 Hello, World
ちゃんと返りますが、
$ curl 192.168.1.22:8080 curl: (52) Empty reply from server
こちらは返りません。
LAN (192.168.xxx.xxx)
では今度はLANアドレス192.168.1.22
を設定してみます。
$ curl 192.168.1.22:8080 Hello, World
今度はこちらが返りますが、
$ curl 127.0.0.1:8080 curl: (7) Failed to connect to 127.0.0.1 port 8080: Connection refused
ループバックアドレスではレスポンスが返りません。
0.0.0.0
最後は0.0.0.0
です。
$ curl 127.0.0.1:8080 Hello, World
$ curl 192.168.1.22:8080 Hello, World
どちらもレスポンスが返ります。
bindまとめ
このようにListenerの名札として機能するのがbindでした。
advertiseアドレスって?
advertiseを辞書で調べると「広告・告知する」といった意味です。
ConsulやVaultは複数のサーバでクラスタを組むため、他のノードに対して「私のIPはこれですよー。このIPでアクセスしてねー」と伝える必要があります。
そのための設定というわけですね。
ちょっと前のクラスタというのは全ノードのリストを固定で持つことでノードを把握し構成されるものでしたが、Consulのように動的にノードが変わるようなクラスタは変化に対応できるようこのような設定になったのだと思われます。
マシンは複数のIPを持つ
なぜ他のノードにIPを指定して教える必要があるのかと言うと、マシンはループバックアドレスの他にNICの数によって複数のIPアドレス(eth0、eth1、ens3などなど)を持つためです。
ノードAからノードBにアクセスしたいのに、当然ながらループバックアドレスでは無理ですし、NICのアドレスによってはAとBのネットワークが繋がってないこともありえます。
なのでAとBがネットワーク的に繋がっているアドレスをadvertiseする必要があります。
具体的な設定
LANで繋がっている場合
ノード | LAN IP |
---|---|
A | 192.168.1.5 |
B | 192.168.1.10 |
であれば、それぞれ
ノード | 設定 |
---|---|
A | consul agent -advertise "192.168.1.5" |
B | consul agent -advertise "192.168.1.10" |
とすればOKです。
LANで繋がっていない場合
この場合WANで繋げる必要があるので、
ノード | WAN IP |
---|---|
A | 13.52.1.5 |
B | 53.108.1.10 |
のようにそれぞれGlobalIPを用意して、
ノード | 設定 |
---|---|
A | consul agent -advertise-wan "13.52.1.5" |
B | consul agent -advertise-wan "53.108.1.10" |
という設定になると思います。
advertiseまとめ
マシンは複数のIPを持つため、クラスタが互いに通信するためのIPを指定するための設定がadvertiseということでした。