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.
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.
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
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
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
Run the example on PWS CloudFoundry
On PWS, go to the marketplace and create a
Service Registry service.
Build and Deploy
My sample project has a
manifest.yml file. Once you are logged in your PWS account and selected your organization/space, you can deploy both apps with a simple
$ 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_CERTSenvironment variables set. If you are running the example manually or in your own code, this setup is also mandatory.
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
You have to add this new dependency into your pom.xml file (or Gradle):
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
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.iowith your own api url.
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
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:
The demo project source code is available on github https://github.com/christophe-f/pws-c2c
Thanks to this Pivotal blog post that helped me getting started.
What’s up next?
Read PART2 about Container Networking performance on PWS.