Container Networking with CloudFoundry PWS/PCF - PART1

CloudFoundry is an amazing PaaS Cloud Platform. I’ve been using it for several years, especially Pivotal Web Services (PWS).

If you are doing microservices and hosting them on the cloud, you probably have the following setup from your Platform. In this example, microservice A is making a request to microservice B. The default behavior forbids a direct communication between A to B. The caller service will have go through the GoRouter first, and will be redirected to the destination service.

Courtesy of Pivotal.io

With Container Networking enabled, your microservice A can have a direct access to microservice B. Pretty cool, right? This allows more security between your containers (on top of your security ie: oAuth2 Client Credentials, etc…) and also reducing the network latency between your services.

Courtesy of Pivotal.io

Getting Started

Before getting started, you will need a few tools/cli to install first.

  • Pivotal Web Services account
  • Feature c2c enabled on PWS (Request here)
  • Feature SCS (Spring Cloud Services) enabled on PWS
  • CloudFoundry CLI
  • Network Access CF CLI plugin installed
  • SpringBoot CLI + Spring Cloud CLI

Run the example locally

Service Registry

If you want your service A to communicate with service B, it has to know where to find it. To do so, you need a local Service Registry. It’s easy to start an Eureka instance with Spring Cloud CLI:

$ spring cloud eureka

Compile and run the example

You can use my basic github example https://github.com/christophe-f/pws-c2c, and start both applications, either from a terminal or your favorite IDE.

# Compiles both services
$ mvn clean package
# Starts the downstream service
$ cd travel-service
$ mvn spring-boot:run
# Starts the client
$ cd travel-client
$ mvn spring-boot:run

Test it

Open the url http://localhost:8761 in a browser, you will see the 2 services registered in Eureka.

Click on the travel-client and open the /destinations endpoint, you will receive a list of destinations coming from the downstream service travel-service.

Run the example on PWS CloudFoundry

Service Registry

On PWS, go to the marketplace and create a Service Registry service.

Build and Deploy

My sample project has amanifest.yml file. Once you are logged in your PWS account and selected your organization/space, you can deploy both apps with a simple cf push

$ mvn clean package
$ cf push

Allow Container Networking communication

Once the 2 applications are deployed and running, you cannot access the travel-service from the travel-client yet. In my manifest.yml deployment file, I did NOT set a route to the downstream service. You must allow the communication with the following command:

$ cf allow-access travel-client travel-service --protocol tcp --port 8080
If you haven’t notice yet, in the manifest.yml file, I have the TRUST_CERTS environment variables set. If you are running the example manually or in your own code, this setup is also mandatory.

Test it

In the Service Registry PWS service, you will see your 2 registered apps.

Try to query the travel-client /destinations endpoint. The route is set to generate a random url, so you will have to get it from your environment.

How to add Container Networking to your existing project

New dependency

You have to add this new dependency into your pom.xml file (or Gradle):

<dependency>
<groupId>io.pivotal.spring.cloud</groupId>
<artifactId>spring-cloud-services-starter-service-registry</artifactId>
<version>1.4.1.RELEASE</version>
</dependency>
If you were using spring-cloud-starter-eureka as a dependency, you can remove it as the one above will replace it

Direct registration in the properties

To register to SCS Eureka, you have to register with the direct method in your application.yml:

spring:
cloud:
services:
registrationMethod: direct

Set the TRUST_CERTS environment variable

To be able to register to the Service Registery service on PWS, you need a using a self-signed SSL certificate. To do so, you have to set a TRUST_CERTS environment variable per application. You can use the one in my manifest.ymldeployment file or set it manually with the following command line:

$ cf set-env travel-client TRUST_CERTS api.run.pivotal.io
$ cf set-env travel-service TRUST_CERTS api.run.pivotal.io
If you are using your own CloudFoundry environment or PCF, you will have to replace api.run.pivotal.io with your own api url.

Security

Using the Spring Cloud Services Starters for Service Registry will make all application endpoints secured. You should use your own authentication system or disable it like I did in my examples (NOT recommended for production) in your application.yml with:

security:
basic:
enabled: false

Ribbon

Ribbon is a client side LoadBalancer from Netflix and available in SpringCloud. While doing microservices without Container Networking, the traffic was load balanced by the Platform with the internal LB/GoRouter. The use of Ribbon was not required. Now that you have enabled Container Networking, Ribbon is becoming mandatory.

To enable Ribbon on your client application, add the following dependency:

<dependency>
<groupId>
org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>

Demo project

The demo project source code is available on github https://github.com/christophe-f/pws-c2c

References

Thanks to this Pivotal blog post that helped me getting started.

What’s up next?

Read PART2 about Container Networking performance on PWS.