How to run Akka Cluster on CloudFoundry
This is a short guide to walk you through how to deploy and run Akka Cluster based application on CloudFoundry
Note: Akka with no Remoting / Cluster can run on Cloud Foundry with no additional requirement. This article deals with cases when Remoting / Cluster features are used.
Background: Akka Cluster is based on TCP communication or optionally can use UDP instead in Akka version >= 2.4.11. However, the current CloudFoundry release v245 doesn’t support container-to-container TCP or UDP based communication. The develop branch of Container Networking for Garden-RunC plugin contains support for this type of communication on CloudFoundry with fixed port numbers (Pivotal plans to support port number ranges in the future). In this guide we will use this experimential plugin to show how to run Akka Cluster that uses TCP. In case of UDP, setting canonical.port
(2.4.11 release notes) will make UDP based Akka Cluster usable on CloudFoundry as well.
Note: For this guide we installed Cloud Foundry locally using bosh-lite. CI deployment scripts and config for AWS provided by CloudFoundry can be found here.
Installing CloudFoundry components:
Both development environment for BOSH and container networking plugin are works in progress, thus we advise to follow their respective latest documentation for installation instructions. In our case we used develop branch as of September 28th, 2016.
Enabling container-to-container networking
By default, there is no network access between different containers. CloudFoundry provides a sample application Cats-and-Dogs that contains instructions how to enable the access on a per port basis.
Deploying Akka application
You can deploy Akka application by using java-buildpack. Our sample application is inspired by akka-sample-cluster). It has backend nodes that calculate factorial upon receiving messages from frontend nodes. Frontend nodes also expose HTTP interface GET <frontend-hostname>/info
that shows number of jobs completed.
Background: with Akka Cluster every node should know IPs/hostnames and ports of cluster seed nodes. Containers in Cloud Foundry have dynamic IPs making it impossible to manage a list of static IPs for seed nodes. One possible way to bootstrap a cluster is when the first node joins itself and publishes its IP in some sort of shared registry that is accessible to the rest of nodes. More nodes can register themselves as seed nodes later. Cloud Foundry doesn’t have any type of Service Registry built-in. Some of the solutions could be to use etcd directly or via ConstructR that utilizes etcd as Akka extension. We used amalgam8 because Cloud Foundry provides an easy way to install amalgam8 on bosh-lite. While it works for proof-of-concept implementation, amalgam8 can not be used in production as is since simultaneous seed nodes registration with amalgam8 has high chances of forming multiple separated cluster.
- Clone sample application: from here.
-
Compile and package sample components:
cd akka-sample-cluster sbt backend:assembly # backend sbt frontend:assembly # frontend
- Deploy amalgam8: amalgam8 installation along with a sample application can be found here.
-
Deploy sample Akka backend: with
--no-route
and--health-check-type none
options since backend doesn’t expose any HTTP ports:cf push --no-route --health-check-type none sample-akka-cluster-backend -p target/scala-2.11/akka-sample-backend.jar -b https://github.com/cloudfoundry/java-buildpack.git cf access-allow sample-akka-cluster-backend sample-akka-cluster-backend --port 2551 --protocol tcp cf logs sample-akka-cluster-backend # check the log to see that first node joined itself cf scale sample-akka-cluster-backend -i 2 # needed since our sample application requires 2 backends, can be changed configuration
Note: to prevent cluster split, verify that the first node is running before scaling it.
-
Deploy sample Akka frontend:
cf push sample-akka-cluster-frontend -p target/scala-2.11/akka-sample-frontend.jar -b https://github.com/cloudfoundry/java-buildpack.git cf access-allow sample-akka-cluster-frontend sample-akka-cluster-backend --port 2551 --protocol tcp
-
Verify that it works:
curl sample-akka-cluster-frontend.bosh-lite.com/info #it should show the number of completed jobs
Summary
This guide shows a prototype implementation so it requires more than that to have a production Akka Cluster on Cloud Foundry, however it is a successful proof-of-concept that demonstrates Akka Cluster working with the latest Cloud Foundry release and the new experimental network plugin.