Beethoven is an application written in Go that automatically configures Nginx for applications deployed on Marathon/Mesos. Beethoven runs in Docker and can be managed by Marathon to provide HTTP load balancing.

Feature Highlights

Uses NGINX for HTTP based load balancing

Handlebars for powerful template parsing

Zero downtime load balancing when changes occur

Allows stream filtering so NGINX re-configuration is only triggered by RegEx patterns

Listens to the realtime SSE from Marathon to quickly change upstreams based on application/tasks state changes

Mesosphere Marathon has adapted their plugin interface, offering two extension points. This includes the ability to have custom plugins handling UI/Rest based authentication as well as securing operations.

I looked around to see what has been released in the open source community and didn’t see much. I wanted to be able to lock down Marathon based on the following requirements:

UI/REST based authentication against LDAP / Active Directory

Ability to offer flexible configuration based on LDAP Groups, for example:

Everyone who is authenticated should be able to see running containers

Admins have unlimited control

Developers can do full CRUD operations against an ID namespace of /dev

As a result of these requirements I decided to create the Marathon-LDAP Plugin. This article will cover how easy it is to secure your Marathon clusters against an LDAP server.

Group Support: Support for creating advanced deployment groups with nested dependencies

Output Format: All output and responses can be outputted in CLI Tabular, JSON or YAML formats

Property Substitution: Supports ${PROPERTY} substitution within the application descriptor. For example you can inject values from the build system directly into the template which resolves and deploys

Async/Sync Deployments: Depcon allows you to deploy an application and either wait for it to become healthy or simply deploy and exit allowing you to poll on your own frequency using Depcon.

Environment Configuration: Depcon creates and uses a configuration file which allows you to define preferred global options as well as named environments. With named environments authentication details and endpoint info is saved allowing you to switch between environments quickly.

Recently I had a project where I was dealing with large file systems that had to be spanned and preserved against 100’s of Docker services for computation. I decided to use Amazons EFS which was recently announced at re:Invent 2015.

I setup the file system which was easy and attempted to play with it. I first mounted it manually via NFS4 on one of the Mesos
slaves. It worked and initial tests showed great performance. Now
the next step was meeting some of my personal requirements before I could call this successful.

My requirements were:

The file system should be mounted when needed within a Docker container and tore down when no longer in use

EFS provides endpoints in each availability zone so I also needed to support dynamic linking based on which slave the container was running in and the corresponding endpoint matching the AZ.

Must use NFS4 (This is what EFS supports)

Did not want to create or modify existing container images to attempt to mount NFS within the container itself. This also would mean the container would need to run in privileged mode which I’m against

After analysis, I decided the best choice was to write a plugin myself to extend the Docker engine.

Docker Volume Plugins

Docker volume plugins enable Docker deployments to be integrated with external storage systems. A volume plugin makes use of the -v and --volume-driver flag on the docker run command. For example:

This command passes the volumename through to the volume plugin as a user-given name for the volume.

By having the user specify a volumename, a plugin can associate the volume to an external volume beyond the lifetime of a single container or container host. This can be used, for example, to move a stageful container from one server to another.

Meet Docker-Volume-Netshare Plugin

Before I began coding a plugin I wanted to pre-define some requirements. Here’s some of them below:

Write it in Go so it runs at native speed

Support NFS 3/4 and CIFS (might come in handy someday)

For EFS support the plugin will lookup local EC2 metadata on the slave to find the corresponding AZ and region for building the URI from the File System ID

Must support volume management

Understand when a volume is already mounted and keep track of its connections

If a container is stopped determining based on active connections if the volume mount should be removed

Support all of the Docker Plugin API

After designing the plugin I installed it on the slaves (container hosts) and as a result I was able to dynamically mount EFS volumes and link them into the container based on the specified target mount.

OpenStack4j is a fluent OpenStack client that allows provisioning and control of an OpenStack deployment. This includes support for Identity, Compute, Image, Network, Block Storage, Telemetry, Data Processing as well as many extensions (LBaaS, FWaaS, Quota-Set and many more)

About Jeremy

I'm Jeremy Unruh, a longtime developer, architect, leader and entrepreneur. I love engineering and have a strong passion for cloud computing and service architecture using containers. Welcome to my blog!