Git Product home page Git Product logo

maestro-ng's Introduction

MaestroNG

Build Status Docs

MaestroNG is an orchestrator of Docker-based, multi-hosts environments.

The original Maestro was developed as a single-host orchestrator for Docker-based deployments. Given the state of Docker at the time of its writing, it was a great first step towards orchestration of deployments using Docker containers as the unit of application distribution.

Docker having made significant advancements since then, deployments and environments spanning across several hosts are becoming more and more common and are in the need for some orchestration.

Based off ideas from the original Maestro and taking inspiration from Docker's links feature, MaestroNG makes the deployment and control of complex, multi-host environments using Docker containers possible and easy to use. Maestro of course supports declared dependencies between services and makes sure to honor those during environment bring up.

What is Maestro?

MaestroNG is, for now, a command-line utility that allows for automatically managing the orchestrated deployment and bring up of a set of service instance containers that compose an environment on a set of target host machines.

Each host machine is expected to run a Docker daemon. Maestro will then contact the Docker daemon of each host in the environment to figure out the status of the environment and what actions to take based on the requested command.

Dependencies

MaestroNG requires Docker 0.6.7 or newer on the hosts as it makes use of the container naming feature and bug fixes in NAT port forwarding.

You'll also need the following Python modules, although these will be automatically installed by setuptools if you follow the instructions below.

  • A recent docker-py
  • PyYAML (you may need to install this manually, e.g. apt-get install python-yaml)
  • Jinja2
  • Python Requests
  • bgtunnel
  • six

If you plan on using the HipChat auditor, you'll also need python-simple-hipchat.

Installation

Maestro is distributed on the Python Package Index. You can install Maestro via Pip:

$ pip install --user --upgrade maestro-ng

If you want the bleeding edge, you can install directly from the Git repository:

$ pip install --user --upgrade git+git://github.com/signalfx/maestro-ng

Note for MacOS users

The above command may fail if you installed Python and pip via Homebrew, usually with the following error message:

error: can't combine user with prefix, exec_prefix/home, or install_(plat)base

This is because the Homebrew formula for pip configures distutils with an installation prefix, and this cannot be combined with the use of the --user flag, as describe in https://github.com/Homebrew/homebrew/wiki/Homebrew-and-Python#note-on-pip-install---user.

If you encounter this problem, simply install the package without the --user flag:

$ pip install --upgrade git+git://github.com/signalfx/maestro-ng

Use as a Docker container

First, build your maestro-ng image using :

docker build -t maestro-ng .

Then say you have a maestro-ng configuration named /fu/bar/myconf.yml

If you want to start this on a docker host without install python and its pip modules :

docker run --rm -t -i -v /fu/bar/myconf.yml:/maestro.yaml maestro-ng <start/stop/status/clean>

or, if the myconf.yml is in the current dir :

docker run --rm -t -i -v $(pwd)/myconf.yml:/maestro.yaml maestro-ng <start/stop/status/clean>

Documentation

The MaestroNG documentation is available on ReadTheDocs. For a overview of recent changes, see the ChangeLog.

License

MaestroNG is licensed under the Apache License, Version 2.0. See LICENSE for full license text.

maestro-ng's People

Contributors

acaranta avatar aeuio avatar caljess599 avatar ceasar avatar corradio avatar dankamongmen avatar ekimekim avatar ericcj avatar flokli avatar grmble avatar ivotron avatar jud avatar jverhoeven avatar krijger avatar ksatrasala avatar kuhess avatar lightcode avatar mpetazzoni avatar mzsanford avatar nikicat avatar psi-signalfuse avatar sassrobi avatar soby avatar soby-taulia avatar stefanfoulis avatar suriya avatar tedoc2000 avatar tkrille avatar wlopata-sfx avatar zsuzhengdu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

maestro-ng's Issues

Implement upgrade command

Provide an upgrade command that does the equivalent of a restart -r but only restarting containers that are not running the latest version of the image specified for that service.

  1. pull the image to refresh it
  2. check if container is running
  3. if it is, check the image SHA it is running off from
  4. if the SHA matches the pulled image, do nothing
  5. in all other cases, restart the container on the new image

The recommended install command fails on OSX.

Leaving out the --user option worked fine on OSX. Any ideas why so?

pip install --user --upgrade git+git://github.com/signalfuse/maestro-ng 

Downloading/unpacking git+git://github.com/signalfuse/maestro-ng
  Cloning git://github.com/signalfuse/maestro-ng to /var/folders/bm/hr3cq_z10418bp98j9hv0vxw0000gn/T/pip-UBQXM9-build
  Running setup.py (path:/var/folders/bm/hr3cq_z10418bp98j9hv0vxw0000gn/T/pip-UBQXM9-build/setup.py) egg_info for package from git+git://github.com/signalfuse/maestro-ng

Requirement already up-to-date: docker-py>=0.3.2 in /usr/local/lib/python2.7/site-packages (from maestro==0.2.3)
Requirement already up-to-date: pyyaml in /usr/local/lib/python2.7/site-packages (from maestro==0.2.3)
Requirement already up-to-date: jinja2 in /usr/local/lib/python2.7/site-packages (from maestro==0.2.3)
Requirement already up-to-date: six in /usr/local/lib/python2.7/site-packages (from maestro==0.2.3)
Requirement already up-to-date: bgtunnel in /usr/local/lib/python2.7/site-packages (from maestro==0.2.3)
Requirement already up-to-date: python-simple-hipchat in /usr/local/lib/python2.7/site-packages (from maestro==0.2.3)
Requirement already up-to-date: requests>=2.2.1 in /usr/local/lib/python2.7/site-packages (from docker-py>=0.3.2->maestro==0.2.3)
Requirement already up-to-date: websocket-client>=0.11.0 in /usr/local/lib/python2.7/site-packages (from docker-py>=0.3.2->maestro==0.2.3)
Requirement already up-to-date: markupsafe in /usr/local/lib/python2.7/site-packages (from jinja2->maestro==0.2.3)
Requirement already up-to-date: backports.ssl-match-hostname in /usr/local/lib/python2.7/site-packages (from websocket-client>=0.11.0->docker-py>=0.3.2->maestro==0.2.3)
Installing collected packages: maestro
  Running setup.py install for maestro
    error: can't combine user with prefix, exec_prefix/home, or install_(plat)base
    Complete output from command /usr/local/opt/python/bin/python2.7 -c "import setuptools, tokenize;__file__='/var/folders/bm/hr3cq_z10418bp98j9hv0vxw0000gn/T/pip-UBQXM9-build/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /var/folders/bm/hr3cq_z10418bp98j9hv0vxw0000gn/T/pip-y1Z3zg-record/install-record.txt --single-version-externally-managed --compile --user:
    running install

error: can't combine user with prefix, exec_prefix/home, or install_(plat)base

----------------------------------------
Cleaning up...
Command /usr/local/opt/python/bin/python2.7 -c "import setuptools, tokenize;__file__='/var/folders/bm/hr3cq_z10418bp98j9hv0vxw0000gn/T/pip-UBQXM9-build/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /var/folders/bm/hr3cq_z10418bp98j9hv0vxw0000gn/T/pip-y1Z3zg-record/install-record.txt --single-version-externally-managed --compile --user failed with error code 1 in /var/folders/bm/hr3cq_z10418bp98j9hv0vxw0000gn/T/pip-UBQXM9-build
Storing debug log for failure in /Users/<username>/.pip/pip.log

Allow shared env variables on service

Most env variables (and possibly other settings) for the instances of a service are identical. It would be nice if it were possible to define "default" settings on a service that are inherited by all instances.

problem running demo.yaml ... unable to create container at 192.168.10.2 ..

I suspect I'm making a very basic error here ... but any pointers would be appreciated.
In ubuntu 13.04 (a VM under parallels), I created a new virtualenv and installed Maestro as per your readme using pip (rather than running setup.py in the cloned repo) ... while this installed maestro and its dependencies in the lib/python2.7/site-packages folder, it didn't end up copying across the demo.yaml file ... so I ended up cloning across the repo under Maestro to access this ... although I didn't re-run setup.py.

If I run the unittest.py in the tests folder, it appears to work.

However, when I try to run demo.yaml using start ... it doesn't appear to be able to create a new container at 192.168.10.2. Does this have something to do with me running within a VM? Or within a virtualenv.

Thanks.

(env)parallels@ubuntu:~/Development/Tools/Maestro/maestro-ng$ python -m maestro -f demo.yaml start
  #  INSTANCE             SERVICE         SHIP                 CONTAINER       STATUS    
  1. zk-node-1            zookeeper       vm1                  failed to start container!
Traceback (most recent call last):
  File "/usr/lib/python2.7/runpy.py", line 162, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/home/parallels/Development/Tools/Maestro/maestro-ng/maestro/__main__.py", line 96, in <module>
    sys.exit(main(sys.argv[1:]))
  File "/home/parallels/Development/Tools/Maestro/maestro-ng/maestro/__main__.py", line 88, in main
    getattr(c, options.command)(**vars(options))
  File "maestro/maestro.py", line 200, in start
    plays.Start(containers, self._registries, refresh_images).run()
  File "maestro/plays.py", line 185, in run
    result = self._start_container(o, container)
  File "maestro/plays.py", line 260, in _start_container
    status = container.status(refresh=True)
  File "maestro/entities.py", line 256, in status
    self._status = self.ship.backend.inspect_container(self.name)
  File "/home/parallels/Development/Tools/Maestro/env/local/lib/python2.7/site-packages/docker/client.py", line 529, in inspect_container
    self._get(self._url("/containers/{0}/json".format(container))),
  File "/home/parallels/Development/Tools/Maestro/env/local/lib/python2.7/site-packages/docker/client.py", line 102, in _get
    return self.get(url, **self._set_request_timeout(kwargs))
  File "/home/parallels/Development/Tools/Maestro/env/local/lib/python2.7/site-packages/requests/sessions.py", line 395, in get
    return self.request('GET', url, **kwargs)
  File "/home/parallels/Development/Tools/Maestro/env/local/lib/python2.7/site-packages/requests/sessions.py", line 383, in request
    resp = self.send(prep, **send_kwargs)
  File "/home/parallels/Development/Tools/Maestro/env/local/lib/python2.7/site-packages/requests/sessions.py", line 486, in send
    r = adapter.send(request, **kwargs)
  File "/home/parallels/Development/Tools/Maestro/env/local/lib/python2.7/site-packages/requests/adapters.py", line 387, in send
    raise Timeout(e)
requests.exceptions.Timeout: (<requests.packages.urllib3.connectionpool.HTTPConnectionPool object at 0x7fba09013b90>, 'Connection to 192.168.10.2 timed out. (connect timeout=5)')
(env)parallels@ubuntu:~/Development/Tools/Maestro/maestro-ng$ 

maestro start failing with 'Error: tuple index out of range'

We have a maestro config with 16 services defined, running against 1 ship at the moment. When stopping and starting maestro to reload the latest images, we run into 'Error: tuple index out of range' after seeing "Failed to start container".

Is there any way to get more info about the problem from maestro?

Error getting logs

I pulled the latest version of maestro, and got this error when trying to get logs:

python -u -m maestro -f ../../maestro_config.yaml -o logs scheduler
Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py", line 162, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/Library/Python/2.7/site-packages/maestro/__main__.py", line 103, in <module>
    sys.exit(main())
  File "/Library/Python/2.7/site-packages/maestro/__main__.py", line 94, in main
    getattr(c, options.command)(**vars(options))
  File "/Library/Python/2.7/site-packages/maestro/maestro.py", line 257, in logs
    o = plays.OutputFormatter()
AttributeError: 'module' object has no attribute 'OutputFormatter'

Unable to stop/start via service name?

I have a config file with a few services, each with one instance. When I try to start/stop using:

python -m maestro -f /vagrant/etc/orchestration.yml stop $service

Sometimes it errors, sometimes it fails, sometimes it doesn't, but it never actually stops the service either way.

Starting services sometimes reports that a service is already started and gives the container id for an instance in another service.

I'm going to dive into this one, but wanted to report it here if you had any quick thoughts on obvious causes.

Check for containers with the same name

Say I have this yaml file:

name: demo
ships:
  main: {ip: 172.17.42.1}
services:
  one:
    image: someimage
    instances:
      myinstance:
        ship: main
  two:
    image: otherimage
    instances:
      myinstance:
        ship: main

As can be seen, there are two instances with the name myinstance. If I try to start this file, only one of the two instances is created. No error, no warning or anything. In this simple case it's easy to spot that you've started only one container instead of two, but on a more complex setup this could be easily overlooked.

Maestro should warn the user about this, possibly refusing to do anything before the error is fixed. On a similar note, if the first "name" key is ommited, only a KeyError: 'name' is thrown, which is also not very informative.

I have tested this only with containers on the same host, I haven't checked maestro's behavior when running in multiple hosts.

All mestro commands hang indefinitely when using SSH tunnelling

When I try to use any commands (status/start etc), maestro hangs indefinitely. The hanging occurs in bgtunnel.py in _validate_ssh_process

I can see bgtunnel has opened up an SSH tunnel to the docker host, something like this:

152638154 47788 47783   0 10:01am ttys003    0:00.02 /usr/bin/ssh -o BatchMode=yes -i /Users/jbloggs/.ssh/id_rsa -T -p 22 -L 127.0.0.1:57656:127.0.0.1:4243 [email protected]

Interestingly, I can also confirm the tunnel is working fine using curl on the command line:

$ curl 127.0.0.1:57656/images/json?all
[{"Created":1406811123,"Id":"be45fb9546dda26f073dfb9bb2cb232377d22e4ff9138280de831c5a49f38f60","ParentId":"bb18aaa8b7a92176b13aea9eba872cb3a9a9301e66c3a3aad04fbd216d1e9baf","RepoTags":["quay.io/somerepo/somesvc:1.0.0"],"Size":0,"VirtualSize":822164249}

Playing with the maestro code, I added in bgtunnel's expect_hello option and set it to false just to confirm that was not a problem (not including that as an option might block some servers from functioning with maestro), but that just results in getting 'host down' almost immediately when doing maestro status

Anyone got any ideas?

Mestro - 0.2.2
Environments - tried Ubuntu Precise and Mac OS X 10.9.2
Python - tried 2.7.3 and 2.7.5
Docker - 0.11

ERROR: […] object has no attribute 'iteritems'

I installed maestro-ng via pip and I get the following error:

 % python -m maestro -f Maestrofile                                                                                                                
Traceback (most recent call last):
  File "/usr/lib/python3.4/runpy.py", line 171, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.4/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/home/niko/.local/lib/python3.4/site-packages/maestro/__main__.py", line 96, in <module>
    sys.exit(main(sys.argv[1:]))
  File "/home/niko/.local/lib/python3.4/site-packages/maestro/__main__.py", line 70, in main
    c = maestro.Conductor(config)
  File "/home/niko/.local/lib/python3.4/site-packages/maestro/maestro.py", line 29, in __init__
    for k, v in self._config['ships'].iteritems())
AttributeError: 'dict' object has no attribute 'iteritems'

I don't know Python at all… but it seems "iteritems" got removed in Python 3. (If that's the case perhaps Python 2 as requirement should be stated in the maestro-ng README). So I installed Python 2 and maestro-ng again via pip2:

 % python2 -m maestro -f Maestrofile                                                                                                                    Laut/radioadmin (master⚡) niko@tier[0]
Traceback (most recent call last):
  File "/usr/lib/python2.7/runpy.py", line 162, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/home/niko/.local/lib/python2.7/site-packages/maestro/__main__.py", line 96, in <module>
    sys.exit(main(sys.argv[1:]))
  File "/home/niko/.local/lib/python2.7/site-packages/maestro/__main__.py", line 70, in main
    c = maestro.Conductor(config)
  File "/home/niko/.local/lib/python2.7/site-packages/maestro/maestro.py", line 33, in __init__
    for name, registry in self._registries.iteritems():
AttributeError: 'NoneType' object has no attribute 'iteritems'

So I thought maybe my Maestrofile is broken. It parses as YAML but perhaps a required property is missing?

name: myapp
registries:
  # Auth credentials for each registry that needs them (see below)
ships:
  l: {ip: localhost}
services:
  webapp:
    image: myapp:2014-03-26__14_51_02
    instances:
      w1:
        ship: l
        ports: {http: 3344}
        env:
          MYSQL_PORT: 3306

Any help would be highly appreciated.

All the best, Niko.

'Thread' object has no attribute '_children'

Guys, set up a new machine with the latest version and am running into some issues... here's what the 'output' looks like (whitewashed with 'docker' instead of my image names):

  #  INSTANCE             SERVICE         SHIP                 CONTAINER       STATUS
  1. docker               docker          host1                3113cdd         failed to start container!
  2. docker-1             docker          host1                e92d1ae         failed to start container!
  3. docker               docker          host1                9053e1f         up
  4. docker               docker          host1                5d9221e         failed to start container!
  5. docker-1             docker          host1                9173bdc         failed to start container!
  6. docker-1             docker          host1                44a337e         failed to start container!
  7. docker               docker          host1                aborted!
'Thread' object has no attribute '_children'

Images all start fine on their own outside of maestro-ng. I've had 0 problems before today.

Python 3 compatibility

In python 3 I get NameError: name 'reduce' is not defined when I try to run Maestro:

 % python -m maestro -f Maestrofile start webapp                                                                                                        
Traceback (most recent call last):
  File "/usr/lib/python3.4/runpy.py", line 171, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.4/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/home/niko/.local/lib/python3.4/site-packages/maestro/__main__.py", line 96, in <module>
    sys.exit(main(sys.argv[1:]))
  File "/home/niko/.local/lib/python3.4/site-packages/maestro/__main__.py", line 88, in main
    getattr(c, options.command)(**vars(options))
  File "/home/niko/.local/lib/python3.4/site-packages/maestro/maestro.py", line 209, in start
    if not only else self._to_containers(things)
  File "/home/niko/.local/lib/python3.4/site-packages/maestro/maestro.py", line 167, in _ordered_containers
    sorted(self._gather_dependencies(self._to_containers(things),
  File "/home/niko/.local/lib/python3.4/site-packages/maestro/maestro.py", line 156, in _to_containers
    return reduce(lambda x, y: x+y, map(parse_thing, things), [])
NameError: name 'reduce' is not defined

The error occurs here: https://github.com/signalfuse/maestro-ng/blob/dc6e2030295586f9072de8eaf967ebadafea0622/maestro/maestro.py#L156

reduced was moved to functools in python 3.

Just a guess (as I know close to no python), but I think the same applies here:

https://github.com/signalfuse/maestro-ng/blob/dc6e2030295586f9072de8eaf967ebadafea0622/maestro/maestro.py#L140

and here:

https://github.com/signalfuse/maestro-ng/blob/ff32775c96f5e5625a720c4cecc4fab4da9ae662/maestro/plays.py#L217

All the best, Niko.

Support -link feature

I understand that maestro-ng has taken inspiration from the -link command but doesn't support it directly?

If -icc=false is set then containers can't talk to each other unless the -link command has been used, for more secure environments maestro-ng wouldn't work.

Also the maestro-ng env var naming format differs from the link format, which makes it difficult to support interoperability between using a container with maestro vs just starting it up manually.

It would be really slick to see the -link command supported.

Thanks!

Friendly errors

I got errors right now like that:
Error: 'ship'
Error: 'name'

no line number or any meta information, it's not very helpful

Make -o the default option for stop/restart

I find the 'restart dependent containers' behavior surprising, for example when I restart a web application layer which is connected to a frontend, the frontend will restart as well. I think this behavior is not usually desirable. What about a '-a' option for applying this behavior?

ENV variables in yml config?

I'm thinking about using maestro-ng for a dockerized dev environment, but needing to hard-code the private repo credentials into the yml file seems less than optimal.

The docker-registry uses _env:VAR_NAME, maybe something like that would work?

Add support for volumes-from

From Docker 0.11, volumes from allows mounting volumes from other containers. Use case: sshd container to connect to and update an app container's git repo.

current docker-py supports this so should be a simple addition. I'll try to get to it if nobody does.

Slow pulls on first bootstrap causes maestro to crash

3. zk-4                 zookeeper       rhapsody-4           61bb940         started
4. zk-5                 zookeeper       rhapsody-5           failed to start container!

On an initial start, where the image needs to be pulled to the target server, sometimes time is needed to finish. Can the timeout be increased here?

Custom port in private repository not supported

Hello,
I tried to run maestro with images in my private repo on non-standard port, and failed. The reason if that the entities.py:get_image_details() function assumes that given repository name (which is "host:port/repo" in my case), the tag is always after the colon.
This fixed it for me:

def get_image_details(self):
  p = self._image.split(':')
    if len(p[0].split('.'))>0:
      return {'repository': p[0]+':'+p[1], 'tag': len(p) > 2 and p[2] or 'latest'}
    else:
      return {'repository': p[0], 'tag': len(p) > 1 and p[1] or 'latest'}

demo.yaml does not work

Hi,

I am trying the setup and test the demo.yaml but got the following error. It seems the yaml file missing some fields. Can you explain how to run the demo? Thanks.

ymtoe

python -m maestro -f demo.yaml

Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py", line 162, in _run_module_as_main
"main", fname, loader, pkg_name)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "/Users/coder/maestro/maestro-ng/maestro/main.py", line 79, in
sys.exit(main(sys.argv[1:]))
File "/Users/coder/maestro/maestro-ng/maestro/main.py", line 55, in main
c = maestro.Conductor(config)
File "maestro/maestro.py", line 50, in init
self._config['name'])
KeyError: 'name'

[Q] Does Maestro-Ng handle reboot gracefully ?

Maestro-Ng looks promising, but I wonder does it handle the starting order of container when booting ?

Eg: I have an app that needs to be started after mysql, redis, php-fpm, and nginx are started.

Documentation issue? Maestro authentication with registries uses local $HOME/.dockercfg when available

Unsure if this is a bug or just a documentation issue - I was struggling to get login working with a private registry when I specified credentials under registries in my maestro.yaml.

I had a look at the docker-py code and noticed it was looking out for a local .dockercfg and using the auth token from that instead. Turns out I had an out of date dockercfg with incorrect credentials :) Fixed that and it all started working... awesome!

Is it worth pointing out in the documentation that you can skip the registries section in the maestro.yaml if you already have a local .dockercfg in your home directory containing credentials for your private registry? I can make a PR with the change but want to be sure that is intended behaviour first?

TBH I think this behaviour is better - I was pretty uncomfortable having registry credentials in source code...

Document use of Jinja2 templating

Maestro pre-processes the configuration file through the Jinja2 templating engine, but the documentation doesn't talk about it nor does it show examples of use and all the cool things that can be done with it (per service sub-templates, etc.).

TCP lifecycle check does not work

The lifecycle check didn't work properly with the following configuration file:

name: test
ships:
    master: {ip: &master_ship_ip localhost, docker_port: 4243}
services:
    postgres:
        image: postgres
        instances:
            postgres-1:
                ship: master
                ports: {test: 9998}
                lifecycle:
                    running: [{type: tcp, port: test}]

I expect maestro-ng to tell me that the container did not start because the port is closed.

I think the problem comes from here. The port 9998 on the host machine redirects to the same port on the container. Python sees that port as open on the host machine even if the port is closed on the container.

$ docker ps

CONTAINER ID        IMAGE                                 COMMAND                CREATED             STATUS              PORTS                                       NAMES
c9a7978fce19        postgres:latest                       /usr/src/postgres/do   2 minutes ago       Up 2 minutes        5432/tcp, 0.0.0.0:9998->9998/tcp            postgres-1

$ maestro -v

maestro-0.1.8.2

$ docker version

Client version: 1.0.1
Client API version: 1.12
Go version (client): go1.2.1
Git commit (client): 990021a
Server version: 1.0.1
Server API version: 1.12
Go version (server): go1.2.1
Git commit (server): 990021a

I got timeout when images downloading from private registry

vagrant@vagrant-ubuntu-trusty-64:~/projects/maestro-ng$ maestro -f yamls/vagrant.yaml start

INSTANCE SERVICE SHIP CONTAINER STATUS

  1. idol-node-1 idol vm1 1b707fe started
  2. mongodb-node-1 mongodb vm1 2368d8c started
  3. openfire-node-1 openfire vm1 8ba1ee3 started
  4. postgresql-node-1 postgresql vm1 e7fc457 started
  5. rabbitmq-node-1 rabbitmq vm1 failed to start container!
  6. redis-node-1 redis vm1 3fdce0c started
  7. smtp-node-1 smtp vm1 failed to start container!
  8. vertica-node-1 vertica vm1 pulling image myd-vm00941.hpswlabs.adapps.hp.com:5000/vertica:6.1.3...
    timed out

Hi running ubuntu 14.04

Hi
Try to install/upgrade and got following error : ImportError: cannot import name ContextualZipFile

Ports configured as UDP are in fact TCP

Ports configured as UDP in my Maestro config file are mapped as TCP. When doing a maestro fullstatus it does show an udp port, docker inspect however shows me that it's a TCP.

Please see port 8125 in the relevant part of my config, the result of maestro fullstatus and the output of docker inspect:

Maestro config:

ports: {
  http: "80:8080", 
  line_receiver: "2003:12003", 
  pickle_receiver: "2004:12004", 
  cache_query: "7002", 
  statsd: "8125/udp", 
  ssh: "22:2004"
}

Maestro fullstatus:

  2. gp1                  graphite        mainship             e66a33d         up
     >>  8125/udp:statsd
     >>  8080/tcp:http
     >>  2004/tcp:ssh
     >> 12003/tcp:line_recei
     >>  7002/tcp:cache_quer
     >> 12004/tcp:pickle_rec

Docker inspect:

"PortBindings": {
    "2003/tcp": [
        {
            "HostIp": "0.0.0.0",
            "HostPort": "12003"
        }
    ],
    "2004/tcp": [
        {
            "HostIp": "0.0.0.0",
            "HostPort": "12004"
        }
    ],
    "22/tcp": [
        {
            "HostIp": "0.0.0.0",
            "HostPort": "2004"
        }
    ],
    "7002/tcp": [
        {
            "HostIp": "0.0.0.0",
            "HostPort": "7002"
        }
    ],
    "80/tcp": [
        {
            "HostIp": "0.0.0.0",
            "HostPort": "8080"
        }
    ],
    "8125/tcp": [
        {
            "HostIp": "0.0.0.0",
            "HostPort": "8125"
        }
    ],
    "8125/udp": null
}

Deploy a Docker instance to one of a 'Fleet' of Ships

Rather than specifying a particular Ship on which to deploy a Docker instance, it would be useful to be able to deploy to a given 'Fleet' (pool) of Ships, with Maestro-ng working out which Ship in the Fleet to deploy to using a simple round-robin or balancing algorithm.

As a future 'nice-to-have' it would also be nice for Maestro-ng to watch for Serf MemberJoin and MemberLeave events as to dynamically construct the Fleet, although I appreciate this may be well out of the scope of the project.

Basically, I want to say "Deploy to the fleet!" without caring which ship it deploys to.

Add rolling upgrade feature

I am working on using maestro-ng to manage some web servers running a custom app. When I build a new container I deploy using stop followed by start (with -r). This stops all instances of the site and then pulls and starts each one consecutively. If there is some problem pulling the image the entire site is down.

Ideally we would deploy via a rolling restart where each ship does the stop/pull/start consecutively and thus we have only one server out of rotation at a time. Better yet would be a way to do the pull first and then stop/start each server to minimize downtime. I looked at adding maestro restart with these semantics but my Python is very poor so I felt better adding a feature request so someone with better Python skill can attempt a fix.

Arbitrary runtime service configuration

I have not used maestro yet but it sounds very promising and surely adds one of the missing puzzle when working with Docker.
However, before I start diving into maestro I would like to know if maestro also serves the need for detailed runtime configuration of a particular service container.
Let's take a simple container running an nginx webserver for example. Would it be possible to generate the configuration files for an arbitrary number of virtual hosts via the maestro config? As far as I understand the only possibility for defining an arbitrary number of configuration values is to use the env parameter in the yaml config which does not give the opportunity to define a structured configuration element like virtual hosts.
I know that I could use volumes and drop in vhost config files but I would rather like to avoid defining such config files for my applications, especially because they might also differ for different environments.
So is maestro theoretically intended for such kind of runtime configuration management? Or is that out of scope?

Maestro pull fails with "DockerException: HTTPS endpoint unresponsive and insecure mode isn't enabled."

Docker-client's last update requires HTTPS by default on private registries:
https://github.com/docker/docker-py/blob/7a462970852a2578c3869e581a57dd70eaa22217/ChangeLog.md

We should have a global flag that enables pulls from unsecure registries.

L346 needs to be changed with an added insecure_registry=True parameter
https://github.com/signalfuse/maestro-ng/blob/fe89532acb3a61e84294de9d418e69b6fae04467/maestro/plays/tasks.py#L346

SSH-secured access to ships

Disclaimer: I haven't used/read your code enough to know how you're connecting to remote API ports, you may already be either doing some security or considering the SSL security docker.io has released. It appears to me that you're just using docker-py's docker.Client and assuming that the port is open to the maestro controller computer

Just wanted to bring this code to your attention, it's literally a few extra lines beyond a normal docker-py remote connection. This seems to be working great for me so far, and my remote systems only allow docker on "-H 127.0.0.1:4243" and only have port 22 open, which makes me feel better.

I don't think this should be the default behavior, but I think automatic SSH tunneling would be a killer feature for maestro

Incorrect parsing of ip:port in image names

In get_image_details, the split is done on :, which gives incorrect results when using an image from a local docker registry e.g. 192.168.50.1:5001/gearman (with no tag)

This can be worked around by adding :latest, but should work without having to do that.

Unable to bind one port to multiple interfaces

When using a config file like that:

ports: 
          mongod-private:   {exposed: 27017, external: [192.168.0.10, 27017]}
          mongod-localhost: {exposed: 27017, external: [127.0.0.1, 27017]}

the given port is only exposed to one interface instead of both.

Generate host environment var from port specification if provided

Right now host environment variables for dependencies are generated based on the ip entry in ship definition. I propose to use the hostname for a service when specified with an 'external' port.

Use case: Two services on two different machines have a dependency, e.g. logstash forwarder to logstash. We prefer to keep those logging ports on a private IP range. Port config on the log server would be:

    ports:
      logstash:
        exposed: 5000
        external: [ 10.1.1.2, 5000 ]

Since the additional of SSH (great feature!), we started controlling maestro from an external system, so we started giving the ships public ips.

However, when two dockers have a dependency like above, the environment variable in the forwarder docker gets the public IP of the logstash server ship. I suggest to use the IP address of the port specification if they have been explicitly specified.

Add reference file for YAML

There's already a demo.yaml for a working demo; perhaps a reference.yaml would be beneficial as a complete list of available keys. I see that the "cmd" key was just added, but there's no docs on it yet. There may be others that are similarly unknown but are actually supported in the codebase. While full docs would be great, perhaps a single file that just shows off what keys are available would be a step in the right direction? It would help people new to the project quickly see what's available

simplify docker api endpoint configuration for ships

currently the docker api endpoint (which is passed to the docker-py library) is built automatically from ip and port:

ships:
    node-01: {ip: '10.33.33.201', docker_port: 4243}

resulting docker api endpoint: http://10.33.33.201:4243

But what if I have basic auth on my docker api enpoint. With the current it works like this:

ships:
    node-01: {ip: 'docker-api:[email protected]', docker_port: 4243}

resulting docker api endpoint: http://docker-api:[email protected]:4243

So far so good.... but what if my docker api uses https? Because the added http:// is hardcoded, that wont work.

I suspect the ip is needed elsewhere and my above basic auth example probably only works with the very simple test I did. So I propose adding an additional (optional) parameter to ship called docker_api. If docker_api is set, docker_port is ignored.

    ships:
        node-01: {ip: '10.33.33.201', docker_api:'https://docker-api:[email protected]:4243'}

I this is something you would consider to merge, I can make a pull-request.

private images in official docker registry

When I choose a private image from docker registry, -r option does not work. New version is not downloaded and there is no exception to catch. SSH tunneled machine has docker credentials entered to download the requested image.

Everything works fine if I change visibility of image from private to public.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.