Search code examples
dockermulti-tenantcoreos

Can a Docker container manage other Docker containers?


I need to be able to deploy a new container or manage Docker containers running in CoreOS from another running docker container.

Docker version is 1.5.0
CoreOS version is 647.2.0

Right now my process for deploying a new instance of my application is using a shell script.

It basically does:

  1. duplicate the source code of the Node.js application to a new folder
  2. cd into it
  3. deploy a new docker container in detached mode setting pwd as -v to the work directory then the application runs

I was thinking, if it's possible to execute the shell script from inside the container so that it deploys a new container in CoreOS or are there any alternatives for this method.

Another objective is to be able to stop a running container.

Any comments or suggestions would be greatly appreciated.


Solution

  • run the controlling container with the Docker client & socket mounted and you will be able to control the docker daemon from within your containers (run docker client within docker container)

    EDIT: DO note root access is required to the docker socket, this means the container is able to control the docker daemon and launch a containter to get root on the host, so use this with containers you trust and only you need to access.

    $ docker run \ 
      -v /var/run/docker.sock:/var/run/docker.sock \   
      -v /usr/bin/docker:/usr/bin/docker \ 
      -v /usr/lib/libdevmapper.so.1.02:/usr/lib/libdevmapper.so.1.02 \
      ubuntu docker --version
    
    Docker version 1.1.2, build d84a070
    

    also tested on latest coreOS / Docker:

    core@coreos2 /usr/lib $ docker run -it --name=test --rm -h=dod -v /var/run/docker.sock:/var/run/docker.sock -v `which docker`:/usr/bin/docker -v /usr/lib/libdevmapper.so.1.02:/usr/lib/libdevmapper.so.1.02 ubuntu bash
    root@dod:/# docker ps -a
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    6746d8cd1c8d        ubuntu:latest       "bash"              3 seconds ago       Up 2 seconds                            test
    root@dod:/# docker --version
    Docker version 1.6.2, build 7c8fca2-dirty
    root@dod:/#
    

    EDIT: for debian:jessie this wouldn't work without libsqlite3-0, we can mount it form the host or search for the package:

    root@066bf3df3f2e:/# ldd `which docker`
            linux-vdso.so.1 (0x00007ffdb7dc8000)
            libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe8a77df000)
            libsqlite3.so.0 => not found
            libdevmapper.so.1.02 => /usr/lib/libdevmapper.so.1.02 (0x00007fe8a7593000)
            libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe8a71ea000)
            /lib64/ld-linux-x86-64.so.2 (0x00007fe8a79fc000)
            libudev.so.1 => /lib/x86_64-linux-gnu/libudev.so.1 (0x00007fe8a6fdb000)
            librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fe8a6dd3000)
            libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe8a6bcf000)
    

    to find out which package provides this file for debian:jessie use packages.debian.org/search

    EDIT: the user within the container will need to have permission to read the docker socket from the host, if it is a non-root user, you could try to have a docker group within the container, but the group gid should match to host docker group (unconfirmed if this actually works).

    Alternatively you could apt-get install sudo and

    echo "<user_name> ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/90-custom && \
    chmod 0440 /etc/sudoers.d/90-custom
    

    at which point you can write scripts for that user to sudo docker .. control the host docker daemon.