I've been running a few experiments in distributed systems on top of akka and time and again I needed a small akka cluster as a base for my tests. Thus, kluster was born.
kluster is a minimal akka cluster application that runs locally via docker containers. It includes a shell script to build, kill and redeploy the application.
The code is on github and the README contains instructions on how to build and run the application. You should get everything up and running with a single command line: run.sh.
EDIT: 2017-06-20 see updates on how to add and remove nodes from the cluster.
kluster relies on user defined networks to run the cluster. The script run.sh
handles all the magic. The script creates a user defined network named kluster
if it doesn't exist. Then, the containers comprising the cluster are run on this
network. Furthermore, the hostname of each container is set and follows the
naming convention klusterN
. This way, containers can query their own hostnames
and talk to other containers in the cluster.
The docker architecture drives the implementation of the akka cluster code.
The configuration value akka.remote.netty.tcp.hostname
is not set in the
resource file application.conf.
Instead, the hostname value is set programmatically since all containers contain the same image.
The main method handles the setup
val hostname: String = { val inetAddr = InetAddress.getLocalHost() inetAddr.getHostName() } val config = ConfigFactory .parseString(s"akka.remote.netty.tcp.hostname=$hostname") .withFallback(ConfigFactory.load())
The code above fetches the hostname of the node, which was set in the docker run command, and then apply it to the configuration used by akka.
Also, seed nodes are not set in the configuration file. Instead, we assume that
the first node is always present at the creation of the cluster. During
bootstrap all nodes join the first node kluster1
.
The following snippet of code is executed by all nodes
val addr = Address("akka.tcp", system.name, "kluster1", 2550) val cluster = Cluster(system) cluster.join(addr)
You can follow the logs using docker. For example, to check the logs from kluster1 you can run:
docker logs -f kluster1
After making changes to the scala code you can build the code and redeploy the cluster by just running:
./run.sh -f
You can test the side effects of adding or removing nodes to the cluster using docker.
For example, to remove kluster3
run
docker kill kluster3
To add a new node, say, kluster4
, run
docker run --rm -itd --expose=8080 --expose=2550 --network=kluster --hostname=kluster4 --name=kluster4 kluster
©2023 daniberg.com