# How to Configure Service Discovery in Easegress with Eureka, Consul, or etcd

> Learn to configure Easegress service discovery with Eureka, Consul, or etcd. Easily integrate backend registries into your dynamic traffic pipelines.

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

---

**Easegress configures service discovery through dedicated service-registry controllers—`EurekaServiceRegistry`, `ConsulServiceRegistry`, and `EtcdServiceRegistry`—that poll or watch backend registries and push discovered instances to the central `ServiceRegistry` system controller for use in dynamic traffic pipelines.**

Easegress supports multi-backend service discovery by implementing registry-specific controllers that integrate with **Eureka**, **Consul**, and **etcd**. Each controller runs as a **Business Controller** object that watches its respective backend and synchronizes instance data to Easegress's internal service registry. This article explains how to configure service discovery in Easegress using the exact spec fields and source implementations found in the `megaease/easegress` repository.

## Architecture of Service Discovery Controllers

Easegress implements service discovery through four coordinated components:

1. **Controller object** – One of `EurekaServiceRegistry`, `ConsulServiceRegistry`, or `EtcdServiceRegistry` (registered as a Business Controller).
2. **Client** – A thin wrapper around the native SDK (Eureka client, Consul API, or etcd v3 client). The client is built lazily and cached with a read-write mutex.
3. **Sync loop** – Each controller runs a goroutine that parses `SyncInterval` (or `CacheTimeout` for etcd), queries the backend, converts results into `serviceregistry.ServiceInstanceSpec` objects, and sends a `RegistryEvent` on an internal channel.
4. **ServiceRegistry** – The system controller defined in [`pkg/object/serviceregistry/serviceregistry.go`](https://github.com/megaease/easegress/blob/main/pkg/object/serviceregistry/serviceregistry.go) aggregates events from all registries and makes instance maps available to traffic controllers.

## Configuring Eureka Service Discovery

The **EurekaServiceRegistry** controller is implemented in [`pkg/object/eurekaserviceregistry/eurekaserviceregistry.go`](https://github.com/megaease/easegress/blob/main/pkg/object/eurekaserviceregistry/eurekaserviceregistry.go). It uses the third-party client `github.com/ArthurHlt/go-eureka-client/eureka` to poll the `/eureka/apps` endpoint. The sync loop (`run`) parses `SyncInterval`, calls `update()` to fetch application data, and emits registry events.

```yaml

# eureka-registry.yaml

kind: EurekaServiceRegistry
name: eureka-registry
endpoints:
  - http://127.0.0.1:8761/eureka   # Eureka server URL(s)

syncInterval: 10s

```

```bash
egctl apply -f eureka-registry.yaml

```

## Configuring Consul Service Discovery

The **ConsulServiceRegistry** controller resides in [`pkg/object/consulserviceregistry/consulserviceregistry.go`](https://github.com/megaease/easegress/blob/main/pkg/object/consulserviceregistry/consulserviceregistry.go). It builds a Consul client with `api.NewClient` and reads service information via the Consul Catalog API. The controller applies optional `ServiceTags` filtering before notifying the ServiceRegistry.

```yaml

# consul-registry.yaml

kind: ConsulServiceRegistry
name: consul-registry
address: "127.0.0.1:8500"   # Consul agent address

scheme: http
syncInterval: 15s
serviceTags: ["my-app"]     # optional tag filter

```

```bash
egctl apply -f consul-registry.yaml

```

## Configuring Etcd Service Discovery

The **EtcdServiceRegistry** controller is implemented in [`pkg/object/etcdserviceregistry/etcdserviceregistry.go`](https://github.com/megaease/easegress/blob/main/pkg/object/etcdserviceregistry/etcdserviceregistry.go). It stores service data under a configurable key prefix (default `/services/`). A background goroutine watches the prefix, caches results for `CacheTimeout`, and pushes updates to the ServiceRegistry.

```yaml

# etcd-registry.yaml

kind: EtcdServiceRegistry
name: etcd-registry
endpoints:
  - "127.0.0.1:2379"
prefix: "/services/"          # key prefix where services are stored

cacheTimeout: 30s

```

```bash
egctl apply -f etcd-registry.yaml

```

## Consuming Discovered Services in Traffic Pipelines

Once a registry controller is active, discovered instances are stored in the central ServiceRegistry. You reference these instances in a **ServicePool** within an HTTPServer or other traffic controller by specifying the `serviceName` that matches the service registered in Eureka, Consul, or etcd.

```yaml

# http-server.yaml

kind: HTTPServer
name: demo-http
port: 8080
pools:
  - name: backend-pool
    serviceName: my-backend-service   # must match the service name in the registry

    lbPolicy: roundRobin

```

The `backend-pool` automatically receives upstream instances discovered by the chosen registry controller without manual IP configuration.

## Key Implementation Details

All three controllers expose uniform **spec** fields (`address`/`endpoints`, `syncInterval`/`cacheTimeout`, etc.) documented in [`docs/07.Reference/7.01.Controllers.md`](https://github.com/megaease/easegress/blob/main/docs/07.Reference/7.01.Controllers.md) (lines 81-136). However, their internal mechanisms differ:

- **Eureka** – Polls the REST API at `SyncInterval` intervals and converts Eureka application metadata into `ServiceInstanceSpec` objects.
- **Consul** – Queries the Catalog API, supports tag-based filtering, and emits events when instance health changes.
- **Etcd** – Uses the v3 client watch API on the configured prefix, maintaining a local cache governed by `CacheTimeout` to reduce etcd server load.

Each controller sends `RegistryEvent` structs to the `ServiceRegistry` system controller, which maintains a thread-safe map of all available instances across all backends.

## Summary

- Easegress implements service discovery through three specialized controllers: `EurekaServiceRegistry`, `ConsulServiceRegistry`, and `EtcdServiceRegistry`.
- Each controller runs an independent sync loop that converts backend-specific data into standardized `ServiceInstanceSpec` objects.
- Configuration requires YAML manifests declaring endpoints, synchronization intervals (`syncInterval` or `cacheTimeout`), and backend-specific options like `serviceTags`.
- The `ServiceRegistry` system controller aggregates events from all registries, making discovered instances available to **ServicePools** in HTTPServers and other traffic pipelines.

## Frequently Asked Questions

### What is the difference between SyncInterval and CacheTimeout in Easegress service discovery?

`SyncInterval` controls how often the Eureka and Consul controllers actively poll their respective APIs for changes, while `CacheTimeout` specifically governs the Etcd controller's local cache expiration before re-querying the key-value store. Both parameters prevent excessive backend load but apply to different discovery mechanisms.

### How does Easegress handle authentication with Eureka, Consul, or etcd?

According to the source implementations in [`eurekaserviceregistry.go`](https://github.com/megaease/easegress/blob/main/eurekaserviceregistry.go), [`consulserviceregistry.go`](https://github.com/megaease/easegress/blob/main/consulserviceregistry.go), and [`etcdserviceregistry.go`](https://github.com/megaease/easegress/blob/main/etcdserviceregistry.go), authentication is configured through the client initialization parameters in the YAML spec. This includes TLS certificate paths, tokens, or credentials passed via the `endpoints` or `address` configuration blocks, depending on the backend's requirements.

### Can multiple service registries be used simultaneously in Easegress?

Yes. The `ServiceRegistry` system controller in [`pkg/object/serviceregistry/serviceregistry.go`](https://github.com/megaease/easegress/blob/main/pkg/object/serviceregistry/serviceregistry.go) aggregates `RegistryEvent` channels from all configured registry controllers. You can run multiple Eureka, Consul, or etcd backends concurrently, and their discovered instances will feed into the same or different service pools based on the `serviceName` matching.

### What data format does Easegress expect for etcd service discovery?

As implemented in [`pkg/object/etcdserviceregistry/etcdserviceregistry.go`](https://github.com/megaease/easegress/blob/main/pkg/object/etcdserviceregistry/etcdserviceregistry.go), services must be stored under a configurable prefix (default `/services/`) in etcd. The controller watches this prefix using the etcd v3 watch API, decodes the values into service instance specifications, and caches them for the duration specified by `CacheTimeout` before refreshing.