サービスディスカバリー比較:Consul vs etcd vs ZooKeeper でマイクロサービスを管理する
オープンソースラボ編集部 ・ 2026年6月14日
サービスディスカバリー比較:Consul vs etcd vs ZooKeeper でマイクロサービスを管理する
マイクロサービスアーキテクチャでは、動的にスケールするサービスのIP・ポートをコードにハードコードできません。Consul(HashiCorp製・サービスメッシュ統合)・etcd(Kubernetes標準・分散KVS)・ZooKeeper(Java製・元祖)の3つがOSSサービスディスカバリーのデファクトスタンダードです。
サービスディスカバリーが必要な理由
- 動的IP管理: コンテナ・クラウドインスタンスは起動のたびIPが変わるため、サービス名での参照が必要
- ヘルスチェック: 障害サービスをロードバランサーから自動除外してダウンタイムを最小化
- 設定管理: アプリケーション設定(DB接続文字列・フィーチャーフラグ)を中央集権管理して動的更新
- リーダー選出: 分散システムのマスター/レプリカ切り替えをConsensusアルゴリズム(Raft/Paxos)で安全に実施
主要ツールの概要
Consul
2014年公開、Go製のOSSです。GitHubスター28k+。サービスディスカバリー・ヘルスチェック・KVS・サービスメッシュ(Consul Connect)を統合したオールインワンツールです。HTTPとDNSの2つのインターフェースでサービスを名前解決できます。
# docker-compose.yml - Consul クラスター(3ノード)
version: "3.8"
services:
consul-1:
image: hashicorp/consul:latest
restart: unless-stopped
ports:
- "8500:8500" # HTTP UI/API
- "8600:8600/udp" # DNS
command: >
consul agent -server -ui
-node=consul-1
-bootstrap-expect=3
-bind=0.0.0.0
-advertise=consul-1
-client=0.0.0.0
-retry-join=consul-2
-retry-join=consul-3
-data-dir=/consul/data
consul-2:
image: hashicorp/consul:latest
command: >
consul agent -server
-node=consul-2
-bootstrap-expect=3
-bind=0.0.0.0
-advertise=consul-2
-retry-join=consul-1
-data-dir=/consul/data
consul-3:
image: hashicorp/consul:latest
command: >
consul agent -server
-node=consul-3
-bootstrap-expect=3
-bind=0.0.0.0
-advertise=consul-3
-retry-join=consul-1
-data-dir=/consul/data
# Python: Consul APIでサービス登録・ヘルスチェック・KVS操作
import consul
import socket
c = consul.Consul(host='localhost', port=8500)
# サービスを登録(HTTPヘルスチェック付き)
c.agent.service.register(
name='order-service',
service_id='order-service-001',
address=socket.gethostbyname(socket.gethostname()),
port=8080,
tags=['v2', 'production'],
check=consul.Check.http(
url='http://localhost:8080/health',
interval='10s',
timeout='5s',
deregister='30s', # 失敗後30秒でサービスを除外
),
)
print('サービス登録完了: order-service-001')
# 健全なサービスのみを取得(ロードバランシング)
_, services = c.health.service('order-service', passing=True)
endpoints = [(s['Service']['Address'], s['Service']['Port']) for s in services]
print(f'利用可能なendpoint: {endpoints}')
# KVSに設定を保存
c.kv.put('config/database/max_connections', '100')
c.kv.put('config/feature_flags/new_checkout', 'true')
# KVSから設定を取得(変更監視)
index, data = c.kv.get('config/database/max_connections')
print(f'DB最大接続数: {data["Value"].decode()}')
# KVSの変更をlong-pollingで監視
def watch_config(key: str):
index = None
while True:
index, data = c.kv.get(key, index=index, wait='60s')
if data:
print(f'設定変更検知: {key} = {data["Value"].decode()}')
# DNS経由のサービス解決(コードなし・ネイティブDNS)
# dig @localhost -p 8600 order-service.service.consul
# → 健全なorder-serviceインスタンスのIPが返る
etcd
2013年公開、Go製のOSSです。GitHubスター48k+。Kubernetesのクラスター状態を保存する分散KVSとして知られていますが、単独のサービスディスカバリー・設定ストアとしても使えます。Raftアルゴリズムによる強整合性と高可用性が特徴です。
# etcd クラスター起動(3ノード、Docker Compose)
version: "3.8"
services:
etcd-1:
image: quay.io/coreos/etcd:v3.5.13
environment:
ETCD_NAME: etcd-1
ETCD_DATA_DIR: /etcd-data
ETCD_LISTEN_CLIENT_URLS: http://0.0.0.0:2379
ETCD_ADVERTISE_CLIENT_URLS: http://etcd-1:2379
ETCD_LISTEN_PEER_URLS: http://0.0.0.0:2380
ETCD_INITIAL_ADVERTISE_PEER_URLS: http://etcd-1:2380
ETCD_INITIAL_CLUSTER: etcd-1=http://etcd-1:2380,etcd-2=http://etcd-2:2380,etcd-3=http://etcd-3:2380
ETCD_INITIAL_CLUSTER_STATE: new
ETCD_INITIAL_CLUSTER_TOKEN: my-cluster-token
ports:
- "2379:2379"
volumes:
- etcd1_data:/etcd-data
# Python: etcd3でサービスディスカバリーを実装
import etcd3
import json
import time
import threading
client = etcd3.client(host='localhost', port=2379)
SERVICE_PREFIX = '/services/order-service/'
def register_service(service_id: str, host: str, port: int):
service_info = json.dumps({'host': host, 'port': port, 'status': 'healthy'})
# TTL付きリース(60秒)でサービスを登録
lease = client.lease(ttl=60)
key = f'{SERVICE_PREFIX}{service_id}'
client.put(key, service_info, lease=lease)
# リースを定期的に更新(ハートビート)
def keepalive():
while True:
lease.refresh()
time.sleep(20)
t = threading.Thread(target=keepalive, daemon=True)
t.start()
print(f'サービス登録: {key}')
return lease
def discover_services() -> list:
services = []
results = client.get_prefix(SERVICE_PREFIX)
for value, meta in results:
service_info = json.loads(value.decode())
services.append(service_info)
return services
def watch_services():
events_iterator, cancel = client.watch_prefix(SERVICE_PREFIX)
print('サービス変更を監視中...')
for event in events_iterator:
if isinstance(event, etcd3.events.PutEvent):
print(f'サービス追加/更新: {event.key.decode()}')
elif isinstance(event, etcd3.events.DeleteEvent):
print(f'サービス削除(障害/停止): {event.key.decode()}')
# 使用例
lease = register_service('instance-001', '192.168.1.10', 8080)
services = discover_services()
print(f'発見したサービス: {services}')
ZooKeeper
2007年公開、Java製のOSSです。GitHubスター12k+。Apache Kafkaのブローカー管理・Hadoop/HBaseのコーディネーションに長く使われてきた分散コーディネーションサービスです。Paxosアルゴリズムで強整合性を保証しますが、JavaのJVMオーバーヘッドとKafkaの最新版でのZooKeeperレス化(KRaft)により新規採用は減っています。
機能比較表
| 比較項目 | Consul | etcd | ZooKeeper |
|---|---|---|---|
| サービスメッシュ | ✅(Connect) | ❌ | ❌ |
| DNS/HTTP両対応 | ✅ | HTTPのみ | ❌ |
| Kubernetes標準 | △ | ✅ | ❌ |
| 言語 | Go | Go | Java |
| 学習コスト | 中 | 低 | 高 |
サービスディスカバリーはDevOpsカテゴリ/categories/devopsのKubernetes・Istio・Nomadと統合してマイクロサービスのサービスメッシュを構成します。セキュリティカテゴリ/categories/securityのConsul ACL・TLS相互認証でサービス間通信を暗号化します。
FAQ
Q. KubernetesのコアDNS(CoreDNS)との違いは何ですか?
A. CoreDNSはKubernetes内のPod/Service間のDNS解決、Consulは複数のKubernetesクラスター間・VM・コンテナにまたがるサービスディスカバリーを担います。Kubernetesのみの環境ではCoreDNS+Service/EndpointリソースでサービスディスカバリーはKubernetesが管理します。ハイブリッドクラウド(K8s+VMのマルチクラウド)やKubernetesクラスター間のフェデレーションが必要な場合にConsulが価値を発揮します。
Q. etcdをKubernetes以外で使えますか?
A. 使えますが、Consulの方が汎用的です。etcdをアプリケーション設定ストア・サービスディスカバリーとして使う場合: ①etcd3(Python)・etcd-client(Go/Node.js)でプログラムからアクセス②KVS(put/get/watch/lease)でシンプルな設定管理③leaseのTTLを使ってサービスの自動登録解除(ハートビート)。ただしUIがなくAPIが低レベルなためConsulと比較すると使いやすさで劣ります。etcdは「Kubernetesが使っているから信頼性が高い」という理由でKubernetesと同じインフラに採用されることがあります。
Q. Kafka 3.xはZooKeeperなしで動きますか?
A. Kafka 3.3以降でKRaft(Kafka Raft Metadata mode)がGA(一般提供)となりZooKeeper不要になりました。KRaft モード: ①ZooKeeperをKafkaクラスターから完全に廃止(インフラが簡素化)②Kafkaブローカー自身がメタデータ管理を担う③起動速度・パーティション数の上限が改善。移行: Kafka 3.3〜3.6ではkafka-storage.shで新規クラスターをKRaftで初期化。既存のZooKeeperクラスターからの移行ツール(kafka-migrations)も提供されています。Confluent Platform・Amazon MSK 3.6+でもKRaftがサポートされています。
Q. Consulのサービスメッシュ(Consul Connect)はIstioと比べてどうですか?
A. Consultは設定がシンプル・Istioはより機能が豊富という違いです。Consul Connect: ①サイドカープロキシはEnvoyまたはConsul内蔵プロキシ②mTLS相互認証・インテンションポリシー(サービス間通信の許可/拒否)③KubernetesとVMの混合環境に強い④設定がHashiCorp CLIとHCLで統一。Istio: ①EnvoyサイドカーでHTTP/gRPCのより詳細なトラフィック制御②サーキットブレーカー・リトライ・カナリアデプロイの細かな制御③Kiali(ビジュアル管理UI)・JaegerトレーシングがAmbient Meshモードで統合④Kubernetes専用(VMサポートは追加設定が必要)。
まとめ
| ユースケース | 推奨ツール |
|---|---|
| マルチクラスター・VM+K8s混合・サービスメッシュ | Consul |
| Kubernetes内部・シンプルな設定ストア | etcd |
| Kafka・Hadoop・HBase(レガシー) | ZooKeeper |