Docker

From Neuroinformatics Research Group
Jump to: navigation, search

Contents

Install Docker

If you don't have docker installed, follow the installation tutorial online.

Pull an Image


Once you have Docker installed, pull an image from our registry. For this tutorial, we'll use the eqc image.

$ sudo docker pull docker.rc.fas.harvard.edu/eqc:0.1

If you have trouble pulling the image, refer to our troubleshooting guide.

Once you've pulled the image successfully, take note of the IMAGE ID (also note that your IMAGE ID may be different)

$ sudo docker images
REPOSITORY                                         TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
docker.rc.fas.harvard.edu/eqc                      0.1                 72921163b86a        7 minutes ago       2.304 GB

Run a Container

With sudo privileges, you can simply run an eqc container and execute the extqc command

$ sudo docker run 72921163b86a extqc --help
usage: extqc [-h] [--backup-previous] [--debug] [--delete-only]
             [--email-from EMAIL_FROM] [--email-on EMAIL_ON]
             [--email-to EMAIL_TO] [--keep-all] [--keep-dicoms] [--keep-extqc]
             [--groups GROUPS] [--keep-nifti] [--keep-xar-dir]
             [--mask-threshold MASK_THRESHOLD] [--max MAX] [--no-delete]
             [--no-lpi] [--no-slope] [--no-storexar] [--no-swapdim]
             --output-dir OUTPUT_DIR [--remove-xar] [--reprocess-all]
             [--rerun-all] [--scans] [--session-ids]
             [--session-list-file SESSION_LIST_FILE] [--skip NUM_VOLS_TO_SKIP]
             [--smtp-host SMTP_HOST] [--use-dev-shm] [--verbose] --xnat
             XNAT_ALIAS [--mon-name MON_NAME] [--mon-url MON_URL]

If you want to expose the extqc software to untrusted users, for the time being, your best bet is to start a sshd service on port 22

$ sudo docker run -u root -p 22 -d 72921163b86a /usr/sbin/sshd -D
aed8b99320d005509377299ece0e3e80438aa70aeb3c46d57d5cdfcf2bb7bc0f

The -u root argument is necessary to start sshd on a privileged port within the container, -p 22 tells Docker to bind port 22 on the container to an unprivileged port on the host (not entirely necessary), and -d tells Docker to daemonize the container.

When you start the container, the entire Container ID will be printed to the console. You can recover this ID later by issuing the following command. Notice that only the first several characters are all that you need to identify a container uniquely.

$ sudo docker ps -a
CONTAINER ID        IMAGE                                               COMMAND                CREATED             STATUS              PORTS                    NAMES
aed8b99320d0        docker.rc.fas.harvard.edu/eqc:0.1                   /usr/sbin/sshd -D      8 seconds ago       Up 8 seconds        0.0.0.0:49154->22/tcp    goofy_darwin

The host port that is bound to the container port 22 is visible within the output from docker ps -a, or by issuing the following command

$ sudo docker port aed8b99320d0 22
0.0.0.0:49154

The host port is 49154. You can use this port to ssh to the container

$ ssh -p 49154 docker@localhost
docker@localhosts password:  # password is docker
[docker@aed8b99320d0 ~]$

Alternatively, if you discover the IP address of the container through docker inspect you can ssh to that address directly

$ sudo docker inspect aed8b99320d0 | grep IPAddress | cut -d '"' -f 4
172.17.0.43
$ ssh docker@172.17.0.43
docker@172.17.0.13s password:  # password is docker
[docker@aed8b99320d0 ~]$

Once you're connected to the container, you can run commands such as extqc

[docker@aed8b99320d0 ~]$ extqc --help
usage: extqc [-h] [--backup-previous] [--debug] [--delete-only]
             [--email-from EMAIL_FROM] [--email-on EMAIL_ON]
             [--email-to EMAIL_TO] [--keep-all] [--keep-dicoms] [--keep-extqc]
             [--groups GROUPS] [--keep-nifti] [--keep-xar-dir]
             [--mask-threshold MASK_THRESHOLD] [--max MAX] [--no-delete]
             [--no-lpi] [--no-slope] [--no-storexar] [--no-swapdim]
             --output-dir OUTPUT_DIR [--remove-xar] [--reprocess-all]
             [--rerun-all] [--scans] [--session-ids]
             [--session-list-file SESSION_LIST_FILE] [--skip NUM_VOLS_TO_SKIP]
             [--smtp-host SMTP_HOST] [--use-dev-shm] [--verbose] --xnat
             XNAT_ALIAS [--mon-name MON_NAME] [--mon-url MON_URL]

Digression: ~/.xnat_auth

Some of our pipelines, including eqc, use apps.xnat.Xnat from the Neuroinfo Toolkit. This class reads credentials from a XML file ~/.xnat_auth. You will need to create this file within the docker user's home directory

<xnat>
  <central version="1.5">
    <username>username</username>
    <password>password</password>
    <url>http://central.xnat.org</url>
  </central>
</xnat>

Or, you can mount an ~/.xnat_auth file into the container at startup

$ sudo docker run -v ~/.xnat_auth:/home/docker/.xnat_auth 72921163b86a cat /home/docker/.xnat_auth
<xnat>
  <central version="1.5">
    <username>user</username>
    <password>p@$$wd</password>
    <url>http://my.xnat.org</url>
  </central>
</xnat>

You can mount most paths from the host to a custom location within any Docker container if you have privilege to run docker commands. These commands require administrative privileges for the time being to avoid certain issues described in About Security. That is supposedly going to change in future versions of Docker.

Building an Image (buildy)

There are several ways to build an image with Docker and they're all simple. Managing and rebuilding an image from a specific point in time however, does not come for free.

For this I wrote buildy to pull a Dockerfile and any resources i.e., "context", from an explicit git branch and build it. Say that you want to build the nipy image version 0.3.0

$ ./buildy --repo=https://github.com/tokeefe/nipy.git --branch=0.3.0 --prefix=_builds --tag=docker.rc.fas.harvard.edu/nipy:0.3.0
[2014-02-26 15:03:59,893][INFO] - buildy.says - cloning repo=https://github.com/tokeefe/nipy.git, branch=0.3.0
[2014-02-26 15:04:00,781][INFO] - buildy.says - clone written to _builds/https%3A%2F%2Fgithub.com%2Ftokeefe%2Fnipy.git_0.3.0_2014-02-26T20:03:59.894029+00:00_DIdNxb
[2014-02-26 15:04:00,781][INFO] - buildy.says - building docker image
[2014-02-26 15:05:28,445][INFO] - buildy.says - image built successfully

That's all there is to it.

About Security

There is a much more comprehensive review of Docker security online. Anyone interested in using Docker should read this page very carefully and re-read periodically.

The most important issue to understand is container-to-host privilege escalation. It is important that untrusted users do not gain root access while they are operating within a Docker container. At the moment, there is no distinction between root within a container and root outside of the container. What this means is, any untrusted user who can issue docker commands e.g., docker run, docker start, docker pull, can essentially gain root access on the host. That user can mount host storage e.g., -v /lib:/host/lib, which may have very, um, undesirable consequences.

Thankfully the future of user namespaces should be capable of mapping the root user within a container to a less privileged user on the host. Until then, user discretion is advised.

Troubleshooting

X-Docker-Registry-Version header not found in the response

If you are experiencing the following error

$ sudo docker pull docker.rc.fas.harvard.edu/eqc:0.1
2014/02/08 15:43:12 Invalid Registry endpoint: This does not look like a Registry server ("X-Docker-Registry-Version" header not found in the response)

It may be that you do not have the Incommon CA certificate installed. You can verify this by issuing the following command

$ wget https://docker.rc.fas.harvard.edu        
--2014-02-08 15:12:34--  https://docker.rc.fas.harvard.edu/
Resolving docker.rc.fas.harvard.edu (docker.rc.fas.harvard.edu)... 10.242.110.121
Connecting to docker.rc.fas.harvard.edu (docker.rc.fas.harvard.edu)|10.242.110.121|:443... connected.
ERROR: cannot verify docker.rc.fas.harvard.edu's certificate, issued by `/C=US/O=Internet2/OU=InCommon/CN=InCommon Server CA':
  Unable to locally verify the issuer's authority.
To connect to docker.rc.fas.harvard.edu insecurely, use `--no-check-certificate'
.

Paste the following certificate into /etc/ssl/certs/ca-bundle.crt (RHEL/CentOS)

-----BEGIN CERTIFICATE-----
MIIEwzCCA6ugAwIBAgIQf3HB06ImsNKxE/PmgWdkPjANBgkqhkiG9w0BAQUFADBv
MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk
ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF
eHRlcm5hbCBDQSBSb290MB4XDTEwMTIwNzAwMDAwMFoXDTIwMDUzMDEwNDgzOFow
UTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUludGVybmV0MjERMA8GA1UECxMISW5D
b21tb24xGzAZBgNVBAMTEkluQ29tbW9uIFNlcnZlciBDQTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAJd8x8j+s+kgaqOkT46ONFYGs3psqhCbSGErNpBp
4zQKR6e7e96qavvrgpWPyh1/r3WmqEzaIGdhGg2GwcrBh6+sTuTeYhsvnbGYr8YB
+xdw26wUWexvPzN/ppgL5OI4r/V/hW0OdASd9ieGx5uP53EqCPQDAkBjJH1AV49U
4FR+thNIYfHezg69tvpNmLLZDY15puCqzQyRmqXfq3O7yhR4XEcpocrFup/H2mD3
/+d/8tnaoS0PSRan0wCSz4pH2U341ZVm03T5gGMAT0yEFh+z9SQfoU7e6JXWsgsJ
iyxrx1wvjGPJmctSsWJ7cwFif2Ns2Gig7mqojR8p89AYrK0CAwEAAaOCAXcwggFz
MB8GA1UdIwQYMBaAFK29mHo0tCb3+sQmVO8DveAky1QaMB0GA1UdDgQWBBRIT1r6
L0qaXuBQ82t7VaXe9b40XTAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB
/wIBADARBgNVHSAECjAIMAYGBFUdIAAwRAYDVR0fBD0wOzA5oDegNYYzaHR0cDov
L2NybC51c2VydHJ1c3QuY29tL0FkZFRydXN0RXh0ZXJuYWxDQVJvb3QuY3JsMIGz
BggrBgEFBQcBAQSBpjCBozA/BggrBgEFBQcwAoYzaHR0cDovL2NydC51c2VydHJ1
c3QuY29tL0FkZFRydXN0RXh0ZXJuYWxDQVJvb3QucDdjMDkGCCsGAQUFBzAChi1o
dHRwOi8vY3J0LnVzZXJ0cnVzdC5jb20vQWRkVHJ1c3RVVE5TR0NDQS5jcnQwJQYI
KwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEF
BQADggEBAJNmIYB0RYVLwqvOMrAp/t3f1iRbvwNqb1A+DhuzDYijW+7EpBI7Vu8G
f89/IZVWO0Ex/uGqk9KV85UNPEerylwmrT7x+Yw0bhG+9GfjAkn5pnx7ZCXdF0by
UOPjCiE6SSTNxoRlaGdosEUtR5nNnKuGKRFy3NacNkN089SXnlag/l9AWNLV1358
xY4asgRckmYOha0uBs7Io9jrFCeR3s8XMIFTtmYSrTfk9e+WXCAONumsYn0ZgYr1
kGGmSavOPN/mymTugmU5RZUWukEGAJi6DFZh5MbGhgHPZqkiKQLWPc/EKo2Z3vsJ
FJ4O0dXG14HdrSSrrAcF4h1ow3BmX9M=
-----END CERTIFICATE-----

For Debian/Ubuntu, either place the certificate bundle into /etc/ssl/certs/ca-certificates.crt (Debian/Ubuntu), or you may need to put the contents into /usr/local/share/ca-certificates/incommon.crt and run

$ sudo update-ca-certificates
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.

Error pulling image (1.0) from some.registry.com/image, no such file or directory

There have been reported issues attempting to pull an image using Docker v0.8. You may see errors similar to the following

$ sudo docker pull docker.rc.fas.harvard.edu/eqc:0.1
Pulling repository docker.rc.fas.harvard.edu/eqc
dfdb7c8a0aef: Download complete
6a3191fa4cc6: Download complete
a1dfbada3de5: Pulling dependent layers
6dd481947faf: Download complete
10d8c565432a: Pulling dependent layers
514a3794a3ed: Download complete
4edeb16ccd5b: Pulling dependent layers
580200da68e5: Pulling dependent layers
70fb895303b3: Error pulling image (0.1) from docker.rc.fas.harvard.edu/eqc, no such file or directory
08ed7fb8d54b: Download complete
01f443328498: Pulling dependent layers
99a298b39c6b: Download complete
799ad5905c54: Downloading [========>                                          ] 105.8 MB/606.1 MB 4m0s
a30a5f726851: Pulling dependent layers
3a7837e29452: Download complete
72935e3696a3: Pulling dependent layers
802f9b9d4732: Download complete
0bd1ef379fa2: Download complete
539c0211cd76: Download complete
e413c69a2379: Download complete
33fc00201463: Pulling dependent layers
a2a98d9b21ab: Download complete
f9212305550b: Download complete
55bb112f76ed: Download complete
d61f0b2d851d: Pulling dependent layers
d5713909b50b: Download complete

At this time, my recommendation is to downgrade your Docker version to the latest version in the 0.7.x series, which is 0.7.6 at the moment.

You can download and install any previous docker build from get.docker.io

sudo mkdir -p /usr/local/bin
sudo wget https://get.docker.io/builds/Linux/x86_64/docker-0.7.6 -O /usr/local/bin/docker
sudo chmod +x /usr/local/bin/docker

If you have installed docker from e.g., apt-get or yum, that happens to register an upstart script, make sure you stop the docker daemon

sudo service docker stop

then modify the script to start the 0.7.6 version

sudo sed -i 's@DOCKER=/usr/bin@DOCKER=/usr/local/bin@g' /etc/init/docker.conf

and start the new daemon

sudo service docker start

Other

I've not yet identified the root cause of the following errors, but a reboot fixes them

Error: container_delete: Cannot destroy container 481a71ba838a: Driver devicemapper failed to remove root filesystem 481a71ba838aad155bdfb585270c13aeecade77bdebc692f7c9f5018d3870b3e: device or resource busy
Error pulling image (1.0) from some.registry.com/image, Driver aufs failed to create image rootfs 799ad5905c5499db00393b83c1a2178444790d31d8ca4784bc5973bb2675d530: mkdir /var/lib/docker/aufs/mnt/799ad5905c5499db00393b83c1a2178444790d31d8ca4784bc5973bb2675d530: file exists 78444790d31d8ca4784bc5973bb2675d530: file exists

Acknowledgements

  • a big shout-out to Mark Hollenbeck for illuminating the Docker v0.8 bug!
Personal tools
Namespaces

Variants
Actions
Open Data
Software
Tools and Utilities
Toolbox
Share