Easegress Service Discovery: Native Support for Consul, Eureka, and Nacos

TLDR: Easegress implements service discovery through a unified registry center that exposes native Consul, Eureka, and Nacos APIs, allowing existing clients to discover services without code changes while the sidecar automatically handles registration.

Easegress provides a comprehensive service mesh solution that abstracts service discovery through a centralized registry center. This architecture enables seamless integration with existing infrastructure by supporting multiple popular service discovery protocols natively. The implementation normalizes different registry backends into a common API while exposing protocol-specific endpoints for backward compatibility.

Architecture of Easegress Service Discovery

The service discovery mechanism in Easegress operates through a layered architecture that decouples service declaration from protocol implementation:

  • Service Specification Layer: Defines which discovery mechanism a service uses through the Sidecar.DiscoveryType field in pkg/object/meshcontroller/spec/spec.go. Supported values include consul, eureka, and nacos.

  • Registry Center Layer: Normalizes all supported registries into a common Go API in pkg/object/meshcontroller/registrycenter/discovery.go. This layer provides DiscoveryService(serviceName) and Discovery() methods that return a unified ServiceRegistryInfo structure.

  • Worker API Layer: Exposes HTTP endpoints that mimic the original registry APIs. Separate adapters in pkg/object/meshcontroller/worker/api_consul.go, api_eureka.go, and api_nacos.go translate between the internal representation and protocol-specific wire formats.

  • Sidecar Integration: Automatically registers services with the MeshController on startup, creating the linkage between the service name and the sidecar's egress address.

The Registry Center Abstraction

The core normalization logic resides in pkg/object/meshcontroller/registrycenter/discovery.go. This file implements the DiscoveryService function that retrieves service specifications and constructs virtual service instances:

// DiscoveryService returns ServiceRegistryInfo containing the service spec
// and a default sidecar egress instance pointing to the sidecar's address
serviceInfo, err := registryServer.DiscoveryService(serviceName)

The ServiceRegistryInfo structure contains the service specification and a default sidecar egress instance (uniqInstanceID). This instance points to the sidecar's egress port, effectively creating a virtual endpoint that downstream services can target.

Supported Service Discovery Protocols

Easegress exposes native-compatible APIs for three major service discovery protocols, allowing existing clients to migrate without modification.

Consul Integration

The Consul-compatible API is implemented in pkg/object/meshcontroller/worker/api_consul.go. It exposes endpoints such as GET /v1/health/service/{serviceName} that return Consul-formatted JSON:


# Query service health information using Consul API

curl http://127.0.0.1:13009/v1/health/service/orders

The handler converts internal ServiceRegistryInfo to Consul's health service format using ToConsulHealthService:

func (worker *Worker) healthService(w http.ResponseWriter, r *http.Request) {
    serviceName := chi.URLParam(r, "serviceName")
    serviceInfo, err := worker.registryServer.DiscoveryService(serviceName)
    serviceEntry := worker.registryServer.ToConsulHealthService(serviceInfo)
    buff := codectool.MustMarshalJSON(serviceEntry)
    worker.writeJSONBody(w, buff)
}

Eureka Integration

Eureka support resides in pkg/object/meshcontroller/worker/api_eureka.go, handling both XML and JSON formats via the /eureka/apps/{serviceName} endpoint:


# Query service information using Eureka API (XML format)

curl -H "Accept: application/xml" http://127.0.0.1:13009/eureka/apps/orders

The implementation uses ToEurekaApp to transform the internal representation:

serviceInfo, err := worker.registryServer.DiscoveryService(serviceName)
xmlAPP := worker.registryServer.ToEurekaApp(serviceInfo)
rsp, err := worker.encodeByAcceptType(registrycenter.ContentTypeXML, jsonApp, xmlAPP)

Nacos Integration

Nacos compatibility is provided in pkg/object/meshcontroller/worker/api_nacos.go, exposing the /nacos/ns/instance/list endpoint:


# List service instances using Nacos API

curl "http://127.0.0.1:13009/nacos/ns/instance/list?serviceName=orders"

The handler converts data using ToNacosService:

serviceInfo, err = worker.registryServer.DiscoveryService(serviceName)
nacosSvc := worker.registryServer.ToNacosService(serviceInfo)
buff := codectool.MustMarshalJSON(nacosSvc)
worker.writeJSONBody(w, buff)

Service Registration and Sidecar Integration

Service discovery requires services to register themselves with the mesh. Easegress automates this through the sidecar pattern defined in pkg/object/meshcontroller/spec/spec.go:


# Mesh spec declaring Consul discovery

service:
  name: orders
  registerTenant: default
  sidecar:
    discoveryType: consul
    address: 10.0.1.23
    ingressPort: 13010
    egressPort: 13011

When the sidecar starts, it invokes worker.registryServer.Register from handlers like consulRegister in pkg/object/meshcontroller/worker/api_consul.go:

func (worker *Worker) consulRegister(w http.ResponseWriter, r *http.Request) {
    // Retrieve service specification from mesh controller
    serviceSpec := worker.service.GetServiceSpec(worker.serviceName)
    
    // Register with registry center, creating default sidecar egress instance
    worker.registryServer.Register(serviceSpec, worker.ingressServer.Ready, worker.egressServer.Ready)
}

The Worker API server listens on port 13009 by default, exposing the discovery endpoints that downstream services query to locate upstream instances.

Summary

  • Easegress service discovery normalizes multiple registry protocols through a centralized registry center architecture implemented in pkg/object/meshcontroller/registrycenter/discovery.go.
  • Native API compatibility allows existing Consul, Eureka, and Nacos clients to discover services without code modifications via protocol-specific worker APIs.
  • Automatic sidecar registration eliminates manual service registration by having the sidecar automatically register with the MeshController on startup using the discoveryType specified in the service spec.
  • Virtual instance generation creates default sidecar egress instances that point to the sidecar's egress port, enabling transparent traffic interception.

Frequently Asked Questions

What service discovery protocols does Easegress support?

Easegress supports Consul, Eureka, and Nacos service discovery protocols natively. The implementation exposes compatible HTTP endpoints for each protocol in pkg/object/meshcontroller/worker/api_consul.go, api_eureka.go, and api_nacos.go, allowing existing clients to query services using their native SDKs without modification.

How does automatic service registration work in Easegress?

Automatic registration occurs through the sidecar pattern. When a sidecar starts, it reads the Sidecar.DiscoveryType field from the service specification defined in pkg/object/meshcontroller/spec/spec.go. The sidecar then calls worker.registryServer.Register() to create a service entry in the registry center, generating a default egress instance that points to the sidecar's egress address.

Can existing microservices migrate to Easegress without changing discovery client code?

Yes. Easegress implements protocol-compatible API adapters that translate between internal ServiceRegistryInfo structures and native registry wire formats. Clients using Consul, Eureka, or Nacos SDKs can point their configuration to the Easegress Worker API endpoint (default port 13009) instead of the original registry URL, and discovery operations will function identically.

Where is the service discovery type configured in Easegress?

The discovery mechanism is declared in the mesh service specification via the sidecar.discoveryType field. This YAML configuration resides in the service definition processed by pkg/object/meshcontroller/spec/spec.go. Valid values include consul, eureka, or nacos, determining which Worker API adapter handles registration and discovery requests for that service.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →