How to run Docker in a LXD container

We are running Ubuntu 16.04 and LXD 2.18 (from the lxd-stable PPA). Let’s get Docker (docker-ce) to run in a container!

General instructions on running Docker (docker.io, from the Ubuntu repositories) in an LXD container can be found at LXD 2.0: Docker in LXD [7/12].

 

First, let’s launch a LXD container in a way that will make it suitable to run Docker in it.

$ lxc launch ubuntu:x docker -c security.nesting=true
Creating docker
Starting docker
$

Here, docker is just the name of the LXD Container. The security.nesting feature is needed because our Docker installation will be a container inside the LXD container.

 

Second, let’s install Docker CE on Ubuntu.

ubuntu@docker:~$ sudo apt-get update
Get:1 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB]
...
Reading package lists... Done
ubuntu@docker:~$ sudo apt-get install \
> apt-transport-https \
> ca-certificates \
> curl \
> software-properties-common
Reading package lists... Done
...
The following additional packages will be installed:
 libcurl3-gnutls
The following packages will be upgraded:
 curl libcurl3-gnutls
2 upgraded, 0 newly installed, 0 to remove and 20 not upgraded.
...
ubuntu@docker:~$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
OK
ubuntu@docker:~$ sudo apt-key fingerprint 0EBFCD88
pub 4096R/0EBFCD88 2017-02-22
 Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid Docker Release (CE deb) <docker@docker.com>
sub 4096R/F273FCD8 2017-02-22

ubuntu@docker:~$ sudo add-apt-repository \
> "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
> $(lsb_release -cs) \
> stable"
ubuntu@docker:~$ sudo apt-get update
...
ubuntu@docker:~$ sudo apt-get install docker-ce
...
The following NEW packages will be installed:
 aufs-tools cgroupfs-mount docker-ce libltdl7
0 upgraded, 4 newly installed, 0 to remove and 20 not upgraded.
Need to get 21.2 MB of archives.
After this operation, 100 MB of additional disk space will be used.
...
ubuntu@docker:~$

 

Third, let’s test that Docker is working, by running the hello-world image.

ubuntu@docker:~$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
5b0f327be733: Pull complete 
Digest: sha256:07d5f7800dfe37b8c2196c7b1c524c33808ce2e0f74e7aa00e603295ca9a0972
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
 executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
 to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://cloud.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

ubuntu@docker:~$

 

Finally, let’s go full inception by running Ubuntu in a Docker container inside an Ubuntu LXD container on Ubuntu 16.04.

ubuntu@docker:~$ sudo docker run -it ubuntu bash
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
ae79f2514705: Pull complete 
5ad56d5fc149: Pull complete 
170e558760e8: Pull complete 
395460e233f5: Pull complete 
6f01dc62e444: Pull complete 
Digest: sha256:506e2d5852de1d7c90d538c5332bd3cc33b9cbd26f6ca653875899c505c82687
Status: Downloaded newer image for ubuntu:latest
root@cc7fe5598b2e:/# exit

 

Before we finish, let’s check what docker info says.

ubuntu@docker:~$ sudo docker info
Containers: 2
 Running: 0
 Paused: 0
 Stopped: 2
Images: 2
Server Version: 17.09.0-ce
Storage Driver: vfs
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 06b9cb35161009dcb7123345749fef02f7cea8e0
runc version: 3f2f8b84a77f73d38244dd690525642a72156c64
init version: 949e6fa
Security Options:
 apparmor
 seccomp
 Profile: default
Kernel Version: 4.10.0-37-generic
Operating System: Ubuntu 16.04.3 LTS
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 4.053 GiB
Name: docker
ID: KEA5:KU1N:MM6U:2ROA:UHJ5:3VRR:3B6C:ZWF4:KTOB:V6OT:ROLI:CAT3
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false

WARNING: No swap limit support
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
ubuntu@docker:~$

An issue here is that the Docker storage driver is vfs, instead of aufs or overlay2. The Docker package in the Ubuntu repositories (name: docker.io) has modifications to make it work better with LXD. There are a few questions here on how to get a different storage driver and a few things are still unclear to me.

Permanent link to this article: https://blog.simos.info/how-to-run-docker-in-a-lxd-container/

3 comments

    • Giorgio on January 7, 2019 at 16:50
    • Reply

    I tried but finally end up in
    Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
    Can you elaborate, I don’t know what Iam doing wrong

      • Michael on April 16, 2019 at 20:21
      • Reply

      Use root

        • Michael on April 16, 2019 at 20:22
        • Reply

        or sudo

Leave a Reply to MichaelCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.