From ce7b24a56bd17d269c51b49bb21c8fe8db390307 Mon Sep 17 00:00:00 2001 From: zachary Date: Mon, 6 Jul 2015 10:21:12 -0400 Subject: [PATCH] Squashed 'dind/' content from commit 41bdbd4 git-subtree-dir: dind git-subtree-split: 41bdbd41e834ea9727b505fc87d5f8ba2c211f22 --- .gitignore | 1 + Dockerfile | 22 +++++ LICENSE | 202 +++++++++++++++++++++++++++++++++++++++++++ README.md | 136 +++++++++++++++++++++++++++++ alpine/Dockerfile | 17 ++++ alpine/build.sh | 5 ++ archlinux/Dockerfile | 14 +++ archlinux/build.sh | 5 ++ fedora/Dockerfile | 19 ++++ fedora/build.sh | 5 ++ opensuse/Dockerfile | 16 ++++ opensuse/build.sh | 5 ++ spintop.jpg | Bin 0 -> 37325 bytes wrapdocker | 113 ++++++++++++++++++++++++ 14 files changed, 560 insertions(+) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 README.md create mode 100644 alpine/Dockerfile create mode 100755 alpine/build.sh create mode 100644 archlinux/Dockerfile create mode 100755 archlinux/build.sh create mode 100644 fedora/Dockerfile create mode 100755 fedora/build.sh create mode 100644 opensuse/Dockerfile create mode 100755 opensuse/build.sh create mode 100644 spintop.jpg create mode 100755 wrapdocker diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b25c15b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*~ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1fad950 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +FROM ubuntu:14.04 +MAINTAINER jerome.petazzoni@docker.com + +# Let's start with some basic stuff. +RUN apt-get update -qq && apt-get install -qqy \ + apt-transport-https \ + ca-certificates \ + curl \ + lxc \ + iptables + +# Install Docker from Docker Inc. repositories. +RUN curl -sSL https://get.docker.com/ubuntu/ | sh + +# Install the magic wrapper. +ADD ./wrapdocker /usr/local/bin/wrapdocker +RUN chmod +x /usr/local/bin/wrapdocker + +# Define additional metadata for our image. +VOLUME /var/lib/docker +CMD ["wrapdocker"] + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..1ee6c9e --- /dev/null +++ b/README.md @@ -0,0 +1,136 @@ +# Docker-in-Docker + +This recipe lets you run Docker within Docker. + +![Inception's Spinning Top](spintop.jpg) + +There is only one requirement: your Docker version should support the +`--privileged` flag. + + +## Quickstart + +Build the image: +```bash +docker build -t dind . +``` + +Run Docker-in-Docker and get a shell where you can play, and docker daemon logs +to stdout: +```bash +docker run --privileged -t -i dind +``` + +Run Docker-in-Docker and get a shell where you can play, but docker daemon logs +into `/var/log/docker.log`: +```bash +docker run --privileged -t -i -e LOG=file dind +``` + +Run Docker-in-Docker and expose the inside Docker to the outside world: +```bash +docker run --privileged -d -p 4444 -e PORT=4444 dind +``` + +Note: when started with the `PORT` environment variable, the image will just +the Docker daemon and expose it over said port. When started *without* the +`PORT` environment variable, the image will run the Docker daemon in the +background and execute a shell for you to play. + +### Daemon configuration + +You can use the `DOCKER_DAEMON_ARGS` environment variable to configure the +docker daemon with any extra options: +```bash +docker run --privileged -d -e DOCKER_DAEMON_ARGS="-D" dind +``` + +## It didn't work! + +If you get a weird permission message, check the output of `dmesg`: it could +be caused by AppArmor. In that case, try again, adding an extra flag to +kick AppArmor out of the equation: + +```bash +docker run --privileged --lxc-conf="lxc.aa_profile=unconfined" -t -i dind +``` + +If you get the warning: + +```` +WARNING: the 'devices' cgroup should be in its own hierarchy. +```` + +When starting up dind, you can get around this by shutting down docker and running: + +```` +# /etc/init.d/lxc stop +# umount /sys/fs/cgroup/ +# mount -t cgroup devices 1 /sys/fs/cgroup +```` + +If the unmount fails, you can find out the proper mount-point with: + +```` +$ cat /proc/mounts | grep cgroup +```` + +## How It Works + +The main trick is to have the `--privileged` flag. Then, there are a few things +to care about: + +- cgroups pseudo-filesystems have to be mounted, and they have to be mounted + with the same hierarchies than the parent environment; this is done by a + wrapper script, which is setup to run by default; +- `/var/lib/docker` cannot be on AUFS, so we make it a volume. + +That's it. + + +## Important Warning About Disk Usage + +Since AUFS cannot use an AUFS mount as a branch, it means that we have to +use a volume. Therefore, all inner Docker data (images, containers, etc.) +will be in the volume. Remember: volumes are not cleaned up when you +`docker rm`, so if you wonder where did your disk space go after nesting +10 Dockers within each other, look no further :-) + + +## Which Version Of Docker Does It Run? + +Outside: it will use your installed version. + +Inside: the Dockerfile will retrieve the latest `docker` binary from +https://get.docker.io/; so if you want to include *your* own `docker` +build, you will have to edit it. If you want to always use your local +version, you could change the `ADD` line to be e.g.: + + ADD /usr/bin/docker /usr/local/bin/docker + + +## Can I Run Docker-in-Docker-in-Docker? + +Yes. Note, however, that there seems to be a weird FD leakage issue. +To work around it, the `wrapdocker` script carefully closes all the +file descriptors inherited from the parent Docker and `lxc-start` +(except stdio). I'm mentioning this in case you were relying on +those inherited file descriptors, or if you're trying to repeat +the experiment at home. + +[kojiromike/inception](https://github.com/kojiromike/inception) is +a wrapper script that uses dind to nest Docker to arbitrary depth. + +Also, when you will be exiting a nested Docker, this will happen: + +```bash +root@975423921ac5:/# exit +root@6b2ae8bf2f10:/# exit +root@419a67dfdf27:/# exit +root@bc9f450caf22:/# exit +jpetazzo@tarrasque:~/Work/DOTCLOUD/dind$ +``` + +At that point, you should blast Hans Zimmer's [Dream Is Collapsing]( +http://www.youtube.com/watch?v=imamcajBEJs) on your loudspeakers while twirling +a spinning top. diff --git a/alpine/Dockerfile b/alpine/Dockerfile new file mode 100644 index 0000000..cc769ad --- /dev/null +++ b/alpine/Dockerfile @@ -0,0 +1,17 @@ +FROM gliderlabs/alpine +MAINTAINER platform-eng@c2fo.com + +# Let's start with some basic stuff. +RUN apk-install iptables ca-certificates lxc e2fsprogs + +# Install Docker from Alpine repos +RUN apk-install docker + +# Install the magic wrapper. +ADD ./wrapdocker /usr/local/bin/wrapdocker +RUN chmod +x /usr/local/bin/wrapdocker + +# Define additional metadata for our image. +VOLUME /var/lib/docker +CMD ["wrapdocker"] + diff --git a/alpine/build.sh b/alpine/build.sh new file mode 100755 index 0000000..582a43e --- /dev/null +++ b/alpine/build.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +cp ../wrapdocker . +docker build -t dind_alpine . +rm wrapdocker diff --git a/archlinux/Dockerfile b/archlinux/Dockerfile new file mode 100644 index 0000000..32d92be --- /dev/null +++ b/archlinux/Dockerfile @@ -0,0 +1,14 @@ +FROM logankoester/archlinux +MAINTAINER logan@logankoester.com + +# Install Docker from Arch repos +RUN pacman -S --noprogressbar --noconfirm --needed ca-certificates lxc e2fsprogs docker + +# Install the magic wrapper. +ADD ./wrapdocker /usr/local/bin/wrapdocker +RUN chmod +x /usr/local/bin/wrapdocker + +# Define additional metadata for our image. +VOLUME /var/lib/docker +CMD ["wrapdocker"] + diff --git a/archlinux/build.sh b/archlinux/build.sh new file mode 100755 index 0000000..722bece --- /dev/null +++ b/archlinux/build.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +cp ../wrapdocker . +docker build -t dind_archlinux . +rm wrapdocker diff --git a/fedora/Dockerfile b/fedora/Dockerfile new file mode 100644 index 0000000..986fefe --- /dev/null +++ b/fedora/Dockerfile @@ -0,0 +1,19 @@ +FROM fedora:20 +MAINTAINER amitsaha.in@gmail.com + +# Let's start with some basic stuff. +RUN yum -y clean all +RUN yum -y update +RUN yum install -y iptables ca-certificates lxc e2fsprogs + +# Install Docker from Fedora repos +RUN yum -y install docker-io + +# Install the magic wrapper. +ADD ./wrapdocker /usr/local/bin/wrapdocker +RUN chmod +x /usr/local/bin/wrapdocker + +# Define additional metadata for our image. +VOLUME /var/lib/docker +CMD ["wrapdocker"] + diff --git a/fedora/build.sh b/fedora/build.sh new file mode 100755 index 0000000..dde3fc1 --- /dev/null +++ b/fedora/build.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +cp ../wrapdocker . +docker build -t dind_fedora . +rm wrapdocker diff --git a/opensuse/Dockerfile b/opensuse/Dockerfile new file mode 100644 index 0000000..e25feb4 --- /dev/null +++ b/opensuse/Dockerfile @@ -0,0 +1,16 @@ +FROM opensuse:latest +MAINTAINER git@yeoldegrove.de + +# Let's start with some basic stuff. +RUN zypper --gpg-auto-import-keys --non-interactive refresh && \ + zypper --gpg-auto-import-keys --non-interactive update && \ + zypper --gpg-auto-import-keys --non-interactive install --auto-agree-with-licenses e2fsprogs apparmor-parser docker + +# Install the magic wrapper. +ADD ./wrapdocker /usr/local/bin/wrapdocker +RUN chmod +x /usr/local/bin/wrapdocker + +# Define additional metadata for our image. +VOLUME /var/lib/docker +CMD ["wrapdocker"] + diff --git a/opensuse/build.sh b/opensuse/build.sh new file mode 100755 index 0000000..fef6454 --- /dev/null +++ b/opensuse/build.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +cp ../wrapdocker . +docker build -t dind_opensuse . +rm wrapdocker diff --git a/spintop.jpg b/spintop.jpg new file mode 100644 index 0000000000000000000000000000000000000000..983128ad4c34534fea20c6c45359d389c948cee3 GIT binary patch literal 37325 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 literal 0 HcmV?d00001 diff --git a/wrapdocker b/wrapdocker new file mode 100755 index 0000000..373baba --- /dev/null +++ b/wrapdocker @@ -0,0 +1,113 @@ +#!/bin/bash + +# Ensure that all nodes in /dev/mapper correspond to mapped devices currently loaded by the device-mapper kernel driver +dmsetup mknodes + +# First, make sure that cgroups are mounted correctly. +CGROUP=/sys/fs/cgroup +: {LOG:=stdio} + +[ -d $CGROUP ] || + mkdir $CGROUP + +mountpoint -q $CGROUP || + mount -n -t tmpfs -o uid=0,gid=0,mode=0755 cgroup $CGROUP || { + echo "Could not make a tmpfs mount. Did you use --privileged?" + exit 1 + } + +if [ -d /sys/kernel/security ] && ! mountpoint -q /sys/kernel/security +then + mount -t securityfs none /sys/kernel/security || { + echo "Could not mount /sys/kernel/security." + echo "AppArmor detection and --privileged mode might break." + } +fi + +# Mount the cgroup hierarchies exactly as they are in the parent system. +for SUBSYS in $(cut -d: -f2 /proc/1/cgroup) +do + [ -d $CGROUP/$SUBSYS ] || mkdir $CGROUP/$SUBSYS + mountpoint -q $CGROUP/$SUBSYS || + mount -n -t cgroup -o $SUBSYS cgroup $CGROUP/$SUBSYS + + # The two following sections address a bug which manifests itself + # by a cryptic "lxc-start: no ns_cgroup option specified" when + # trying to start containers withina container. + # The bug seems to appear when the cgroup hierarchies are not + # mounted on the exact same directories in the host, and in the + # container. + + # Named, control-less cgroups are mounted with "-o name=foo" + # (and appear as such under /proc//cgroup) but are usually + # mounted on a directory named "foo" (without the "name=" prefix). + # Systemd and OpenRC (and possibly others) both create such a + # cgroup. To avoid the aforementioned bug, we symlink "foo" to + # "name=foo". This shouldn't have any adverse effect. + echo $SUBSYS | grep -q ^name= && { + NAME=$(echo $SUBSYS | sed s/^name=//) + ln -s $SUBSYS $CGROUP/$NAME + } + + # Likewise, on at least one system, it has been reported that + # systemd would mount the CPU and CPU accounting controllers + # (respectively "cpu" and "cpuacct") with "-o cpuacct,cpu" + # but on a directory called "cpu,cpuacct" (note the inversion + # in the order of the groups). This tries to work around it. + [ $SUBSYS = cpuacct,cpu ] && ln -s $SUBSYS $CGROUP/cpu,cpuacct +done + +# Note: as I write those lines, the LXC userland tools cannot setup +# a "sub-container" properly if the "devices" cgroup is not in its +# own hierarchy. Let's detect this and issue a warning. +grep -q :devices: /proc/1/cgroup || + echo "WARNING: the 'devices' cgroup should be in its own hierarchy." +grep -qw devices /proc/1/cgroup || + echo "WARNING: it looks like the 'devices' cgroup is not mounted." + +# Now, close extraneous file descriptors. +pushd /proc/self/fd >/dev/null +for FD in * +do + case "$FD" in + # Keep stdin/stdout/stderr + [012]) + ;; + # Nuke everything else + *) + eval exec "$FD>&-" + ;; + esac +done +popd >/dev/null + + +# If a pidfile is still around (for example after a container restart), +# delete it so that docker can start. +rm -rf /var/run/docker.pid + +# If we were given a PORT environment variable, start as a simple daemon; +# otherwise, spawn a shell as well +if [ "$PORT" ] +then + exec docker -d -H 0.0.0.0:$PORT -H unix:///var/run/docker.sock \ + $DOCKER_DAEMON_ARGS +else + if [ "$LOG" == "file" ] + then + docker -d $DOCKER_DAEMON_ARGS &>/var/log/docker.log & + else + docker -d $DOCKER_DAEMON_ARGS & + fi + (( timeout = 60 + SECONDS )) + until docker info >/dev/null 2>&1 + do + if (( SECONDS >= timeout )); then + echo 'Timed out trying to connect to internal docker host.' >&2 + break + fi + sleep 1 + done + [[ $1 ]] && exec "$@" + exec bash --login +fi