> For the complete documentation index, see [llms.txt](https://rocdu.gitbook.io/deep-understanding-of-istio/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://rocdu.gitbook.io/deep-understanding-of-istio/10/7.md).

# ServiceDiscovery

ServiceDiscovery

ServiceDiscovery 接口用于列出服务和实例列表

```
ac := aggregate.NewController(aggregate.Options{
    MeshHolder: e,
})
e.ServiceDiscovery = ac
```

## aggregate Controller

pilot/pkg/serviceregistry/aggregate/controller.go

```
type Controller struct {
    registries []serviceregistry.Instance
    storeLock  sync.RWMutex
    meshHolder mesh.Holder
    running    bool
}
```

其主要包含了service registry的实例。 单个service registry结合了服务发现和用于管理异步事件的控制器的功能。

```go
type Instance interface {
    model.Controller
    model.ServiceDiscovery

    // Provider backing this service registry (i.e. Kubernetes etc.)
    Provider() ProviderID

    // Cluster for which the service registry applies. Only needed for multicluster systems.
    Cluster() string
}
```

## 实现

### kube controller

pilot/pkg/serviceregistry/kube/controller/controller.go Controller

```
kubeRegistry := NewController(client, options)
m.serviceController.AddRegistry(kubeRegistry)
```

对于kube来说直接读取servicesMap

```
// Services implements a service catalog operation
func (c *Controller) Services() ([]*model.Service, error) {
    c.RLock()
    out := make([]*model.Service, 0, len(c.servicesMap))
    for _, svc := range c.servicesMap {
        out = append(out, svc)
    }
    c.RUnlock()
    sort.Slice(out, func(i, j int) bool { return out[i].Hostname < out[j].Hostname })

    return out, nil
}
```

### serviceentrystore

pilot/pkg/serviceregistry/serviceentry/servicediscovery.go ServiceEntryStore

```
s.serviceEntryStore = serviceentry.NewServiceDiscovery(s.configController, s.environment.IstioConfigStore, s.XDSServer)
    serviceControllers.AddRegistry(s.serviceEntryStore)
```

可以看到对于ServiceEntryStore从各个store里面获取ServiceEntries

```
func (s *ServiceEntryStore) Services() ([]*model.Service, error) {
    services := make([]*model.Service, 0)
    for _, cfg := range s.store.ServiceEntries() {
        services = append(services, convertServices(cfg)...)
    }

    return autoAllocateIPs(services), nil
}
```
