Setup marathon
Schedule long running jobs with Marathon
As already specified in the mesos theory we are diving into one of the popular framework called Marathon. We will need long running jobs like web application, load balancer, database, etc which needs to be placed in the available resources. Marathon has a good UI and good APIs through which one can submit jobs (applications in marathon context). The applications can just be a shell command or docker container to run in the servers/nodes. Along with the application description we can specify number of instances that it has to be maintained, marathon will take care of creating / destroying containers to maintain that count.
Once you create or update an application description it creates a deployment request to marathon which is evaluated further to actually deploy. There can be parallel deployments requests but marathon will run one deployment request per application. There can be dependencies between applications like web application dependent on database before starting so marathon generates a dependency graph for all deployment requests and executes the least dependent one first. Applications are grouped as groups and groups can be dependent on other groups too.
Marathon provides a way to specify constraints in application description like hostname to be unique _which makes every container to be deployed on a new node, or _hostname unlike regular expression.
Marathon provides a way to specify port mapping which is a tuple of host port and container port. Both of these can be equal to 0 which enforces marathon to provide a dynamic port which creating that application on that node. Dynamic ports are useful in scaling the application as there you cannot always ensure the same application is not running in same node where there might be a port conflict.
Marathon also sets environment variables like $PORT0 for first port and $MARATHON_APP_DOCKER_IMAGE.
Example job
{
"id": "simple-docker",
"container": {
"docker": {
"image": "busybox"
}
},
"cmd": "echo hello from docker",
"cpus": 0.2,
"mem": 32.0,
"instances": 2
}
# reference : https://mesosphere.github.io/marathon/docs/recipes.html
Reference : Topics in marathon documentation
In the code repository cloned you will have a marathon folder which has the following scripts too.
Installing marathon in master instance :
CLUSTER_NAME=dc1
PUBLIC_HOSTNAME=$(curl -s http://169.254.169.254/latest/meta-data/public-hostname)
Note: If you're running this within a private VPC, you should use local-ipv4
instead of public-hostname
.
# Create configurations file for mesos slave
sudo tee /etc/docker/marathon <<-EOF
CONSUL_IP=localhost
DC=$CLUSTER_NAME
MARATHON_MASTER=zk://$CLUSTER_NAME.zookeeper.service.consul:2181/mesos
MARATHON_ZK=zk://$CLUSTER_NAME.zookeeper.service.consul:2181/marathon
MARATHON_HOSTNAME=$PUBLIC_HOSTNAME
MARATHON_FRAMEWORK_NAME=$CLUSTER_NAME-marathon
EOF
sudo docker run --restart=always -d --name=marathon --net=host --env-file=/etc/docker/marathon flyinprogrammer/marathon
Check installation
docker logs marathon
Goto consul ui
http://<public-ip-of-mesos-master-instance>:8500/ui/#/dc1/services
You should see the marathon as one of the service in green tag
Troubleshooting
warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8): No such file or directory
This warning may from mesos-init-wrapper in /usr/bin still have to dig more
docker stop marathon && docker rm marathon
mkdir marathon && cd marathon
wget https://raw.githubusercontent.com/flyinprogrammer/docker-marathon/master/app.json .
tee Dockerfile <<-EOF
FROM flyinprogrammer/mesos-base
RUN apt-get -y update && \
apt-get -y install marathon locales libcurl4-nss-dev
RUN locale-gen en_US.UTF-8
ENV LANG=en_US.UTF-8
COPY app.json /app.json
ENV CONTAINERPILOT=file:///app.json
EXPOSE 5050
CMD ["/bin/containerpilot", "/usr/bin/marathon"]
EOF
docker build -t "my-marathon" .
docker run --restart=always -d --name=marathon --net=host --env-file=/etc/docker/marathon my-marathon
Play around !