patterndockerModerate
Why is Docker-in-Docker considered bad?
Viewed 0 times
dockerbadwhyconsidered
Problem
In August 2013 Jérôme Petazzoni created Docker in Docker,
As of Docker 1.8, released two years later in August 2015, Docker in Docker is directly supported by Docker out of the box. However, the use of Docker in Docker comes with a warning, seemingly related to Jérôme's Post: Using Docker-in-Docker for your CI or testing environment? Think twice. which focuses on the reasons why Docker in Docker is not a great choice for Continuous Integration.
Why is it considered bad to use Docker in Docker? Is it simply a case for avoiding Turtles all the way down? or performance considerations?
dind for short, this allowed Docker containers to be created inside of Docker Containers, this functionality proved very popular resulting in Jérôme's GitHub Repository receiving over a thousand stars and three hundred forks.As of Docker 1.8, released two years later in August 2015, Docker in Docker is directly supported by Docker out of the box. However, the use of Docker in Docker comes with a warning, seemingly related to Jérôme's Post: Using Docker-in-Docker for your CI or testing environment? Think twice. which focuses on the reasons why Docker in Docker is not a great choice for Continuous Integration.
Why is it considered bad to use Docker in Docker? Is it simply a case for avoiding Turtles all the way down? or performance considerations?
Solution
Continuous Integration Concerns
In short: Docker in Docker (dind) doesn't handle concurrency well.
The reason why you shouldn't use dind for CI is because Docker was designed to have exclusive access to the directory it uses for storage (normally
Other Concerns
From the link the OP posted, security concerns arise as the system will try to apply security policies in a very "CSS-like" fashion where a lower container could have access to an outer container's resources unless explicitly prohibited. Remember when you could access web server resources by doing something like "mywebsite.com/../another_folder/private_resource.txt"? Also, sometimes filesystems just don't play well with each other when they're nested in this way.
The Fix
Thankfully, the blog post in the OP has a good solution for the issue. Unless your needs are not met by "build/run/push Docker containers from your CI system itself running on Docker", you can use
Reference (from OP): Using Docker-in-Docker for your CI or testing environment? Think twice.
In short: Docker in Docker (dind) doesn't handle concurrency well.
The reason why you shouldn't use dind for CI is because Docker was designed to have exclusive access to the directory it uses for storage (normally
/var/lib/docker). Dind doesn't respect this as all child processes use this directory concurrently. Every time you rebuild (from CI for example), anything related to your app in this directory could get wiped out and forced to start from zero. How would your users like it if they entered their payment details, clicked "Purchase", and suddenly found themselves back on the login screen as if they'd never done anything? That's just not good UX. Two rebuilds occur at once? That's really going to end badly for everyone involved (including your data integrity).Other Concerns
From the link the OP posted, security concerns arise as the system will try to apply security policies in a very "CSS-like" fashion where a lower container could have access to an outer container's resources unless explicitly prohibited. Remember when you could access web server resources by doing something like "mywebsite.com/../another_folder/private_resource.txt"? Also, sometimes filesystems just don't play well with each other when they're nested in this way.
The Fix
Thankfully, the blog post in the OP has a good solution for the issue. Unless your needs are not met by "build/run/push Docker containers from your CI system itself running on Docker", you can use
-v mode (add a data volume to your container) on the Docker socket (usually /var/run/docker.sock:/var/run/docker.sock) to allow the kind of access you need to the "shared" data volume. These containers will be started alongside the parent, instead of underneath, forcing synchronous IO. Now you have the same thing (almost) as dind but without the downsides that come with Docker not being build for concurrency.Reference (from OP): Using Docker-in-Docker for your CI or testing environment? Think twice.
Context
StackExchange DevOps Q#676, answer score: 19
Revisions (0)
No revisions yet.