AI

サービスディスカバリー比較: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)により新規採用は減っています。

機能比較表

比較項目ConsuletcdZooKeeper
サービスメッシュ✅(Connect)
DNS/HTTP両対応HTTPのみ
Kubernetes標準
言語GoGoJava
学習コスト

サービスディスカバリーは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

関連外部リソース

他の記事も読む

Let's Build Together

OSS導入、自社だけで悩まない。

ツール選定から構築・運用・AI活用まで、オープンソースラボ運営元のClasslessが伴走します。初回のご相談は無料です。