Apache Brooklyn#
Intro#
Apache Brooklyn is currently an incubating Apache project.Use (yaml) blueprints to model your application (components) and describe the required infrastructure. But also deploy your app and manage (monitor) your application.
There is a Catalog
with components to choose from, or write your own.
It has a nice web ui, but also everything available via REST interfaces.
Resources#
Installation#
Well, that is very easy:
- download tarball from https://brooklyn.incubator.apache.org/download/index.html
tar -zxf brooklyn-0.7.0-incubating-dist.tar.gz cd brooklyn-0.7.0-incubating bin/brooklyn launch
It will log to 2 files in the current directory brooklyn.info.log brooklyn.debug.log.
If you have not created a ~/.brooklyn/brooklyn.properties file with special settings, you will get anonymous admin access at http://localhost:8081
, but only if you come from localhost. If you come from other hosts (like when you run it in a docker container then you get basic auth), the password is generated each time the server is started and is logged to the brooklyn.info.log file:
2015-08-08 19:12:56,404 INFO b.r.s.p.BrooklynUserWithRandomPasswordSecurityProvider [brooklyn-jetty-server-8081-qtp1042232199-22]: Allowing access to web console from localhost or with brooklyn:m01u2ll1H2
I decided to run it in a Docker container, the Dockerfile and other stuff are in my private my gitblit
.
I also have a Docker container for brooklyn nodes (so we can get very predictable targets for brooklyn).
Both Dockerfiles are "subclassed" from phusion/baseimage.
Using#
Get Started on localhost#
I first followed the get started
and the deploying a blueprint
, which deploys a MySQL DB, a Tomcat7 server and an nginx frontending webserver, all to localhost.
This went well, but make sure that the user brooklyn can ssh to localhost with pub/priv key, no password and no password phrase, and that this user can sudo su - to do all the necessary stuff (the main reason to run it in a Docker container).
So this went rather smooth, note that in the above example you can run all components (MySQL, Tomcat, nginx) on the same target (location), namely localhost.
Deploy to other hosts #
The next experiment was to deploy to a host other than the host where the brooklyn server is running. So, therefore I fired up a second Docker container, arranged ssh and sudo access to that, and tried to deploy the following blueprint :
name: webnode1
services:
- type: brooklyn.entity.webapp.ControlledDynamicWebAppCluster
name: My Web
location:
byon:
hosts:
- brooklyn@172.17.0.76
brooklyn.config:
wars.root: http://search.maven.org/remotecontent?filepath=io/brooklyn/example/brooklyn-example-hello-world-sql-webapp/0.6.0/brooklyn-example-hello-world-sql-webapp-0.6.0.war
java.sysprops:
brooklyn.example.db.url: >
$brooklyn:formatString("jdbc:%s%s?user=%s&password=%s",component("db").attributeWhenReady("datastore.url"),"visitors", "brooklyn", "br00k11n")
- type: brooklyn.entity.database.mysql.MySqlNode
id: db
name: My DB
location:
byon:
hosts:
- brooklyn@172.17.0.76
brooklyn.config:
creationScriptUrl: https://bit.ly/brooklyn-visitors-creation-script
Which basically is a copy of the previous excercise. Note that 172.17.0.76 is the IP address of the second Docker container brooklyn-node1.
This kept failing with No machines available in FixedListMachineProvisioningLocation.
Googled this, but in general you do not get much results foor Apache Brooklyn. After poking around quite a bit I concluded (not sure) that brooklyn cannot run the tomcat server on the same host as where nginx (or MySQL) is running (except for localhost)?
So I only added an additional host to the location, and it all worked fine.
Nice to see you get real time stats in your web UI (or REST if you like).
I ran a simple loadtest script against the application's URL, and you nicely see the effects on the stats.
Time for next experiment, autoscaling.
AutoScaling#
We want to be able to automatically scale the number of Tomcat instances, depending on something like response time or request rate.
First we change the Docker setup a little bit, we remove all existing containers and start 9 nodes and one brooklyn master:
docker run -d --publish 2201:22 --publish 6001:6000 --hostname brooklyn-node1 --name brooklyn-node1 brooklyn-node docker run -d --publish 2202:22 --publish 6002:6000 --hostname brooklyn-node2 --name brooklyn-node2 brooklyn-node docker run -d --publish 2203:22 --publish 6003:6000 --hostname brooklyn-node3 --name brooklyn-node3 brooklyn-node docker run -d --publish 2204:22 --publish 6004:6000 --hostname brooklyn-node4 --name brooklyn-node4 brooklyn-node docker run -d --publish 2205:22 --publish 6005:6000 --hostname brooklyn-node5 --name brooklyn-node5 brooklyn-node docker run -d --publish 2206:22 --publish 6006:6000 --hostname brooklyn-node6 --name brooklyn-node6 brooklyn-node docker run -d --publish 2207:22 --publish 6007:6000 --hostname brooklyn-node7 --name brooklyn-node7 brooklyn-node docker run -d --publish 2208:22 --publish 6008:6000 --hostname brooklyn-node8 --name brooklyn-node8 brooklyn-node docker run -d --publish 2209:22 --publish 6009:6000 --hostname brooklyn-node9 --name brooklyn-node9 brooklyn-node docker run -d --publish 2200:22 --publish 18081:8081 --hostname brooklyn-master --name brooklyn-master --link brooklyn-node1:brooklyn-node1 --link brooklyn-node2:brooklyn-node2 --link brooklyn-node3:brooklyn-node3 --link brooklyn-node4:brooklyn-node4 --link brooklyn-node5:brooklyn-node5 --link brooklyn-node6:brooklyn-node6 --link brooklyn-node7:brooklyn-node7 --link brooklyn-node8:brooklyn-node8 --link brooklyn-node9:brooklyn-node9 brooklyn
So, from the master, we can access all nodes by their name. (Mind that if one of the node containers go down, that is no longer true, or you manually fix the /etc/hosts file in the master).
Because we don't want to have ever random passwords for the web UI, we create a ~brooklyn/.brooklyn/brooklyn.properties file, and have the following lines in there:
brooklyn.webconsole.security.users=admin brooklyn.webconsole.security.user.admin.password=passwordAls make sure you chmod 700 brooklyn.properties or the server will refuse to start :-) . And kill the brooklyn process (it is restarted automagically).
Brooklyn has, by default the following locations configured in brooklyn.properties:
aws-california aws-ireland aws-oregon aws-tokyo localhost
Now we add in there :
brooklyn.location.named.dockerpool=byon:(hosts="brooklyn-node{1-9}")
Now we reload the properties via the Web UI (no brooklyn restart required).
Run a Tomcat8 server.#
Use pools of locations by name #
We want to use a pool of "servers" by name. I think it can be done by specifying locations in the brooklyn.properties file, and for example having a bunch of Docker containers available.
Miscellaneous#
- You can remove an application by selecting it in the left pane, selecting "Advanced" in the right pane, and the choose "Expunge".
- If your VM or container is rebooted/restarted, all brooklyn services are not automagically started....(to be tested, but make sure the container keeps the same IP address after restart)
