GithubHelp home page GithubHelp logo

doytsujin / akka-cluster-on-kubernetes Goto Github PK

View Code? Open in Web Editor NEW

This project forked from lkysow/akka-cluster-on-kubernetes

0.0 1.0 0.0 10 KB

Sample project for deploying Akka Cluster to Kubernetes. Presented at Scala Up North on July 21, 2017.

Scala 100.00%

akka-cluster-on-kubernetes's Introduction

Akka Cluster on Kubernetes

Sample project for deploying Akka Cluster to Kubernetes. Presented at Scala Up North on July 21, 2017. Video of presentation: https://www.youtube.com/watch?v=Esd1UKIpvdU

To run the project yourself:

Create a Kubernetes Cluster

Follow https://cloud.google.com/container-engine/docs/quickstart to create a Kubernetes cluster in minutes.

I recommend getting kubectl set up locally which means you need to install the gcloud SDK: https://cloud.google.com/sdk/docs/quickstarts

Then click the Connect button next to your cluster name here: https://console.cloud.google.com/kubernetes/list to set up kubectl

Run Locally Without Etcd

The master branch is set up to run with etcd so if you want to run locally then you'll need to uncomment the seed-node config in src/main/resources/application.conf

// src/main/resources/application.conf
...
  cluster {
    roles = [frontend, backend]
    // uncomment this if running locally
    seed-nodes = [
      "akka.tcp://[email protected]:2551"
    ]
  }

Then you can run the project and curl the HTTP endpoint.

➜ sbt run
[info] Running com.hootsuite.akkak8s.SimpleClusterApp
[INFO] [07/21/2017 13:51:35.643] [run-main-0] [akka.remote.Remoting] Starting remoting
[INFO] [07/21/2017 13:51:36.052] [run-main-0] [akka.remote.Remoting] Remoting started; listening on addresses :[akka.tcp://[email protected]:2551]
[INFO] [07/21/2017 13:51:36.075] [run-main-0] [akka.cluster.Cluster(akka://ClusterSystem)] Cluster Node [akka.tcp://[email protected]:2551] - Starting up...
[INFO] [07/21/2017 13:51:36.269] [run-main-0] [akka.cluster.Cluster(akka://ClusterSystem)] Cluster Node [akka.tcp://[email protected]:2551] - Registered cluster JMX MBean [akka:type=Cluster]
[INFO] [07/21/2017 13:51:36.269] [run-main-0] [akka.cluster.Cluster(akka://ClusterSystem)] Cluster Node [akka.tcp://[email protected]:2551] - Started up successfully
[INFO] [07/21/2017 13:51:36.365] [ClusterSystem-akka.actor.default-dispatcher-14] [akka.tcp://[email protected]:2551/system/constructr] Stopping self, because seed-nodes defined
[INFO] [07/21/2017 13:51:36.411] [ClusterSystem-akka.actor.default-dispatcher-3] [akka.cluster.Cluster(akka://ClusterSystem)] Cluster Node [akka.tcp://[email protected]:2551] - Node [akka.tcp://[email protected]:2551] is JOINING, roles [frontend, backend]
[INFO] [07/21/2017 13:51:36.463] [ClusterSystem-akka.actor.default-dispatcher-3] [akka.cluster.Cluster(akka://ClusterSystem)] Cluster Node [akka.tcp://[email protected]:2551] - Leader is moving node [akka.tcp://[email protected]:2551] to [Up]

And now curl the app

➜ curl "http://localhost:8080?msg=about+a+hotdog"
Hot Dog! (from fe: xxxxxxxx be: xxxxxxxx)%
➜ curl "http://localhost:8080?msg=about+a+dog"
Not Hot Dog :( (from fe: xxxxxxxx be: xxxxxxxx)%

Run Locally With Etcd

In Kubernetes, we need to use the constructr library to discover other seed nodes.

To test this out locally, comment out the seed-nodes config

    roles = [frontend, backend]
    // uncomment this if running locally
//    seed-nodes = [
//      "akka.tcp://[email protected]:2551"
//    ]

And start etcd with Docker for Mac.

➜ docker run -d \
  --name etcd \
  --publish 2379:2379 \
  quay.io/coreos/etcd:v2.3.7 \
  --listen-client-urls http://0.0.0.0:2379 \
  --advertise-client-urls http://192.168.99.100:2379

Finally, restart the app

➜ sbt run

[info] Running com.hootsuite.akkak8s.SimpleClusterApp
[INFO] [07/21/2017 13:50:16.051] [run-main-0] [akka.remote.Remoting] Starting remoting
[INFO] [07/21/2017 13:50:16.503] [run-main-0] [akka.remote.Remoting] Remoting started; listening on addresses :[akka.tcp://[email protected]:2551]
[INFO] [07/21/2017 13:50:16.530] [run-main-0] [akka.cluster.Cluster(akka://ClusterSystem)] Cluster Node [akka.tcp://[email protected]:2551] - Starting up...
[INFO] [07/21/2017 13:50:16.870] [run-main-0] [akka.cluster.Cluster(akka://ClusterSystem)] Cluster Node [akka.tcp://[email protected]:2551] - Registered cluster JMX MBean [akka:type=Cluster]
[INFO] [07/21/2017 13:50:16.870] [run-main-0] [akka.cluster.Cluster(akka://ClusterSystem)] Cluster Node [akka.tcp://[email protected]:2551] - Started up successfully
[INFO] [07/21/2017 13:50:16.933] [ClusterSystem-akka.actor.default-dispatcher-6] [akka.cluster.Cluster(akka://ClusterSystem)] Cluster Node [akka.tcp://[email protected]:2551] - No seed-nodes configured, manual cluster join required
[INFO] [07/21/2017 13:50:16.951] [ClusterSystem-akka.actor.default-dispatcher-2] [akka.tcp://[email protected]:2551/system/constructr] Creating constructr-machine, because no seed-nodes defined
[INFO] [07/21/2017 13:50:20.348] [ClusterSystem-akka.actor.default-dispatcher-6] [akka.cluster.Cluster(akka://ClusterSystem)] Cluster Node [akka.tcp://[email protected]:2551] - Node [akka.tcp://[email protected]:2551] is JOINING, roles [frontend, backend]
[INFO] [07/21/2017 13:50:20.370] [ClusterSystem-akka.actor.default-dispatcher-6] [akka.cluster.Cluster(akka://ClusterSystem)] Cluster Node [akka.tcp://[email protected]:2551] - Leader is moving node [akka.tcp://[email protected]:2551] to [Up]

And now curl the app again

➜ curl "http://localhost:8080?msg=about+a+hotdog"
Hot Dog! (from fe: xxxxxxxx be: xxxxxxxx)%
➜ curl "http://localhost:8080?msg=about+a+dog"
Not Hot Dog :( (from fe: xxxxxxxx be: xxxxxxxx)%

Package into Docker

➜ sbt assembly
# outputs target/scala-2.12/akka-cluster-on-kubernetes-assembly-0.1.jar
# now build that into a docker image
➜ docker build -t {your namespace}/akka-cluster .

Test Locally With Docker Compose

We still need etcd but we want it accessible from the same network as our app which is now running on Docker, not on localhost. To do this we use Docker Compose.

➜ docker-compose up

Starting akkaclusteronkubernetes_etcd_1 ...
Starting akkaclusteronkubernetes_etcd_1 ... done
Starting akkaclusteronkubernetes_akka_1 ...
Starting akkaclusteronkubernetes_akka_1 ... done
Attaching to akkaclusteronkubernetes_etcd_1, akkaclusteronkubernetes_akka_1
etcd_1  | 2017-07-21 21:08:21.112937 I | etcdmain: etcd Version: 2.3.7
etcd_1  | 2017-07-21 21:08:21.113016 I | etcdmain: Git SHA: fd17c91
etcd_1  | 2017-07-21 21:08:21.113026 I | etcdmain: Go Version: go1.6.2
etcd_1  | 2017-07-21 21:08:21.113041 I | etcdmain: Go OS/Arch: linux/amd64
etcd_1  | 2017-07-21 21:08:21.113052 I | etcdmain: setting maximum number of CPUs to 2, total number of available CPUs is 2
etcd_1  | 2017-07-21 21:08:21.113058 W | etcdmain: no data-dir provided, using default data-dir ./default.etcd
etcd_1  | 2017-07-21 21:08:21.113834 N | etcdmain: the server is already initialized as member before, starting as etcd member...
etcd_1  | 2017-07-21 21:08:21.114360 I | etcdmain: listening for peers on http://localhost:2380
etcd_1  | 2017-07-21 21:08:21.114539 I | etcdmain: listening for peers on http://localhost:7001
etcd_1  | 2017-07-21 21:08:21.114584 I | etcdmain: listening for client requests on http://0.0.0.0:2379
etcd_1  | 2017-07-21 21:08:21.124405 I | etcdserver: name = default
etcd_1  | 2017-07-21 21:08:21.124445 I | etcdserver: data dir = default.etcd
etcd_1  | 2017-07-21 21:08:21.124453 I | etcdserver: member dir = default.etcd/member
etcd_1  | 2017-07-21 21:08:21.124461 I | etcdserver: heartbeat = 100ms
etcd_1  | 2017-07-21 21:08:21.124465 I | etcdserver: election = 1000ms
etcd_1  | 2017-07-21 21:08:21.124470 I | etcdserver: snapshot count = 10000
etcd_1  | 2017-07-21 21:08:21.124505 I | etcdserver: advertise client URLs = http://0.0.0.0:2379
etcd_1  | 2017-07-21 21:08:21.128006 I | etcdserver: restarting member ce2a822cea30bfca in cluster 7e27652122e8b2ae at commit index 424
etcd_1  | 2017-07-21 21:08:21.128122 I | raft: ce2a822cea30bfca became follower at term 10
etcd_1  | 2017-07-21 21:08:21.128165 I | raft: newRaft ce2a822cea30bfca [peers: [], term: 10, commit: 424, applied: 0, lastindex: 424, lastterm: 10]
etcd_1  | 2017-07-21 21:08:21.130984 I | etcdserver: starting server... [version: 2.3.7, cluster version: to_be_decided]
etcd_1  | 2017-07-21 21:08:21.134951 N | etcdserver: added local member ce2a822cea30bfca [http://localhost:2380 http://localhost:7001] to cluster 7e27652122e8b2ae
etcd_1  | 2017-07-21 21:08:21.135076 N | etcdserver: set the initial cluster version to 2.3
etcd_1  | 2017-07-21 21:08:22.431440 I | raft: ce2a822cea30bfca is starting a new election at term 10
etcd_1  | 2017-07-21 21:08:22.431735 I | raft: ce2a822cea30bfca became candidate at term 11
etcd_1  | 2017-07-21 21:08:22.431922 I | raft: ce2a822cea30bfca received vote from ce2a822cea30bfca at term 11
etcd_1  | 2017-07-21 21:08:22.432299 I | raft: ce2a822cea30bfca became leader at term 11
etcd_1  | 2017-07-21 21:08:22.432405 I | raft: raft.node: ce2a822cea30bfca elected leader ce2a822cea30bfca at term 11
etcd_1  | 2017-07-21 21:08:22.433347 I | etcdserver: published {Name:default ClientURLs:[http://0.0.0.0:2379]} to cluster 7e27652122e8b2ae
akka_1  | [INFO] [07/21/2017 21:08:24.309] [main] [akka.remote.Remoting] Starting remoting
akka_1  | [INFO] [07/21/2017 21:08:24.670] [main] [akka.remote.Remoting] Remoting started; listening on addresses :[akka.tcp://[email protected]:2551]
akka_1  | [INFO] [07/21/2017 21:08:24.696] [main] [akka.cluster.Cluster(akka://ClusterSystem)] Cluster Node [akka.tcp://[email protected]:2551] - Starting up...
akka_1  | [INFO] [07/21/2017 21:08:24.936] [main] [akka.cluster.Cluster(akka://ClusterSystem)] Cluster Node [akka.tcp://[email protected]:2551] - Registered cluster JMX MBean [akka:type=Cluster]
akka_1  | [INFO] [07/21/2017 21:08:24.936] [main] [akka.cluster.Cluster(akka://ClusterSystem)] Cluster Node [akka.tcp://[email protected]:2551] - Started up successfully
akka_1  | [INFO] [07/21/2017 21:08:25.005] [ClusterSystem-akka.actor.default-dispatcher-5] [akka.cluster.Cluster(akka://ClusterSystem)] Cluster Node [akka.tcp://[email protected]:2551] - No seed-nodes configured, manual cluster join required
akka_1  | [INFO] [07/21/2017 21:08:25.006] [ClusterSystem-akka.actor.default-dispatcher-2] [akka.tcp://[email protected]:2551/system/constructr] Creating constructr-machine, because no seed-nodes defined
akka_1  | [INFO] [07/21/2017 21:08:27.112] [ClusterSystem-akka.actor.default-dispatcher-4] [akka.cluster.Cluster(akka://ClusterSystem)] Cluster Node [akka.tcp://[email protected]:2551] - Node [akka.tcp://[email protected]:2551] is JOINING, roles [frontend, backend]
akka_1  | [INFO] [07/21/2017 21:08:27.143] [ClusterSystem-akka.actor.default-dispatcher-4] [akka.cluster.Cluster(akka://ClusterSystem)] Cluster Node [akka.tcp://[email protected]:2551] - Leader is moving node [akka.tcp://[email protected]:2551] to [Up]

Deploy to Kubernetes

Finally we're ready to deploy to Kubernetes!

First deploy etcd

➜ docker push {your namespace}/akka-cluster .
➜ kubectl apply -f kubernetes/etcd.yaml

Run a "bounce" pod so you can talk to the cluster easily. I'm using my colleague's debug container which has a bunch of tools built in: https://github.com/markeijsermans/docker-debug.

➜ kubectl run bounce --image=markeijsermans/debug -it bash
If you don't see a command prompt, try pressing enter.
(21:15 bounce-2304503334-6dqpw:/) curl etcd:2379/health
{"health": "true"}

Now deploy the app! If you've been pushing your own Docker images, you'll need to edit the kubernetes/nothotdog.yaml file to use your image. Specifically these lines

...
        image: lkysow/akka-cluster
...

Push your docker image and then apply the app.

➜ docker push {your namespace}/akka-cluster
➜ kubectl apply -f kubernetes/nothotdog.yaml

From your bounce pod, you should be able to curl the app!

➜ curl nothotdog:8080?msg=about-a-hotdog
Hot Dog! (from fe: frontend-3857959296-5x885 be: backend-3899286914-6941z)

Play Around With Kubernetes

curl the app in a loop from the bounce pod

while true; do curl -sS -m 1.5 nothotdog:8080?msg=about-a-hotdog; echo ""; sleep 0.5; done
Hot Dog! (from fe: frontend-3857959296-5x885 be: backend-3899286914-6941z)
Hot Dog! (from fe: frontend-3857959296-5x885 be: backend-3899286914-6941z)
Hot Dog! (from fe: frontend-3857959296-5x885 be: backend-3899286914-6941z)

Scale the app

➜ kubectl scale deployment backend --replicas=3
➜ kubectl scale deployment frontend --replicas=3

Add autoscaling

➜ kubectl autoscale deploy backend --min=1 --max=3 --cpu-percent=5
➜ kubectl get hpa

Add some load from the bounce pod

➜ slow_cooker -concurrency 10 -qps 300 -interval 5s "http://nothotdog:8080?msg=hotdog"

And you're done! Welcome to Akka Cluster on Kubernetes :D

akka-cluster-on-kubernetes's People

Contributors

lkysow avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.