
Microcontainers – Tiny, Portable Docker Containers - kiyanwang
http://www.iron.io/blog/2016/01/microcontainers-tiny-portable-containers.html
======
_query
> Docker enables you to package up your application along with all of the
> application’s dependencies into a nice self-contained image. You can then
> use use that image to run your application in containers.

Actually docker was created to enable easy scaling of web applications. If you
want to package your application up take a look at some modern package
managers. By using a modern package manager like nix you can work around the
issues of containers while still keeping the "it just works" advantage of
containers.

This does not mean that containers are bad, it's just that using a good
package manager is usually a simpler solution.

Take a look at my blog post if you want to read more on this:
[http://www.mpscholten.de/docker/2016/01/27/you-are-most-
like...](http://www.mpscholten.de/docker/2016/01/27/you-are-most-likely-
misusing-docker.html)

~~~
mstade
I mostly agree with what you're saying, but what caught my eye was:

> About the author > Hey! I’m Marc, an eighteen years old software engineer
> located in Germany.

You're obviously quite knowledgeable and well spoken for such a young age, and
presumably English isn't your first language either. I just wanted to say keep
up the good work, you have a bright future ahead of you – kudos!

~~~
wcummings
Surprised he advertises his age, I started working around that age and pretty
deliberately avoided age as a topic of discussion. Age is something best left
unmentioned in a professional context.

~~~
_query
Thanks for the advice. I've thought about it a little bit and decided to
remove it with my next update to the web page.

~~~
mstade
I'd love to say it's not sage advice, but it is. Unfortunately, once people
know your age they will – consciously or subconsciously – treat you
differently. I rather quickly opted to never disclosing my age in any context,
unless it is absolutely necessary (it almost never is.) It's just easier that
way, leads to less discrimination. Unlike skin color or other highly visual
traits, it's one aspect of your person you _can_ hide without any
significantly negative consequence.

------
tmd
Docker storage engines remember all the layers by storing incremental
differences so it makes little sense to have a layer that only removes things
(like the last RUN in [https://github.com/iron-
io/dockers/blob/master/ruby/Dockerfi...](https://github.com/iron-
io/dockers/blob/master/ruby/Dockerfile)). You can see with `docker history
<image>` that this layer has 0 bytes and you can access anything that it
removes by using the parent image (`docker run -it 88ae7e32865f ls
/var/cache/apk`).

In this case it doesn't make much difference (a couple of MB perhaps) but
often you'll see people chaining all the commands and ending it with a cleanup
in a single RUN like here: [https://github.com/docker-
library/ruby/blob/ccbf9e54f60ba245...](https://github.com/docker-
library/ruby/blob/ccbf9e54f60ba2455f4f18e223c5745a14657bdb/2.0/Dockerfile)

~~~
grkvlt
Heh, looks like the author fixed this [1] and it now uses the technique you
suggest, based on issue #22 [2] which restates the same thing as your comment,
basically chaining everything together with `&&` in a single `RUN` entry.

[1] [https://github.com/iron-
io/dockers/commit/71687edb849dcb9079...](https://github.com/iron-
io/dockers/commit/71687edb849dcb9079572f1de251106f6e666ed9) [2]
[https://github.com/iron-io/dockers/issues/22](https://github.com/iron-
io/dockers/issues/22)

------
lox
Do we really need to brand using smaller containers as microcontainers? Why
not submit these as pull requests to the official docker images rather than
introducing more fragmentation?

Also worth noting that the official docker images are moving towards alpine.
Of course if you have ruby or node apps your biggest space hog is still going
to be your packages.

~~~
TheDong
There's also a very good reason to _not_ move some things to alpine, including
ruby and node applications. A significant number of ruby and nodejs apps
depend on some c/c++ code hidden away in this module or that gem. Any time
you're compiling c/c++ code, you run into a chance of musl vs libc causing
differences.

These differences can range from building requiring different options to the
application having strange performance characteristics to random crashes
(rare!).

In addition, people who write these modules typically test against an ubuntu
or debian system, so those are much safer bets. Alpine makes no serious
attempt to match packages with those, either in breadth nor version.

It really isn't feasible to unilaterally move people, and for compatibility
reasons Docker does not often change tags in such a drastic way.

The official docker images are _often_ offering alpine _alternatives_ in
different tags, which is not the same as "moving towards" as you remarked.

~~~
shykes
We are in fact moving towards alpine, but can't just switch the default tags
overnight in case some users depend on the properties of certain distros.

~~~
ishtu
excited to see recently added support[1] of dns search domains in musl (and
therefore Alpine).

[1] [http://git.musl-
libc.org/cgit/musl/commit/?id=3d6e2e477ced37...](http://git.musl-
libc.org/cgit/musl/commit/?id=3d6e2e477ced37fd328870f018950b283cb7293c)

------
philipwood
I've always felt that VMs are a sign that show that OSes have imperfectly
abstracted the virtualization of their resources. A "design smell" if you
will.

When you get right down to it a window is a virtualization of a screen, a
packet switching network is a virtualization of a fixed line, a process is a
virtualization of a CPU, etc. (I can't remember who I'm quoting).

The direction this is all heading (VMs, containers, unikernels, etc.) feels
like confirmation of this to me. A series of corrections aligning our OSes
with more ideal/virtual abstractions.

~~~
sirtaj
Plan 9 was a realization of this line of abstraction, in a lot of ways. Even
though I never used the platform for anything serious, I still draw
inspiration from it all these years later.

------
antouank
Isn't it the same as using "alpine" as base ?
[https://news.ycombinator.com/item?id=10782897](https://news.ycombinator.com/item?id=10782897)

~~~
woadwarrior01
It looks like their base image is based off of the alpine image[1].

[1]: [https://github.com/iron-
io/dockers/blob/master/base/Dockerfi...](https://github.com/iron-
io/dockers/blob/master/base/Dockerfile)

------
schappim
I have to say I love the work iron.io does. Their "iron worker"[1] service is
awesome (think Amazon Lambda for pretty much any common language).

[1] [http://www.iron.io/worker/](http://www.iron.io/worker/)

~~~
markherhold
Interesting. How long does it take an "iron worker" to start code execution
after a webhook (latency)?

~~~
treeder
Typically a couple seconds.

------
_Marak_
This seems to solve one of my biggest issues with trying to use individual
Dockers to run microservices.

Past experiments proved that it wasn't feasible to match one microservice
request to one Docker instance. The size of each Docker required vertical
scaling of the microservices per container, which was not ideal.

Good job Iron.io! Might trying playing with these at some point.

~~~
TheDong
... Why? The scalability difference (in terms of disk space) between having
multiple services per container and many containers is, in practice, zero.

That's because of layered filesystems and most of the language runtimes and
other images pulling from a small set of base images.

For example, if you have two node applications, the base "nodejs" image is
633MB in size. If both of your applications have "FROM node" at the top and
proceed to add different applications (say 2MB each), you'll find the "node"
portion is totally shared and only the diff, you copying in your application's
files, is different. You'll only store a single copy of the 633MB node image +
your two application image's diffs, for a total of 637MB.

That number is the same if you bundle the applications (vertically scale as
you say it).

This is also sorta true across language runtimes too! With some creative
diffing, I experimentally tested the difference between the ruby and nodejs
images. It turns out there's just under 600MB in common. The ruby image has
116MB of data the node one doesn't, and the node one has ~40MB of data the
ruby one doesn't.

Again, you'll end up using a very small amount of disk space.

These savings also apply to downloading images after the initial base layers
are downloaded (e.g. docker pull ruby; docker pull node will only download
roughly 750MB of data, even though that's two >600MB images).

In any case, it's strange that disk space on the order of a couple gigs is
even a scaling concern at all; I'd imagine memory or your application's disk
needs would far outweigh such concerns.

My main point, however, is that your discussion of one service per container
vs multiple services per container being any different in terms of disk space
is rubbish and utterly false.

~~~
_Marak_
I would assume the smaller images would also result in a smaller memory
footprint for running the images and a general reduction in time of starting
images. You seem to know a lot of about Docker, is that a wrong assumption?

The scale which I'm discussing is in the order of at least several hundred
docker images per second. Previous attempts at making this work involved keep
a warm elastic pool of Dockers. I'm working with at least 11 environments, (
which all have separate dependency requirements ).

Instead of trying to manage a very large pool of Dockers, I opted for a
smaller pool with several larger servers to scale the microservices vertically
( using tools like chroot to help try to isolate each service per silo ).

My main issue with using Docker for this was the bulk of the containers.
Startup time, RAM consumption, and the size of the images were all causing me
issues.

~~~
lisivka
Your assumptions are wrong. Glibc is faster (and better) than musl. Systemd is
faster (and better) than SYSV init scripts.

Moreover, for example, I can update my running containers based on Fedora 23
without restarting container, by issuing "dnf update", which will download
updated package from local server, which is much faster that to build
container, publish it to hub, download it back, restart container (even when
only static files are changed).

~~~
sandGorgon
whoa - you have a container with working systemd ? I thought that was an
unfixed bug -
[https://github.com/docker/docker/pull/5773](https://github.com/docker/docker/pull/5773)
and
[https://github.com/docker/docker/issues/3629](https://github.com/docker/docker/issues/3629)

~~~
lisivka
Yep. It have some quirks (hard to shutdown properly), but it works.

    
    
        [vlisivka@apollo5 docker-centos7-systemd-unpriv]$ ./enter.sh
        [root@e3c3dd7539ad /]# ps ax
        PID TTY      STAT   TIME COMMAND
            1 ?        Ss     0:00 /usr/lib/systemd/systemd
           71 ?        Ss     0:00 /usr/lib/systemd/systemd-journald
           74 ?        Ss     0:00 bash
           92 ?        R+     0:00 ps ax
    

[https://github.com/vlisivka/docker-centos7-systemd-
unpriv](https://github.com/vlisivka/docker-centos7-systemd-unpriv)

~~~
sandGorgon
Hmm.. It's not worth it for me right now. I am using supervisord which works
brilliantly

------
BenjaminCoe
I believe Alpine is GPL licensed. Curious what companies are using Alpine?
What ramifications does this have on the licensing of a micro service running
in Alpine.

~~~
danieldk
The GPL only comes into effect when you redistribute software. Since most
companies will probably use it to deploy their own software, GPL does not
matter much in practice.

Besides that, for an application only the licenses of libraries that you link
against are relevant.

------
bmajz
While it's nice to have small on-disk containers for some applications (e.g.
deployment pipelines/CI), for production, I've found that Alpine doesn't save
you much in RAM. I'd love to see this become something people look at as well
when evaluating base images. To me at least, this was a far more important
constraint when running Docker in production.

~~~
bmajz
To be fair, the case I was testing was node, so the packages could be killing
me. Could be much better for a standalone bundled application.

------
mullsork
I thought everyone was doing this already. The first thing I noticed when
pushing my first test version of our Node server was that the images was way
above what I thought it should be. It seems really odd that the "official"
Docker images are this big. Perhaps to enable easy development within the VMs,
and not meaning for these to be distributed?

------
ohdrat
I predict that the term "micro" will be replaced by the term "modular", and
that docker will create a replacement for the microcontainer named the modular
loader/container.

------
ecesena
Related repo with micro containers for each language:
[https://github.com/iron-io/dockers](https://github.com/iron-io/dockers)

------
jorgecurio
how are you guys using docker btw? I keep hearing about it, I like it but have
almost to no reason to use it.

~~~
tombh
Amongst other things I use it to run Skype on my Linux laptop, cos I don't
trust Microsoft.

[https://github.com/sameersbn/docker-
skype](https://github.com/sameersbn/docker-skype)

~~~
kasey_junk
What trust does docker give you? It seems less secure in this instance than
properly permissioning skype or creating a true vm for it?

