After a couple of years in production, we decided to reboot the Arken project to realign it on the new evolutions of the Docker ecosystem. As we started using Docker very early, it meant that we wanted to take advantage of Compose, Software Defined Network and volume plugins.

The Arken Features

Let's start by exposing the Arken features. Arken basically brings you features, such as dynamic, state aware reverse proxying, and passivation of services.

When you start a service in Arken, the Gogeta reverse proxy knows its domain and its state. That way it can give the user some waiting pages or 404 pages when the service is starting or is down.
Gogeta also tracks the last time a service has been accessed and stores it in the Arken service's state.

This leads us to the second feature of Arken: passivation. Given the last access time of a service, we can say that if it has not been accessed for, let's say, 12 hours, then we want to passivate the service. That means that we stop the service container, freeing the CPU and memory but keeping data. When a user wants to acces the service, Gogeta knows that it has been passivated and can ask Arken to start it transparently.

Rancher as an Accelerator

When looking at all new technologies of the Docker ecosystem, we noticed that Rancher was as a solution that could help us a lot in migrating our own system. It handles your Docker infrastructure and exposes a nice high level API to start services based on docker-compose templates.

It also features a catalog of templates that you can reference to start your services. Arken will now launch services based on those templates since you can write your own.

Besides that, your services deserve their own private network and should be able to talk together by using their names, which are resolvable through a DNS query. So now the domain name of your database is simply db.

Another cool thing is the health service that allows to check your services and then updates their state accordingly. This is something we had to do on our own with the first version of Arken: now we just have to subscribe to the Rancher event bus and catch the state change events to update the Arken state.

Give It a Try!

Before anything else, you need a Rancher infrastructure setup. In this sample, we will use a Rancher server running on a Docker host at 192.168.99.100 and a Rancher agent on 192.168.99.101.

In the settings page of the Rancher UI, we will create a new API key for Arken. This way, Arken will be able to send commands to the the Rancher infrastructure.

New Rancher API key

In order to have the definition of the Arken template we will also add the Arken catalog to Rancher whose adress is: https://
github.com/arkenio/rancher-catalog

Add Rancher Catelog

That's all you need to set up before starting our Arken service. Now just go to the Catalog page and you should be able to see an Arken template. To start it you will need the API endpoint of this Rancher environment (something like http://192.168.99.100:8080/v1/projects/1a5) and the Access and Secret keys we created.

As Arken relies on etcd to store its state, we are asked how many etcd nodes we want to start. By default, it's set to 3 but in order to test you can rely only on one etcd node (in production it must be an even number equal or greater than 3).

Launch Arken

Arken Running

When clicking on "Launch", your Arken services will start and will be available on our Rancher Agent node. You can browse the API documentation at http://192.168.99.101:8888/doc.

Arken API Documentation

And now, we can start our service with Arken by launching a create command:

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{
    "name": "nxio-000001",
    "domain": "mynuxeo.arken.io",
    "config": {
        "rancherInfo": {
            "templateId": "community2:nuxeo:0"
        }
    }
}' 'http://192.168.99.101:8888/api/v1/services'

A new nxio-000001 stack is created, and to start it you can launch:

curl -X PUT --header 'Accept: application/json' 'http://192.168.99.101:8888/api/v1/services/nxio-000001?action=start'

After a few moments, your stack should be green and available at http://mynuxeo.arken.io/ address. In order for domain name resolution to work properly, you have to set up a DNS masquerading so that every *.arken.io adress resolves to 192.168.99.101. In a production setup, you would set up a front load balancer that would balance the load over all the Gogeta instances in the cluster, and a catchall DNS entry would point to that load balancer.

One thing to know is that Gogeta forwards the request by convention to the lb service of the Rancher stack. So in order to make your stack Arken compliant you have to add a front load balancer service to it. It's very easy to set that up through Rancher templates with something like this in your template:

    lb:
      expose:
      - 80:8080
      image: rancher/load-balancer-service
      links:
      - nuxeo:nuxeo

Conclusion

Arken adds a thin higher level API on top of Rancher and drives the creation of stacks based on templates. It adds a dynamic reverse proxy that allows to assign a domain name to your service and passivates them if they are not used.

Compared to our first implementation (etcd + fleet + shell + shell + shell), Rancher drastically simplifies the infrastructure and gives a clear separation of concerns that allows every piece of the infrastructure to be well tested.