概要
以前
という記事を書きましたが、また別のケースでハマった話を書きます。
今回はACLを有効にしたConsulクラスタのサーバをアップグレードしようとしたら
Error joining address 'xxx.xxx.xxx.xxx': Unexpected response code: 403 (ACL not found) Failed to join any nodes.
と出てクラスタに登録されなくなった、という問題です。
環境
- Consul 1.5.0
問題
現象
consul join
に限らず、どのconsul
系コマンドを打っても以下のエラーが発生します。
Error joining address 'xxx.xxx.xxx.xxx': Unexpected response code: 403 (ACL not found) Failed to join any nodes.
master tokenを使用しても上記エラーが発生します。
再現方法
特定のconsulサーバで以下の手順を踏みます。
もしくは既存のサーバにconsulサーバを追加でjoinする、でもいいです。
consul leave
でgracefulにクラスタから外す- インスタンス再作成
- ACLが有効なconfigで起動
consul join xxx.xxx.xxx.xxx
でクラスタに登録 ←ここでコケるその時のconfig.json
問題が発生したときのconfig.jsonは以下です。
特別おかしそうなところは見当たりませんでした。
{ "server": true, "primary_datacenter": "dc1", "node_name": "${NODE_NAME}", "acl": { "enabled": true, "default_policy": "deny", "down_policy": "extend-cache", "tokens": { "agent": "${AGENT_TOKEN}" } }, "data_dir": "/var/consul/data", "log_level": "INFO", "enable_syslog": true, "client_addr": "127.0.0.1", "bootstrap_expect": 3 }
追加方法も
Adding & Removing Servers | Consul - HashiCorp Learn
の通りで問題なさそうに見えます。
原因
ACLが有効な場合、リーダーがいないとACLの情報が引っ張れず前述のACL not found
が発生します。
しかしリーダーはクラスタにjoinしてからでないと分かりません。
なのでクラスタに登録してからACLを有効にする必要があります。
対応方法
起動後にjoinすることがNGなので、起動時にjoinする設定にしておきます。
先程の設定にretry_join
を付けます。
{ "server": true, "primary_datacenter": "dc1", "node_name": "${NODE_NAME}", "acl": { "enabled": true, "default_policy": "deny", "down_policy": "extend-cache", "tokens": { "agent": "${AGENT_TOKEN}" } }, "retry_join": ["${JOIN_ADDR}"], "data_dir": "/var/consul/data", "log_level": "INFO", "enable_syslog": true, "client_addr": "127.0.0.1", "bootstrap_expect": 3 }
もしくは起動時のコマンドを
$ consul agent -server -retry-join xxx.xxx.xxx.xxx
のようにしておけばACLが有効な設定でも問題ありません。
まとめ
ACLが無効であれば
Adding & Removing Servers | Consul - HashiCorp Learn
の通り後からconsul join
でも問題ありません。
しかしACLが有効な場合、joinは起動時に行うようにしましょう。
間違っても後からjoinすれば良いや、と考えないでください。