Polyglot Service Discovery for Container Networking in Cloud Foundry

By: | March 9, 2018
Share

This post was co-authored by Angela Chin and Usha Ramachandran from Pivotal.

Introduction

Container networking on Cloud Foundry enables policy-driven direct communication between application instances on the platform. (We covered the motivation behind building a CNI-based container networking solution in an introductory blog post.) Since we introduced this feature, the response from the community has been very positive.

With this solution, applications enjoy direct connectivity with each other. Some of the benefits of direct connectivity include:

  • Reduced latency through direct communication instead of through the Gorouter 
  • Fine grained access control through app to app policy
  • Private communication using container IPs instead of public routes

However, developers were required to implement an external service discovery mechanism to realize these benefits. For Java developers, Eureka or Amalgam8 can be used. But what about other frameworks and languages? There hasn’t been an obvious or simple answer to this question. Until now!

We are happy to announce a big step forward for developer ease-of-use in Cloud Foundry with a new feature for polyglot service discovery. The feature is integrated with Cloud Foundry “out of the box.”

Introducing Polyglot Service Discovery for Cloud Foundry Apps

In Cloud Foundry Deployment 1.13, we shipped an experimental, DNS-based mechanism for service discovery via the platform. With this feature, app developers can write code in any language or framework and rely on the platform for service discovery. (Previously DevOps teams had to implement this feature. Now they get it for free!)

Polyglot service discovery introduces new capabilities with a familiar workflow. An app developer can configure an internal route to create a DNS entry for their app. This makes the app discoverable on the container network (Cloud Foundry developers will notice this workflow is identical to the existing workflow for managing external routes). A DNS lookup on an internal route returns a list of container IPs for applications corresponding to that particular internal route.

Applications that use internal routes will be directly communicating over the container network, instead of having traffic routed out and back in through the load balancer and GoRouter.  There is no change to the behavior of external routes that make apps discoverable and accessible through the GoRouter.

Let’s take a deeper look at how this new capability works, and how it offers advantages for developers.

apps.internal: A new shared domain for internal routes

A route is classified as an internal route if it is bound to an internal top-level domain. In the current implementation all internal routes in a Cloud Foundry deployment share one internal top-level domain. This domain is created automatically at deploy time. As shown below, this is set to apps.internal. The output of “cf domains” shows this new domain as a shared domain.

The apps.internal is a hard coded domain that cannot be modified or deleted. (Of course, we are open to feedback on this behavior.)

Working with Internal Routes

When app developers use the apps.internal domain with the cf create-route and cf map-route CLI commands (or APIs), the resulting route that is created is an internal route.

Note that internal routes differ from external routes in a few ways:

  • Internal routes are not protocol-specific. They specify a name for an app or set of apps that can be used for HTTP, TCP, or UDP traffic.
  • Internal routes currently do not support ports, paths, or route-services. We expect some (or all) of these features to be added in the future.
  • Internal routes enable application containers to communicate directly between each other, bypassing the Gorouter.

Example Use Cases

Scenario 1: Secure Microservices

InfoSec teams often mandate private routes for microservices wherever possible. Internal routes make it possible for private microservices to discover each other without exposing routes to the outside world.

An app developer can run the map-route command with the domain apps.internal and the resulting route created will be an internal route that returns the application’s IP on the container network. Now apps are discoverable internally, yet protected from external access!

In the example above, the application developers can configure internal routes for their applications. This makes them discoverable by using the commands:

In addition to making their applications discoverable, developers will also need to enable network policies to allow their portfolio of apps to connect to each other. Assuming the “destination” applications are listening on port 8080, these commands would set up network policies:

Scenario 2: Blue-Green Deploys

Application developers may want to roll out different versions of their applications that map to the same route for blue-green deployments. Polyglot service discovery supports this too! Best of all, it uses a familiar Cloud Foundry workflow.

Similar to external routes for applications on Cloud Foundry, developers can use create-route to create an internal route using the domain apps.internal and then use map-route to map one or more applications to the route that was created. This configuration is shown below.

In this example, when the application developer wants to test out a new version of their “billing” app, they can map the existing billing.apps.internal route to the new “billing-b” app. Traffic from the “frontend” will now be load balanced across instances of both applications.

Scenario 3: Clustering Applications

In the context of service discovery, clustering applications differ from microservice applications in one important respect — instances may need to communicate with specific instances instead of load balancing to any instance.

In the context of service discovery, clustering applications differ from microservice applications in one important respect — instances may need to communicate with specific instances instead of load balancing to any instance.

In order to support this use case, when developers map internal routes for an application, the platform also generates index-based routes for each instance of that app. As an application is scaled, the index-based routes are updated.  

Try it out

The BOSH release for the experimental service discovery features for container networking is on github. You can add it to your cf-deployment through an experimental ops file by following our deployment instructions.

Once you have an environment, you can try the updated “Cats and Dogs with Service Discovery” example app or push your own apps.

As always, your feedback is very welcome, either through comments here, Github issues/feature requests or on the Cloud Foundry #container-networking Slack channel.

Usha Ramachandran Profile Image

Usha Ramachandran, AUTHOR

SEE ALL ARTICLES