├── Makefile ├── README.md ├── apps └── example.yaml └── docker-compose.yml /Makefile: -------------------------------------------------------------------------------- 1 | YAML2JSON = ( python -c 'import sys, yaml, json; json.dump(yaml.load(sys.stdin), sys.stdout, indent=4)' 2>/dev/null || ruby -ryaml -rjson -e 'puts JSON.pretty_generate(YAML.load(ARGF))' ) 2 | MARATHON_CURL = curl -s -X PUT -H "Content-type: application/json" -d @- 3 | 4 | DOCKER_IP ?= 127.0.0.1 5 | export DOCKER_IP 6 | 7 | .PHONY: deploy 8 | deploy: 9 | $(YAML2JSON) < apps/$(APP).yaml | $(MARATHON_CURL) http://dev:8080/v2/groups | jq . 10 | 11 | .PHONY: run 12 | run: 13 | docker-compose up 14 | 15 | .PHONY: start 16 | start: 17 | docker-compose up -d 18 | 19 | .PHONY: stop 20 | stop: 21 | docker-compose stop 22 | 23 | .PHONY: destroy 24 | destroy: stop 25 | docker-compose rm -fv 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mesos in one command 2 | 3 | This is docker compose config inspired by [blog post by Sebastien Goasguen] 4 | (http://sebgoa.blogspot.com/2015/03/1-command-to-mesos-with-docker-compose.html). 5 | 6 | It uses official images from mesosphere and host networking to enable 7 | interactions with tasks over real network. It also enables docker containerizer. 8 | No state is persisted between runs so feel free to start over if you 9 | screwed cluster state or something. 10 | 11 | ## Versions 12 | 13 | * Mesos 1.0.1 14 | * Marathon 1.3.0 15 | * Chronos 2.4.0 (optional) 16 | * Metronome 0.2.0 (optional) 17 | 18 | Note that you need `docker-compose` 1.6.0 or newer: 19 | 20 | * https://github.com/docker/compose 21 | 22 | ## Compatibility 23 | 24 | This project should work out of the box with docker machine. It requires 25 | host networking to work, so docker for mac won't work. 26 | 27 | If you have docker built dynamically, which is the case on most distros, 28 | you should download and bind-mount statically linked docker client: 29 | 30 | ``` 31 | curl -sL https://get.docker.com/builds/Linux/x86_64/docker-1.11.1.tgz | \ 32 | tar xv --strip-components 1 -C /usr/local/bin 33 | ``` 34 | 35 | This downloads docker 1.11.1 and installs binaries into `/usr/local/bin`. 36 | 37 | ## Usage 38 | 39 | You have to specify `DOCKER_IP` env variable in order to make Mesos work 40 | properly. The default value is `127.0.0.1` and it should work if you have 41 | Docker daemon running locally. 42 | 43 | If you use `docker-machine` you can do the following, assuming `dev` is your 44 | machine's name: 45 | 46 | ``` 47 | export DOCKER_IP=$(docker-machine ip dev) 48 | ``` 49 | 50 | Run your cluster in the background (equivalent to `docker-compose up -d`): 51 | 52 | ``` 53 | make start 54 | ``` 55 | 56 | That's it, use the following URLs: 57 | 58 | * http://$DOCKER_IP:5050/ for Mesos master UI 59 | * http://$DOCKER_IP:5051/ for the first Mesos slave UI 60 | * http://$DOCKER_IP:5052/ for the second Mesos slave UI 61 | * http://$DOCKER_IP:8080/ for Marathon UI 62 | * http://$DOCKER_IP:8888/ for Chronos UI 63 | * http://$DOCKER_IP:8081/ for Metronome UI (REST API) 64 | 65 | If you want to run your cluster in foreground to see logs and be able to stop 66 | it with Ctrl+C, use the following (equivalent to `docker-compose up`): 67 | 68 | ``` 69 | make run 70 | ``` 71 | 72 | To kill your cluster and wipe all state to start fresh: 73 | 74 | ``` 75 | make destroy 76 | ``` 77 | 78 | This is equivalent to issuing `docker-compose stop && docker-compose rm -f -v`. 79 | 80 | ## Task recovery 81 | 82 | Since Mesos slaves run in containers and everything is killed when container 83 | is stopped, there is no possibility to test task recovery. You might think 84 | that docker container recovery is still possible, but you are wrong: 85 | 86 | * https://issues.apache.org/jira/browse/MESOS-3573 87 | 88 | ## Optional services 89 | 90 | In `docker-compose.yml` you can uncomment additional containers. 91 | 92 | ### Second mesos-slave 93 | 94 | Uncomment `slave-two` section to get access to the second mesos-slave. Port 95 | ranges of two mesos-slaves are separated so it shouldn't be an issue. 96 | 97 | Note that both slaves share same memory so you might see OOM if you allocate 98 | and use more memory than your docker host has. 99 | 100 | ### Chronos 101 | 102 | Uncomment `chronos` section to get access to Chronos framework. 103 | 104 | ### Metronome 105 | 106 | Uncomment `metronome` section to get access to Metronome framework. 107 | 108 | ## Deploying on marathon 109 | 110 | A sample app definition in YAML is included for your convenience in `apps` dir. 111 | Use the following command to deploy it: 112 | 113 | ``` 114 | make APP=example deploy 115 | ``` 116 | 117 | Feel free to add your apps to `apps` and deploy them similarly. 118 | -------------------------------------------------------------------------------- /apps/example.yaml: -------------------------------------------------------------------------------- 1 | id: /example 2 | apps: 3 | - id: where 4 | cpus: 0.1 5 | mem: 32 6 | ports: 7 | - 0 8 | instances: 2 9 | container: 10 | type: DOCKER 11 | docker: 12 | image: bobrik/mesos-where-am-i 13 | healthChecks: 14 | - protocol: HTTP 15 | path: / 16 | gracePeriodSeconds: 3 17 | intervalSeconds: 10 18 | timeoutSeconds: 10 19 | maxConsecutiveFailures: 3 20 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | 3 | services: 4 | zk: 5 | image: bobrik/zookeeper 6 | network_mode: host 7 | environment: 8 | ZK_CONFIG: tickTime=2000,initLimit=10,syncLimit=5,maxClientCnxns=128,forceSync=no,clientPort=2181 9 | ZK_ID: 1 10 | 11 | master: 12 | image: mesosphere/mesos-master:1.0.1-2.0.93.ubuntu1404 13 | network_mode: host 14 | environment: 15 | MESOS_ZK: zk://127.0.0.1:2181/mesos 16 | MESOS_QUORUM: 1 17 | MESOS_CLUSTER: docker-compose 18 | MESOS_REGISTRY: replicated_log # default is in_memory for some reason 19 | MESOS_HOSTNAME: ${DOCKER_IP} 20 | LIBPROCESS_IP: ${DOCKER_IP} 21 | depends_on: 22 | - zk 23 | 24 | slave-one: 25 | image: mesosphere/mesos-slave:1.0.1-2.0.93.ubuntu1404 26 | network_mode: host 27 | pid: host 28 | environment: 29 | MESOS_MASTER: zk://127.0.0.1:2181/mesos 30 | MESOS_CONTAINERIZERS: docker,mesos 31 | MESOS_PORT: 5051 32 | MESOS_RESOURCES: ports(*):[11000-11999] 33 | MESOS_HOSTNAME: ${DOCKER_IP} 34 | LIBPROCESS_IP: ${DOCKER_IP} 35 | MESOS_WORK_DIR: /tmp/mesos 36 | volumes: 37 | - /sys/fs/cgroup:/sys/fs/cgroup 38 | - /usr/local/bin/docker:/usr/bin/docker 39 | - /var/run/docker.sock:/var/run/docker.sock 40 | depends_on: 41 | - zk 42 | 43 | # slave-two: 44 | # image: mesosphere/mesos-slave:1.0.1-2.0.93.ubuntu1404 45 | # network_mode: host 46 | # pid: host 47 | # environment: 48 | # MESOS_MASTER: zk://127.0.0.1:2181/mesos 49 | # MESOS_CONTAINERIZERS: docker,mesos 50 | # MESOS_PORT: 5052 51 | # MESOS_RESOURCES: ports(*):[12000-12999] 52 | # MESOS_HOSTNAME: ${DOCKER_IP} 53 | # LIBPROCESS_IP: ${DOCKER_IP} 54 | # volumes: 55 | # - /sys/fs/cgroup:/sys/fs/cgroup 56 | # - /usr/local/bin/docker:/usr/bin/docker 57 | # - /var/run/docker.sock:/var/run/docker.sock 58 | # depends_on: 59 | # - zk 60 | 61 | marathon: 62 | image: mesosphere/marathon:v1.3.0 63 | network_mode: host 64 | environment: 65 | MARATHON_MASTER: zk://127.0.0.1:2181/mesos 66 | depends_on: 67 | - zk 68 | 69 | # chronos: 70 | # image: mesosphere/chronos:chronos-2.4.0-0.1.20151007110204.ubuntu1404-mesos-0.24.1-0.2.35.ubuntu1404 71 | # command: /usr/bin/chronos run_jar --http_port 8888 --master zk://127.0.0.1:2181/mesos --zk_hosts zk://127.0.0.1:2181/mesos 72 | # network_mode: host 73 | # depends_on: 74 | # - zk 75 | 76 | # metronome: 77 | # image: mesoshq/metronome:0.2.0 78 | # network_mode: host 79 | # environment: 80 | # metronome_mesos_master_url: ${DOCKER_IP}:5050 81 | # metronome_zk_url: zk://127.0.0.1:2181/mesos 82 | # PORT0: 8081 83 | # LIBPROCESS_IP: ${DOCKER_IP} 84 | # depends_on: 85 | # - zk 86 | # - master 87 | --------------------------------------------------------------------------------