Consul

HashiCorp Consul 徹底解説 — サービスメッシュとサービスディスカバリの全容

1. はじめに

1.1 Consul とは何か

HashiCorp Consul は、分散システムにおける サービスディスカバリサービスメッシュKey-Value ストアネットワークインフラの自動化 を統合的に提供するプラットフォームである。2014 年に HashiCorp によって初めてリリースされ、以降マイクロサービスアーキテクチャやクラウドネイティブ環境の普及とともに広く採用されてきた。

従来の静的なインフラストラクチャでは、サービス間の接続情報(IP アドレスやポート番号)は設定ファイルやロードバランサーに静的に記述されていた。しかし、コンテナやオーケストレーションプラットフォーム(Kubernetes、Nomad など)の登場により、サービスインスタンスは動的に生成・破棄されるようになった。この環境下では、サービス間の接続を動的に解決し、安全に通信を行うための仕組みが不可欠である。Consul はまさにこの課題を解決するために設計されている。

1.2 Consul が解決する課題

Consul が対処する主要な課題は以下のとおりである。

課題従来のアプローチConsul によるアプローチ
サービスディスカバリDNS の静的レコード、ロードバランサー動的なサービスカタログと DNS/HTTP API
サービス間通信の安全性VPN、ファイアウォールルールmTLS による自動暗号化(サービスメッシュ)
アクセス制御IP ベースのファイアウォールサービスアイデンティティに基づく Intention
設定の一元管理各サーバーの設定ファイル配布Key-Value ストアと Watch 機能
マルチデータセンター個別管理、手動フェデレーションWAN Gossip による自動フェデレーション
ヘルスチェックNagios、Zabbix 等の外部ツール組み込みヘルスチェック機構

1.3 Consul のコア機能一覧

Consul は以下の主要な機能を提供する。

  1. サービスディスカバリ(Service Discovery): サービスの登録と検出を DNS または HTTP API で行う
  2. サービスメッシュ(Service Mesh / Consul Connect): サイドカープロキシを用いた mTLS 通信とトラフィック管理
  3. Key-Value ストア: 設定情報やフィーチャーフラグの動的管理
  4. ヘルスチェック: サービスとノードの健全性監視
  5. マルチデータセンター対応: 複数データセンターにまたがるサービスメッシュとディスカバリ
  6. ネットワークインフラの自動化: Consul-Terraform-Sync(CTS)によるネットワーク機器設定の動的更新
  7. アクセスコントロール(ACL): きめ細かなアクセス制御ポリシー
  8. Intention(意図ベースのアクセス制御): サービス間の通信許可/拒否をサービス名で定義

1.4 Consul のエディション

Consul は以下のエディションで提供されている。

  • Consul OSS(Community Edition): オープンソース版。基本的なサービスディスカバリ、KV ストア、サービスメッシュ機能を含む
  • Consul Enterprise: OSS に加え、名前空間(Namespace)、管理パーティション(Admin Partition)、冗長化機能、Sentinel ポリシーなどエンタープライズ機能を追加
  • HCP Consul(HashiCorp Cloud Platform): HashiCorp が管理するマネージドサービス版

本記事では、OSS 版の機能を中心に解説しつつ、Enterprise 固有の機能についても適宜言及する。


2. アーキテクチャ概要

2.1 全体構成

Consul のアーキテクチャは、以下の主要コンポーネントで構成される。

┌─────────────────────────────────────────────────────────────┐
│                      データセンター 1                         │
│                                                             │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐                  │
│  │ Server 1 │──│ Server 2 │──│ Server 3 │  ← Raft Consensus│
│  │ (Leader) │  │(Follower)│  │(Follower)│                   │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘                  │
│       │              │              │                        │
│       └──────────────┼──────────────┘                       │
│              LAN Gossip (Serf)                              │
│       ┌──────────────┼──────────────┐                       │
│       │              │              │                        │
│  ┌────┴─────┐  ┌────┴─────┐  ┌────┴─────┐                  │
│  │ Client 1 │  │ Client 2 │  │ Client 3 │  ← Agent         │
│  │┌────────┐│  │┌────────┐│  │┌────────┐│                   │
│  ││Service ││  ││Service ││  ││Service ││                   │
│  ││  A     ││  ││  B     ││  ││  C     ││                   │
│  │└────────┘│  │└────────┘│  │└────────┘│                   │
│  └──────────┘  └──────────┘  └──────────┘                   │
│                                                             │
└──────────────────────┬──────────────────────────────────────┘
                       │ WAN Gossip
┌──────────────────────┴──────────────────────────────────────┐
│                      データセンター 2                         │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐                  │
│  │ Server 1 │──│ Server 2 │──│ Server 3 │                   │
│  └──────────┘  └──────────┘  └──────────┘                   │
│       ...(同様の構成)...                                    │
└─────────────────────────────────────────────────────────────┘

2.2 Agent(エージェント)

Consul の中心的なコンポーネントは Agent であり、クラスタの各ノードで実行されるデーモンプロセスである。Agent には 2 つのモードがある。

Server モード

  • Raft コンセンサスプロトコル に参加し、クラスタの状態を管理する
  • サービスカタログ、KV ストア、ACL ポリシーなどのデータを保持する
  • リーダー選出を行い、書き込み操作はリーダーが処理する
  • 通常、1 データセンターあたり 3 台または 5 台の奇数構成が推奨される
  • クォーラム(過半数)が維持されている限り、障害に耐えられる

Client モード

  • ステートレスで、Server に RPC リクエストを転送する
  • サービスの登録、ヘルスチェックの実行、DNS クエリの処理を行う
  • 各アプリケーションノードに 1 つずつ配置されるのが標準的な構成
  • リソース消費が少なく、軽量に動作する

2.3 コンセンサスプロトコル(Raft)

Consul Server は Raft コンセンサスプロトコル を使用して、クラスタ全体でデータの一貫性を保証する。

Raft プロトコルの主要な特性は以下のとおりである。

  • リーダー選出: リーダーが応答しなくなると、Follower がタイムアウト後に選挙を開始する
  • ログレプリケーション: 書き込み操作はまずリーダーのログに記録され、Follower に複製される
  • コミット: 過半数の Server がログエントリを受け入れると、そのエントリはコミット済みとなる
  • 一貫性保証: デフォルトではリーダーが最新のコミット済みデータを返す(default 一貫性モード)

一貫性モードは 3 種類から選択できる。

モード説明用途
defaultリーダーが最新のコミットデータを返す一般的な読み取り
consistentリーダーがクォーラムを確認してから応答強い一貫性が必要な場合
stale任意の Server が応答(古いデータの可能性あり)高スループットが必要な場合

2.4 Gossip プロトコル(Serf)

Consul は Serf ライブラリを使用して Gossip プロトコルを実装している。Gossip プロトコルはメンバーシップ管理と障害検出に使用される。

LAN Gossip

  • 同一データセンター内の全 Agent(Server + Client)が参加する
  • メンバーシップの管理、障害検出、イベント配信を行う
  • UDP ベースで効率的に動作する(デフォルトポート: 8301)

WAN Gossip

  • 異なるデータセンターの Server 間で使用される
  • データセンター間の接続状態を監視する
  • クロスデータセンターのサービスディスカバリを可能にする(デフォルトポート: 8302)

2.5 ネットワークポート一覧

ポートプロトコル用途
8300TCPServer RPC(Agent 間の RPC 通信)
8301TCP/UDPLAN Serf Gossip
8302TCP/UDPWAN Serf Gossip(Server のみ)
8500TCPHTTP API
8501TCPHTTPS API(TLS 有効時)
8502TCPgRPC API(xDS、サービスメッシュ用)
8503TCPgRPC TLS API
8600TCP/UDPDNS インターフェース

3. サービスディスカバリ

3.1 サービスの登録

設定ファイルによる登録

// /etc/consul.d/web-service.json
{
  "service": {
    "name": "web",
    "tags": ["production", "v1.2.3"],
    "port": 8080,
    "meta": {
      "version": "1.2.3",
      "environment": "production"
    },
    "check": {
      "http": "http://localhost:8080/health",
      "interval": "10s",
      "timeout": "5s",
      "deregister_critical_service_after": "90s"
    }
  }
}

HTTP API による登録

curl -X PUT http://localhost:8500/v1/agent/service/register \
  -d '{
    "Name": "web",
    "ID": "web-1",
    "Tags": ["production", "v1.2.3"],
    "Address": "10.0.1.10",
    "Port": 8080,
    "Meta": { "version": "1.2.3" },
    "Check": {
      "HTTP": "http://10.0.1.10:8080/health",
      "Interval": "10s"
    }
  }'

3.2 サービスの検索

DNS インターフェース

# 基本的なサービスルックアップ
dig @127.0.0.1 -p 8600 web.service.consul

# SRV レコードでポート情報を含むクエリ
dig @127.0.0.1 -p 8600 web.service.consul SRV

# タグでフィルタリング
dig @127.0.0.1 -p 8600 production.web.service.consul

# 別のデータセンターのサービスを検索
dig @127.0.0.1 -p 8600 web.service.dc2.consul

DNS フォーマット: [tag.]<service>.service[.datacenter].consul

HTTP API

curl http://localhost:8500/v1/catalog/services
curl http://localhost:8500/v1/health/service/web?passing=true
curl http://localhost:8500/v1/health/service/web?passing=true&tag=production

Prepared Queries(準備済みクエリ)

curl -X POST http://localhost:8500/v1/query \
  -d '{
    "Name": "web-nearest",
    "Service": {
      "Service": "web",
      "Tags": ["production"],
      "Failover": { "NearestN": 3, "Datacenters": ["dc2", "dc3"] },
      "OnlyPassing": true
    },
    "DNS": { "TTL": "10s" }
  }'

3.3 DNS フォワーディングの設定

dnsmasq

# /etc/dnsmasq.d/consul.conf
server=/consul/127.0.0.1#8600

CoreDNS(Kubernetes 環境)

consul {
    forward . 10.0.0.1:8600 10.0.0.2:8600 10.0.0.3:8600 {
        policy round_robin
    }
}

4. ヘルスチェック

4.1 ヘルスチェックの種類

Consul は多様なヘルスチェック方式をサポートしている。

HTTP チェック

{
  "check": {
    "id": "web-health",
    "name": "Web Health Check",
    "http": "http://localhost:8080/health",
    "method": "GET",
    "interval": "10s",
    "timeout": "5s"
  }
}

TCP チェック

{
  "check": {
    "id": "db-tcp",
    "name": "Database TCP Check",
    "tcp": "localhost:5432",
    "interval": "10s",
    "timeout": "3s"
  }
}

スクリプトチェック

{
  "check": {
    "id": "mem-check",
    "name": "Memory Check",
    "args": ["/usr/local/bin/check_mem.sh", "-limit", "256MB"],
    "interval": "30s",
    "timeout": "10s"
  }
}

終了コード: 0=passing, 1=warning, その他=critical

TTL チェック

{ "check": { "id": "app-ttl", "name": "Application TTL", "ttl": "30s" } }
curl -X PUT http://localhost:8500/v1/agent/check/pass/app-ttl \
  -d '{"Output": "Application healthy, 150 requests/sec"}'

gRPC / Docker / H2 Ping チェック

{ "check": { "grpc": "localhost:50051", "grpc_use_tls": true, "interval": "10s" } }
{ "check": { "docker_container_id": "abc123", "args": ["/health.sh"], "interval": "15s" } }
{ "check": { "h2ping": "localhost:443", "h2ping_use_tls": true, "interval": "10s" } }

4.2 ベストプラクティス

  1. チェック間隔はサービスの重要度に応じて設定(重要: 5-10秒、低優先度: 30-60秒)
  2. タイムアウトは間隔より短く設定
  3. deregister_critical_service_after で長時間異常なサービスを自動登録解除
  4. TTL/スクリプトチェックで診断情報を出力

5. サービスメッシュ(Consul Connect)

5.1 サービスメッシュの概念

サービスメッシュとは、マイクロサービス間の通信を管理するインフラストラクチャレイヤーである。Consul Connect は以下を提供する。

  • mTLS(相互 TLS): サービス間通信の暗号化と相互認証
  • Intention: サービスレベルでの通信許可/拒否
  • トラフィック管理: ルーティング、スプリッティング、リゾルバー
  • 可観測性: メトリクス、トレーシング、ログ

5.2 サイドカープロキシ(Envoy)

{
  "service": {
    "name": "web",
    "port": 8080,
    "connect": {
      "sidecar_service": {
        "proxy": {
          "upstreams": [
            { "destination_name": "api", "local_bind_port": 9191 },
            { "destination_name": "database", "local_bind_port": 5432 }
          ]
        }
      }
    }
  }
}
consul connect envoy -sidecar-for web -admin-bind 0.0.0.0:19000

5.3 証明書管理(CA)

内蔵 CA

connect {
  enabled = true
  ca_config {
    leaf_cert_ttl         = "72h"
    root_cert_ttl         = "87600h"
    intermediate_cert_ttl = "8760h"
    private_key_type      = "ec"
    private_key_bits      = 256
  }
}

Vault CA プロバイダー

connect {
  enabled = true
  ca_provider = "vault"
  ca_config {
    address               = "https://vault.example.com:8200"
    root_pki_path         = "pki-root"
    intermediate_pki_path = "pki-intermediate"
    leaf_cert_ttl         = "72h"
  }
}

5.4 Intention(意図ベースのアクセス制御)

consul intention create -allow web api
consul intention create -deny web database
consul intention list

L7 Intention

Kind = "service-intentions"
Name = "api"
Sources = [
  {
    Name = "web"
    Permissions = [
      {
        Action = "allow"
        HTTP { PathPrefix = "/api/v1/"; Methods = ["GET", "POST"] }
      },
      {
        Action = "deny"
        HTTP { PathPrefix = "/api/admin/" }
      }
    ]
  },
  { Name = "monitoring", Action = "allow" },
  { Name = "*", Action = "deny" }
]

5.5 トラフィック管理

Service Router

Kind = "service-router"
Name = "api"
Routes = [
  {
    Match { HTTP { PathPrefix = "/api/v2/" } }
    Destination { Service = "api"; ServiceSubset = "v2" }
  }
]

Service Splitter

Kind = "service-splitter"
Name = "api"
Splits = [
  { Weight = 90, ServiceSubset = "stable" },
  { Weight = 10, ServiceSubset = "canary" }
]

Service Resolver

Kind = "service-resolver"
Name = "api"
DefaultSubset = "stable"
Subsets = {
  stable = { Filter = "Service.Meta.version == 1.0.0" }
  canary = { Filter = "Service.Meta.version == 2.0.0" }
}
Failover = { "*" = { Datacenters = ["dc2", "dc3"] } }
ConnectTimeout = "5s"
RequestTimeout = "10s"
LoadBalancer = {
  Policy = "ring_hash"
  HashPolicies = [{ Field = "header", FieldValue = "X-User-Id" }]
}

Service Defaults

Kind = "service-defaults"
Name = "api"
Protocol = "http"
UpstreamConfig {
  Defaults {
    ConnectTimeoutMs = 5000
    Limits { MaxConnections = 512; MaxPendingRequests = 512; MaxConcurrentRequests = 512 }
    PassiveHealthCheck { Interval = "30s"; MaxFailures = 10 }
  }
}

Proxy Defaults

Kind = "proxy-defaults"
Name = "global"
Config { protocol = "http"; envoy_prometheus_bind_addr = "0.0.0.0:9102" }
MeshGateway { Mode = "local" }
Expose { Checks = true }
TransparentProxy = { OutboundListenerPort = 15001 }

5.6 Mesh Gateway

データセンター間のサービスメッシュトラフィックを仲介するプロキシ。

consul connect envoy -gateway=mesh -register \
  -service "mesh-gateway" \
  -address "10.0.0.1:8443" \
  -wan-address "198.51.100.1:8443"

モード: local(ローカル GW 経由)、remote(リモート GW に直接)、none(直接接続)

5.7 Transparent Proxy

アプリケーションコード変更なしでサービスメッシュに参加。iptables でトラフィックをサイドカーにリダイレクト。

Kind = "proxy-defaults"
Name = "global"
TransparentProxy = true

6. Key-Value ストア

6.1 基本操作

# 書き込み/読み取り
consul kv put config/database/host 10.0.1.50
consul kv get config/database/host
consul kv get -recurse config/database/
consul kv delete -recurse config/database/

# HTTP API
curl -X PUT http://localhost:8500/v1/kv/config/database/host -d '10.0.1.50'
curl "http://localhost:8500/v1/kv/config/database/?recurse"

# CAS(Compare-And-Swap)
curl -X PUT "http://localhost:8500/v1/kv/config/database/host?cas=12345" -d '10.0.1.51'

6.2 高度な機能

トランザクション

curl -X PUT http://localhost:8500/v1/txn \
  -d '[
    { "KV": { "Verb": "set", "Key": "config/database/host", "Value": "MTAuMC4xLjUw" } },
    { "KV": { "Verb": "check-index", "Key": "config/database/version", "Index": 12345 } }
  ]'

Watch

consul watch -type=keyprefix -prefix=config/database/ /usr/local/bin/update-config.sh

Consul Template

# haproxy.cfg.tpl
backend servers
    balance roundrobin
{{range service "web" "passing"}}
    server {{.Node}} {{.Address}}:{{.Port}} check
{{end}}

セッションとロック

SESSION_ID=$(curl -s -X PUT http://localhost:8500/v1/session/create \
  -d '{"Name":"my-lock","TTL":"30s","LockDelay":"15s","Behavior":"release"}' | jq -r '.ID')
curl -X PUT "http://localhost:8500/v1/kv/locks/my-resource?acquire=$SESSION_ID"
curl -X PUT "http://localhost:8500/v1/kv/locks/my-resource?release=$SESSION_ID"

7. ACL(アクセスコントロールリスト)

7.1 ACL ブートストラップ

consul acl bootstrap

7.2 ポリシーの作成

# policies/web-service.hcl
service "web" { policy = "write" }
service "web-sidecar-proxy" { policy = "write" }
service_prefix "" { policy = "read" }
node_prefix "" { policy = "read" }
key_prefix "config/web/" { policy = "read" }
consul acl policy create -name "web-service-policy" -rules @policies/web-service.hcl
consul acl token create -description "Web service token" -policy-name "web-service-policy"

7.3 ロールとサービスアイデンティティ

consul acl role create -name "web-role" -policy-name "web-service-policy" -service-identity "web:dc1,dc2"
consul acl token create -description "Web service token" -service-identity "web:dc1"

7.4 ACL 設定

acl {
  enabled = true
  default_policy = "deny"
  enable_token_persistence = true
  tokens {
    initial_management = "bootstrap-token-uuid"
    agent = "agent-token-uuid"
  }
}

8. マルチデータセンター

8.1 WAN Federation

# DC1 (Primary)
datacenter = "dc1"
primary_datacenter = "dc1"
server = true
bootstrap_expect = 3
retry_join_wan = ["dc2-server1.example.com"]
# DC2 (Secondary)
datacenter = "dc2"
primary_datacenter = "dc1"
server = true
bootstrap_expect = 3
retry_join_wan = ["dc1-server1.example.com"]

Mesh Gateway WAN Federation

connect {
  enabled = true
  enable_mesh_gateway_wan_federation = true
}

8.2 クロスデータセンターのサービスディスカバリ

dig @127.0.0.1 -p 8600 web.service.dc2.consul
curl "http://localhost:8500/v1/health/service/web?dc=dc2&passing=true"

8.3 Admin Partition(Enterprise のみ)

Kind = "exported-services"
Name = "default"
Partition = "team-a"
Services = [{ Name = "api", Consumers = [{ Partition = "team-b" }] }]

9. Consul と Kubernetes

9.1 Helm Chart によるデプロイ

global:
  name: consul
  datacenter: dc1
  tls: { enabled: true, enableAutoEncrypt: true }
  acls: { manageSystemACLs: true }
  gossipEncryption: { autoGenerate: true }
server:
  replicas: 3
  storage: 10Gi
connectInject:
  enabled: true
  transparentProxy: { defaultEnabled: true }
  metrics: { defaultEnabled: true, defaultPrometheusScrapePort: 20200 }
syncCatalog:
  enabled: true
  toConsul: true
  toK8S: true
meshGateway:
  enabled: true
  replicas: 2
ui:
  enabled: true
helm repo add hashicorp https://helm.releases.hashicorp.com
helm install consul hashicorp/consul --namespace consul --create-namespace --values values.yaml

9.2 Connect Inject(サイドカー注入)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  template:
    metadata:
      annotations:
        consul.hashicorp.com/connect-inject: "true"
        consul.hashicorp.com/connect-service-upstreams: "api:9191,database:5432"
        consul.hashicorp.com/transparent-proxy: "true"
        consul.hashicorp.com/enable-metrics: "true"
    spec:
      containers:
        - name: web
          image: myapp/web:1.2.3
          env:
            - name: API_URL
              value: "http://localhost:9191"

9.3 CRD による Config Entry 管理

apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
  name: api-intentions
spec:
  destination: { name: api }
  sources:
    - name: web
      action: allow
    - name: "*"
      action: deny
---
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceSplitter
metadata:
  name: api
spec:
  splits:
    - weight: 90
      serviceSubset: stable
    - weight: 10
      serviceSubset: canary

9.4 Ingress / Terminating Gateway

# Ingress Gateway
apiVersion: consul.hashicorp.com/v1alpha1
kind: IngressGateway
metadata:
  name: ingress-gateway
spec:
  listeners:
    - port: 8080
      protocol: http
      services:
        - name: web
          hosts: ["web.example.com"]
# Terminating Gateway
apiVersion: consul.hashicorp.com/v1alpha1
kind: TerminatingGateway
metadata:
  name: terminating-gateway
spec:
  services:
    - name: external-database
      caFile: /etc/ssl/certs/ca-certificates.crt

10. Consul Template と envconsul

10.1 Consul Template

template {
  source      = "/etc/consul-template/templates/haproxy.cfg.tpl"
  destination = "/etc/haproxy/haproxy.cfg"
  command     = "systemctl reload haproxy"
  wait { min = "5s"; max = "10s" }
}

10.2 envconsul

envconsul -prefix config/myapp/ -secret database/creds/readonly myapp

11. セキュリティ

11.1 TLS 暗号化

consul tls ca create
consul tls cert create -server -dc dc1
consul tls cert create -client -dc dc1
tls {
  defaults {
    ca_file = "/etc/consul.d/tls/consul-agent-ca.pem"
    cert_file = "/etc/consul.d/tls/dc1-server-consul-0.pem"
    key_file = "/etc/consul.d/tls/dc1-server-consul-0-key.pem"
    verify_incoming = true
    verify_outgoing = true
  }
  internal_rpc { verify_server_hostname = true }
}

11.2 Gossip 暗号化

consul keygen
# キーローテーション(ゼロダウンタイム)
consul keyring -install "new-key"
consul keyring -use "new-key"
consul keyring -remove "old-key"
encrypt = "pUqJrVyVRj5jsiYEkM/tFQYfWyJIv4s3XkvDwy7u5Sk="

12. 可観測性

12.1 メトリクス

telemetry {
  prometheus_retention_time = "60s"
  dogstatsd_addr = "127.0.0.1:8125"
  dogstatsd_tags = ["env:production"]
}

主要メトリクス:

メトリクス説明閾値
consul.raft.leader.lastContactリーダーが Follower に連絡した時間> 200ms
consul.raft.commitTimeコミット時間> 500ms
consul.serf.member.failedメンバー障害> 0

12.2 分散トレーシング / ログ / UI

トレーシング(Zipkin/Jaeger)、JSON ログ、Consul UI(Prometheus/Grafana 連携)をサポート。


13. 運用とベストプラクティス

13.1 本番環境の推奨構成

規模CPUメモリディスクServer 数
小(~500)2 コア4 GB50 GB SSD3
中(~5000)4 コア8 GB100 GB SSD5
大(~50000)8+ コア16+ GB200+ GB NVMe5-7

13.2 バックアップ

consul snapshot save backup-$(date +%Y%m%d-%H%M%S).snap
consul snapshot inspect backup.snap
consul snapshot restore backup.snap

13.3 アップグレード手順

  1. スナップショット取得
  2. Follower Server を1台ずつアップグレード
  3. Leader Server を最後にアップグレード
  4. Client をアップグレード
  5. consul members / consul operator raft list-peers で検証

13.4 トラブルシューティング

consul members && consul members -wan
consul operator raft list-peers
consul monitor -log-level=debug
curl localhost:19000/stats  # Envoy Admin
curl localhost:19000/clusters
dig @127.0.0.1 -p 8600 consul.service.consul

14. Consul-Terraform-Sync(CTS)

Consul のサービスカタログ変更を監視し、Terraform でネットワークインフラを自動更新するツール。

task {
  name = "firewall-update"
  module = "findkim/print/cts"
  condition "services" { names = ["web", "api"] }
}

15. 他のサービスメッシュとの比較

機能ConsulIstioLinkerd
データプレーンEnvoyEnvoylinkerd2-proxy
サービスディスカバリ内蔵K8s APIK8s API
KV ストア内蔵なしなし
マルチプラットフォームVM + K8s + NomadK8s のみK8s のみ
マルチクラスタWAN FederationMulti-PrimaryMulti-Cluster
学習コスト
リソース消費

16. 設計パターン

16.1 ゼロトラスト

Kind = "service-intentions"
Name = "*"
Sources = [{ Name = "*", Action = "deny" }]

16.2 カナリアデプロイ

# リゾルバーでサブセット定義 → スプリッターで比率制御
# Weight: 5 → 10 → 25 → 50 → 100

16.3 ブルーグリーンデプロイ

Kind = "service-resolver"
Name = "api"
DefaultSubset = "blue"
Subsets = {
  blue  = { Filter = "Service.Meta.deployment == blue" }
  green = { Filter = "Service.Meta.deployment == green" }
}
# 切り替え: DefaultSubset を "green" に変更

17. まとめ

17.1 Consul の強み

  1. マルチプラットフォーム対応: VM、コンテナ、Kubernetes、Nomad
  2. マルチデータセンター: ネイティブサポート
  3. 統合的な機能セット: ディスカバリ、KV、メッシュ、ACL
  4. HashiCorp エコシステム: Vault、Nomad、Terraform との統合
  5. 段階的な導入: ディスカバリ → メッシュと段階的に導入可能

17.2 導入の指針

  1. サービスディスカバリ → 2. ヘルスチェック → 3. KV ストア → 4. ACL → 5. サービスメッシュ → 6. トラフィック管理 → 7. マルチデータセンター

17.3 今後の展望

  • Consul Dataplane: Agent レスアーキテクチャ
  • V2 Catalog API: Kubernetes ネイティブなカタログ
  • 簡素化: 設定とデフォルト値の最適化
  • パフォーマンス向上: 大規模環境でのスケーラビリティ

付録 A: CLI コマンドリファレンス

コマンド説明
consul agent -dev開発モードで起動
consul membersクラスタメンバー一覧
consul operator raft list-peersRaft ピア一覧
consul catalog servicesサービス一覧
consul health checks <svc>ヘルスチェック状態
consul kv put/get/deleteKV 操作
consul intention create/listIntention 管理
consul config write/listConfig Entry 管理
consul acl bootstrap/token/policyACL 管理
consul snapshot save/restoreバックアップ/リストア
consul connect envoy -sidecar-for <svc>サイドカー起動
consul monitor -log-level=debugログ監視
consul tls ca createCA 証明書作成
consul keygenGossip 暗号化キー生成

付録 B: Config Entry 一覧

Kind説明
proxy-defaultsグローバルプロキシ設定
service-defaultsサービスデフォルト設定
service-routerHTTP ルーティング
service-splitterトラフィック分割
service-resolverサブセットとフェイルオーバー
service-intentionsL7 アクセス制御
ingress-gatewayIngress Gateway
terminating-gatewayTerminating Gateway
meshメッシュ全体設定
exported-servicesサービスエクスポート

付録 C: 参考リンク