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

> Easegress service discovery natively supports Consul Eureka and Nacos through a unified registry center. Connect existing clients without code changes.

- Repository: [easegress-io/easegress](https://github.com/easegress-io/easegress)
- Tags: how-to-guide
- Published: 2026-03-01

---

**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`](https://github.com/easegress-io/easegress/blob/main/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`](https://github.com/easegress-io/easegress/blob/main/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`](https://github.com/easegress-io/easegress/blob/main/pkg/object/meshcontroller/worker/api_consul.go), [`api_eureka.go`](https://github.com/easegress-io/easegress/blob/main/api_eureka.go), and [`api_nacos.go`](https://github.com/easegress-io/easegress/blob/main/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`](https://github.com/easegress-io/easegress/blob/main/pkg/object/meshcontroller/registrycenter/discovery.go). This file implements the `DiscoveryService` function that retrieves service specifications and constructs virtual service instances:

```go
// 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`](https://github.com/easegress-io/easegress/blob/main/pkg/object/meshcontroller/worker/api_consul.go). It exposes endpoints such as `GET /v1/health/service/{serviceName}` that return Consul-formatted JSON:

```bash

# 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`:

```go
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`](https://github.com/easegress-io/easegress/blob/main/pkg/object/meshcontroller/worker/api_eureka.go), handling both XML and JSON formats via the `/eureka/apps/{serviceName}` endpoint:

```bash

# 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:

```go
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`](https://github.com/easegress-io/easegress/blob/main/pkg/object/meshcontroller/worker/api_nacos.go), exposing the `/nacos/ns/instance/list` endpoint:

```bash

# 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`:

```go
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`](https://github.com/easegress-io/easegress/blob/main/pkg/object/meshcontroller/spec/spec.go):

```yaml

# 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`](https://github.com/easegress-io/easegress/blob/main/pkg/object/meshcontroller/worker/api_consul.go):

```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`](https://github.com/easegress-io/easegress/blob/main/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`](https://github.com/easegress-io/easegress/blob/main/pkg/object/meshcontroller/worker/api_consul.go), [`api_eureka.go`](https://github.com/easegress-io/easegress/blob/main/api_eureka.go), and [`api_nacos.go`](https://github.com/easegress-io/easegress/blob/main/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`](https://github.com/easegress-io/easegress/blob/main/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`](https://github.com/easegress-io/easegress/blob/main/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.