0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【検証】SSM 管理下 EC2 上で Nomad / Consul / Vault を構築し Cluster Join まで確認してみた

0
Last updated at Posted at 2026-01-19

はじめに

本記事は、以下の記事の 続編(追記) です:

🔗 https://qiita.com/Raymo-L/items/e8bb79bd9ccb8be49895

前編では、Terraform により構築した VPC / EC2 環境に対して、
踏み台サーバを用いず、SSM Session Manager 経由のみで EC2 に接続可能な状態を構築するところまでを扱いました。

本記事ではその延長として、

・EC2 を SSH を使わず SSM 管理下で運用するために必要だった修正点
・Nomad / Consul / Vault を server / client 構成で導入
・Consul / Nomad の Cluster Join が成立するところまでの確認
・検証過程で 実際に詰まったポイントと、その切り分け

を、実作業ベースで整理します。

検証のゴールと前提

検証のゴール

今回の検証におけるゴールは以下の 2 点です:

  1. EC2 を SSH なし・SSM 接続のみで管理できる状態にする
  2. Nomad / Consul / Vault を導入し、
    server / client 間で Cluster Join が成立することを確認する

本検証では、アプリケーション実行基盤としての 前提となる基盤レイヤ(SSM 管理下 EC2 上での Nomad / Consul の Cluster Join) が成立するかどうかの確認を主目的としています。

前提条件

・Terraform により VPC / Subnet / EC2 / Security Group を構築済み
・EC2 は Private Subnet に配置
・インターネット Gateway / NAT Gateway は 未使用
・OS は Amazon Linux 系
・EC2 へのログインは SSM Session Manager のみ

構成概要

構成イメージ(検証時点)

EC2 × 3 台
 ・server × 1
 ・client × 2

・すべて Private Subnet
・接続は SSM のみ
・Nomad / Consul / Vault は EC2 へ直接インストール

[ SSM ]
   |
[ server ]  <--->  [ client0 ]
      \           /
        <------> [ client1 ]

EC2 を SSM 管理下にするための修正点

前編の時点で SSM 接続自体は成功していたものの、
検証を進めるにつれて以下の課題が明確になりました

・SSM 接続はできるが、資材取得・検証が途中で詰まる
・Nomad Job 実行時に image pull が失敗する
・外部への通信が成立しない

原因

・EC2 は Private Subnet に配置されている
・NAT Gateway は存在しない
・SSM 接続に必要な VPC Endpoint のみが存在していた

実際に利用した VPC Endpoint

サービス 用途
ssm SSM Session Manager
ssmmessages SSM 通信
ec2messages SSM 通信
s3 S3からの資材取得

これらは「SSM 接続できた=完成」ではなく、
“運用できる状態”とは別物であることを示していました。

学び

・SSM 接続に必要な Endpoint と、実運用に必要な Endpoint は違う
・特に S3 Endpoint は後から必ず欲しくなる

セキュリティグループ設計の方針

今回の検証で 最も時間を使ったのが Security Group (SG) 周りの設計でした。

当初の誤解:

・server 側に ingress を許可すれば通信できる
・client 側は egress all にしておけば問題ない

実際に発生した問題:

・Consul / Nomad が Join しない
・一方向では通信が成立しているように見えるが、反対方向からは見えない
・TCP のみ許可しており、UDP が不足していた

※Consul 公式文献にて、ポートリファレンスでは、同じポート番号でも TCP と UDP の双方が必要でした。
🔗 https://developer.hashicorp.com/consul/docs/reference/architecture/ports

つまりサーバ側の設定だけ開けても、UDP を使う gossip まで開いていないと他のノードとの通信が成立しない仕組みとなっています。

プロトコル Port 用途
TCP 8300 Consul サーバ RPC(サーバ ↔ サーバ・クライアント ↔ サーバ)
TCP/UDP 8301 LAN gossip(サーバ ↔ クライアント ↔ サーバ)
TCP/UDP 8302 WAN gossip
TCP 8500 HTTP API
TCP/UDP 8600 DNS

特に 8301 は TCP だけでなく UDP も必要 であり、
Consul の Cluster Join やノード間の クラスタ健全性情報(メンバーの alive / failed 状態など) の共有に利用されています。

実際に必要だった対応:

・server ↔ client の 双方向通信
・TCP / UDP の 両方を明示的に許可
・同一 SG 内通信(self)も発生するため考慮が必要

対応として、
・server ↔ client の 双方向通信
・TCP / UDP の 両方を明示的に許可
・同一 SG 内通信(self)も発生するため考慮が必要
などの修正を行いました。

Nomad / Consul / Vault の導入

詳細な手順は割愛しますが、導入の考え方は以下の通りです。

共通作業

・バイナリを S3 経由で配置
・/usr/local/bin に配置
・systemd unit ファイルを作成し、サービスとして起動

server 側

Consul:server モード
Nomad:server モード
Vault:スタンドアロン構成(Cluster Join 対象外)

client 側

Consul:client モード
Nomad:client モード

詰まったポイントと切り分け

① Consul / Nomad が Join しない

原因

・SG の片方向通信のみ許可していた
・TCP のみ許可し、UDP を考慮していなかった

対応

・gossip 通信に必要な TCP / UDP の両方を許可
・server ↔ client の双方向通信を定義

② Nomad client が起動しない

エラー内容
failed creating alloc mounts dir: permission denied

Nomad service は起動するものの、client が ready にならない状態でした。

原因

・Nomad は systemd 上で nomad ユーザーとして実行される
・/var/lib/alloc_mounts の所有者・権限不足

対応
sudo mkdir -p /var/lib/alloc_mounts
sudo chown nomad:nomad /var/lib/alloc_mounts

Nomad は systemd 上では nomad ユーザーで動くことを見落としていた。

Consul Cluster Join 確認

確認時に混乱した点

Consul members が片側しか見えない:
・client 側では server が見える
・server 側では client が見えない

原因

・gossip 通信(8301/TCP/UDP)の片方向不足
・SG の定義が抜けていた

確認コマンド

consul members

最終的な確認結果

server   alive
client0 alive
client1 alive

server / client 双方から同じ結果が確認できました。

Nomad Cluster Join の確認

server 側確認

nomad server status

Leader が存在することを確認

nomad node status
client0: ready
client1: ready

Job 実行による最終確認

検証用として hello.nomad を実行しました。

hello.nomad について

Nomad クラスタに client ノードが正しく参加し、
server からスケジューリングされたタスクが client 側で実行されることを確認するため、
exec ドライバを用いた最小構成のジョブとして使用しました。

job "hello" {
  datacenters = ["dc1"]

  group "example" {
    task "hello" {
      driver = "exec"

      config {
        command = "sh"
        args    = ["-c", "while true; do echo Hello Nomad; sleep 5; done"]
      }
    }
  }
}
nomad job run hello.nomad
nomad alloc logs <alloc-id>
Hello Nomad

client ノードでジョブが実行されることを確認しました
Nomad / Consul の連携が成立していることを確認しました

検証結果まとめ

本検証では、以下を満たした時点で Cluster Join が成立したと判断しました。
・Consul members が server / client 双方で一致する
・Nomad server が leader として動作している
・Nomad client が ready 状態になる
・client ノード上でジョブが実行される

項目 結果
SSM 管理下 EC2 接続 OK
Consul Cluster Join OK
Nomad Cluster Join OK
server / client 分離 OK
ジョブ実行 OK

補足:Nomad と Consul の連携について

本検証では、Nomad および Consul はそれぞれ server / client 構成で起動し、
Cluster Join が成立することまでを確認しています。

一方で、Nomad の設定ファイルやジョブ定義において
Consul への service 登録(service stanza)を用いた連携設定は 行っていません。

そのため、本記事時点では
Nomad と Consul はそれぞれ独立したクラスタとして動作している状態 であり、
アプリケーションのサービス検出やヘルスチェック連携までは未実施です。

振り返り・反省点

・HashiCorp 製品は通信仕様の理解がとても重要
・SG をとりあえず開けるような構成は後で必ず詰まる。SG設計の見積もりは慎重に。
・Nomad client は実行ユーザー視点でのディレクトリ設計が必須
・SSM + Private 構成は強力だが、Endpoint 設計を忘れると詰みが発生する
・VPC Endpoint を「SSM 用」としか考えていなかった

次に同じようなことを実施するなら

・SG Rule は最初から通信表を書いて設計
・VPC Endpoint は「後で足す前提」で余裕を持つ

おわりに

前編では SSM 接続、本記事では Cluster Join までを扱いました。
Terraform × SSM × Nomad / Consul というPrivate 構成特有の難しさが多い検証でしたが、
その分、実運用を見据えた多くの学びを得ることができました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?