Carpe Diem

備忘録

ConsulのACLでハマった話2

概要

以前

christina04.hatenablog.com

という記事を書きましたが、また別のケースでハマった話を書きます。

今回は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する、でもいいです。

  1. consul leaveでgracefulにクラスタから外す
  2. インスタンス再作成
  3. ACLが有効なconfigで起動
  4. 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すれば良いや、と考えないでください。

ソース