Service discovery configuration

Service discovery is how applications and (micro)services are located on the network. In a cloud environment, services are ephemeral, so a real-time service discovery mechanism is critical. Ambassador uses information from service discovery to determine where to route incoming requests.

Ambassador support for service discovery

Ambassador supports different mechanisms for service discovery. These mechanisms are:

  • Kubernetes service-level discovery (default).
  • Kubernetes endpoint-level discovery.
  • Consul endpoint-level discovery.

Kubernetes service-level discovery

By default, Ambassador uses Kubernetes DNS and service-level discovery. In a Mapping resource, specifying service: foo will prompt Ambassador to look up the DNS address of the foo Kubernetes service. Traffic will be routed to the foo service. Kubernetes will then load balance that traffic between multiple pods. For more details on Kubernetes networking and how this works, see https://blog.getambassador.io/session-affinity-load-balancing-controls-grpc-web-and-ambassador-0-52-2b916b396d0c.

Kubernetes endpoint-level discovery

Ambassador can also watch Kubernetes endpoints. This bypasses the Kubernetes service routing layer, and enables the use of advanced load balancing controls such as session affinity and maglev. For more details, see the load balancing reference.

Consul endpoint-level discovery

Ambassador natively integrates with Consul for endpoint-level service discovery. In this mode, Ambassador obtains endpoint information from Consul. One of the primary use cases for this architecture is in hybrid cloud environments that run a mixture of Kubernetes services as well as VMs, as Consul can serve as the single global registry for all services.

The Resolver resource

The Resolver resource is used to configure Ambassador's service discovery strategy.

The Kubernetes Service Resolver

The Kubernetes Service Resolver configures Ambassador to use Kubernetes services. If no resolver is specified, this behavior is the default. When this resolver is used, the service.namespace value from a Mapping is handed to the Kubernetes cluster's DNS resolver to determine where requests are sent.

---
apiVersion: ambassador/v1
kind: KubernetesServiceResolver
name: kubernetes-service

The Kubernetes Endpoint Resolver

The Kubernetes Endpoint Resolver configures Ambassador to resolve Kubernetes endpoints. This enables the use of more advanced load balancing configuration. When this resolver is used, the endpoints for the service defined in a Mapping are resolved and used to determine where requests are sent.

---
apiVersion: ambassador/v1
kind: KubernetesEndpointResolver
name: endpoint

The Consul Resolver

The Consul Resolver configures Ambassador to use Consul for service discovery. When this resolver is used, the service defined in a Mapping is passed to Consul, along with the datacenter specified, to determine where requests are sent.

---
apiVersion: ambassador/v1
kind: ConsulResolver
name: consul-dc1
address: consul-server.default.svc.cluster.local:8500
datacenter: dc1
  • address: The fully-qualified domain name or IP address of your Consul server. This field also supports environment variable substitution.
  • datacenter: The Consul data center where your services are registered

You may want to use an environment variable if you're running a Consul agent on each node in your cluster. In this setup, you could do the following:

---
apiVersion: ambassador/v1
kind: ConsulResolver
name: consul-dc1
address: "${HOST_IP}"
datacenter: dc1

and then add the HOST_IP environment variable to your Kubernetes deployment:

containers:
  - name: example
    image: quay.io/datawire/ambassador:0.70.0
    env:
      - name: HOST_IP
        valueFrom:
          fieldRef:
             fieldPath: status.hostIP

Using Resolvers

Once a resolver is defined, you can use them in a given Mapping:

---
apiVersion: v1
kind: Service
metadata:
  name: qotm
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v1
      kind:  Mapping
      name:  qotm_mapping
      prefix: /qotm/
      service: qotm
      load_balancer:
        policy: round_robin
      ---
      apiVersion: ambassador/v1
      kind:  Mapping
      name:  bar_mapping
      prefix: /bar/
      service: https://bar:9000
      tls: client-context
      resolver: consul-dc1
      load_balancer:
        policy: round_robin
spec:
  selector:
    service: qotm
  ports:
    - port: 80
      targetPort: http-api
  type: NodePort

The YAML configuration above will configure Ambassador to use Kubernetes Service Discovery to route to the qotm Kubernetes service on requests with prefix: /qotm/ and use Consul Service Discovery to route to the bar service on requests with prefix: /bar/.