How to Configure Service Discovery in Easegress with Eureka, Consul, or etcd
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:
- Controller object – One of
EurekaServiceRegistry,ConsulServiceRegistry, orEtcdServiceRegistry(registered as a Business Controller). - 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.
- Sync loop – Each controller runs a goroutine that parses
SyncInterval(orCacheTimeoutfor etcd), queries the backend, converts results intoserviceregistry.ServiceInstanceSpecobjects, and sends aRegistryEventon an internal channel. - ServiceRegistry – The system controller defined in
pkg/object/serviceregistry/serviceregistry.goaggregates 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. 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.
# eureka-registry.yaml
kind: EurekaServiceRegistry
name: eureka-registry
endpoints:
- http://127.0.0.1:8761/eureka # Eureka server URL(s)
syncInterval: 10s
egctl apply -f eureka-registry.yaml
Configuring Consul Service Discovery
The ConsulServiceRegistry controller resides in 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.
# 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
egctl apply -f consul-registry.yaml
Configuring Etcd Service Discovery
The EtcdServiceRegistry controller is implemented in 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.
# etcd-registry.yaml
kind: EtcdServiceRegistry
name: etcd-registry
endpoints:
- "127.0.0.1:2379"
prefix: "/services/" # key prefix where services are stored
cacheTimeout: 30s
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.
# 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 (lines 81-136). However, their internal mechanisms differ:
- Eureka – Polls the REST API at
SyncIntervalintervals and converts Eureka application metadata intoServiceInstanceSpecobjects. - 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
CacheTimeoutto 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, andEtcdServiceRegistry. - Each controller runs an independent sync loop that converts backend-specific data into standardized
ServiceInstanceSpecobjects. - Configuration requires YAML manifests declaring endpoints, synchronization intervals (
syncIntervalorcacheTimeout), and backend-specific options likeserviceTags. - The
ServiceRegistrysystem 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, consulserviceregistry.go, and 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 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, 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.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →