
Gocker: Docker implemented in 1.3k lines of Go - shuss
http://unixism.net/2020/06/containers-the-hard-way-gocker-a-mini-docker-written-in-go/
======
jraph
My 2018 joke has been implemented.

> Or Gocker, an implementation of Docker in go...

[https://news.ycombinator.com/item?id=16119842](https://news.ycombinator.com/item?id=16119842)

~~~
Tade0
As a kid I was a compulsive liar and would make up non-existent stories.

With the advent of search engines I discovered that any story I can come up
with actually happened somewhere in the world and has an article about it
already.

~~~
yboris
Sounds like a Gettier problem / Gettier case [0]

Example: Fake barn county. You're driving in a county and see lots of barns.
You point to one and say "that's a barn". Unbeknownst to you, almost all the
barns are not barns but are facades. By accident you actually are pointing at
one of the few real barns.

[0]
[https://en.wikipedia.org/wiki/Gettier_problem](https://en.wikipedia.org/wiki/Gettier_problem)

------
i_have_to_speak
Here's one in 100 lines of bash called, what else, "bocker":
[https://github.com/p8952/bocker](https://github.com/p8952/bocker)

~~~
D2187645
Now someone make one for fortran

~~~
swasheck
I have nipples, can you milk me?

~~~
Exmoor
ASK HN: Help me explain to my wife why I'm doubled over laughing about a
Fortran/Lactation joke.

~~~
d33
Could someone explain the joke to me?

~~~
nfrmatk
[https://youtu.be/bXNwzKo5Yps](https://youtu.be/bXNwzKo5Yps)

~~~
d33
The video doesn't seem to be available - perhaps it is marked as private?

~~~
giancarlostoro
Must be country block due to copyright cause it works for me, it's a scene
from Meet the Parents - Milking Cats.

~~~
misnome
And the portmanteau of Fortran/Docker is the same as the surname of the
character in the film

------
koffiezet
Pretty cool, and very educational for people not familiar with how these
things work

That said (and I've said this before), this is not really Docker. It's running
containers, not the same thing. If you want to compare it to anything, it's
runc, but that's not a good headline :)

Not that the docker architecture is that clean, but it is the combination of
ideas it brought to the table what made docker docker:

\- have APIs to do everything, from launching workloads to building images. \-
combining layered filesystems with os-level namespaces \- package format for
"images" coupled with a distribution system

If it was just starting containers, that was already possible for a good while
(and many shared hosting providers already did this).

I think many people underestimate the importance of the first point, having an
API to do all this. It's having this combination of ideas that democratised
cloud computing, it is what makes the bigger picture possible. While the
Docker API is currently not very important anymore, it showed the
possibilities, and made the limitations it had also very apparent, and at the
beginning, nobody had solutions for this. It took things like Mesos and
kubernetes to take it to the next level, with the latter having become the de-
facto standard container API.

~~~
notrandom
> If you want to compare it to anything, it's runc, but that's not a good
> headline :)

I don’t know, gunc is a pretty good name.

------
grensley
Honestly, I don't like lines of code as a metric for anything over the novelty
amount of 1. And even then, that's usually some demonic Python list
comprehension code.

That being said, the code here is pretty approachable and they weren't
noticeably trying to cram it into fewer lines. Like the library, not this
marketing.

~~~
Frost1x
While I tend to agree, I think LoC can give a sense of scale for large systems
and at least a tiny bit of insight about its potential complexity.

I recently worked with a client on an integration effort that had to touch
many different points on a (massive, for me) codebase with tens of millions of
LoC. For that, LoC was the only reasonable metric I could come up with to try
and convey the scale and complexity of the task at hand--being quite ignorant
of the system's (and subsystems') architecture(s) at the time.

That was further complicated by the way the massive codebase supported all
sorts of dynamic compositions and certain interactions needed to work with
baseline compositions expressed in a form of markup totaling about about 5
times the amount of the actual code base, amongst other things.

These folks thought the integration could be done for $80k tops and in a
couple months. It took LoC metrics to get them to understand the potential
complexity at hand and that a lot more time needed to be spent in assessment
and design before jumping in.

~~~
nemosaltat
Hopefully you’ll forgive this potentially obvious question- is LoC (still?)
generally accepted to be bounded ar 80 col?

~~~
0xEFF
In some circles yes. Linus recently weighed in against the 80 limit.

[http://lkml.iu.edu/hypermail/linux/kernel/2005.3/08168.html](http://lkml.iu.edu/hypermail/linux/kernel/2005.3/08168.html)

------
miked85
Isn’t Docker implemented in Go already?

~~~
birdyrooster
Doesn't matter, rewrite it and make the name a gortmanteau.

~~~
rantwasp
take your upvote and get out :))

~~~
stock_toaster
I think you mean, take your upvote and _go_. ;)

~~~
rantwasp
take your upvote, check err and go.

------
forty
The HN title is not great. It's not docker, it's a mini-docker as the original
title says. For example there is no "gocker build" command.

I wonder if that can run in unprivileged docker.

------
drej
Check out this Liz Rice talk on implementing container tech from scratch. Very
clear.
[https://www.youtube.com/watch?v=8fi7uSYlOdc](https://www.youtube.com/watch?v=8fi7uSYlOdc)

------
pbreit
Can someone explain the value/purpose of docker to someone who (easily)
deploys regular apps to a Digital Ocean droplet?

~~~
ryanmcbride
The joke that I think actually explains it pretty well is that it eliminates
the "well it works on _my_ machine" problem, by not just shipping the code,
but shipping the machine.

~~~
MaxBarraclough
*shipping the userland

It's not the equivalent of handing over a VM image. You're still open to
unintended sensitivity to kernel versions, for instance.

~~~
ryanmcbride
I know that this joke isn't exactly what's happening. I just feel like it's a
good way to explain the _idea_ of Docker to people who have no idea what it
is.

------
javajosh
Has anyone made an "X implemented in N lines of Y" site yet?

~~~
grogenaut
How many lines of code can you make it in?

~~~
Skunkleton
> How many lines of code can you make it in?

xinylines.io - implemented in zero lines of code, and one large shameful html
file.

------
kohtatsu
This talk by Bryan Cantrill on the history of OS-level virtualization is
great.

[https://youtu.be/hgN8pCMLI2U](https://youtu.be/hgN8pCMLI2U)

Apparently the first version of Jails was a few hundred lines of code.

------
gorgoiler
Very nice! I love projects like this that return to first principles, and
rebuild the core without the cruft. It is refreshing.

The dependency on netlink adds a little to the code weight. Some of this also
feels like it could just be a shell script (sh, unlike Go, ships with built in
Linux support for netlink, and sticks with dotted-quad-string types for IP
addresses instead of mixing with int32!)

I did not realize cgroups were this simple to manipulate. Thank you for the
enlightenment.

~~~
nine_k
TBH, all network utilities I ever saw accept the int32 form of IP addresses.
E.g. ping 127.0.0.1 can also be written as

    
    
      ping 0x7f000001
    

Try it; it works.

~~~
Erwin
URLs too, though Chrome makes them canonical:

[http://0xacd91124/](http://0xacd91124/) \-- Google

I did a quick search for whether "fun" Hex strings are reachable, but didn't
find any (e.g. the canonical [http://0xcafebabe](http://0xcafebabe)). Random
combination of hex-words are login pages to web cameras or cable modems. I
didn't try to e.g. replace "e" with "3", e.g.
[http://0xcaf3babe/](http://0xcaf3babe/)

------
lima
Cool educational project!

runc - which is the low-component that does the actual container launching in
Docker and other runtimes - is mostly written in Go and quite approachable[1],
if you're curious what a production-ready container runtime looks like.

Namespaces look simple on the surface, but there are plenty of subleties,
particularly when using Go:

\- `runtime.LockOSThread()` has to be called before entering a namespace to
pin the goroutine to a specific OS thread. The unshare call affects only the
current thread[2][3]. Even then, you have to be careful not to spawn any new
goroutines[4]. For this reason, parts of runc are currently written in C (you
could technically implement it in pure Go, but the maintainers believe it's
easier to reason about the C implementation).

\- The container runtime has to reexec itself from a copy of itself in a memfd
to prevent the container from writing to /proc/self/exe[5][6].

\- Various race conditions and symlink attacks during container setup[7][8].

\- Some parts of the container initialization have to be done after switching
to the new rootfs, which is attacker-controlled territory[9][10].

\- ... and plenty of other gotchas, the runc code is full of comments that
explain why things have to be done in particular ways.

Obviously, Gocker is an experiment and does none of these things, and you
shouldn't run it on anything that you care about :) Sometimes things are
complex for a reason.

[1]:
[https://github.com/opencontainers/runc](https://github.com/opencontainers/runc)

[2]:
[https://golang.org/doc/go1.10#runtime](https://golang.org/doc/go1.10#runtime)

[3]:
[https://github.com/golang/go/issues/20676](https://github.com/golang/go/issues/20676)

[4]: [https://www.weave.works/blog/linux-namespaces-golang-
followu...](https://www.weave.works/blog/linux-namespaces-golang-followup)

[5]:
[https://github.com/opencontainers/runc/pull/1984](https://github.com/opencontainers/runc/pull/1984)

[6]:
[https://github.com/opencontainers/runc/commit/0a8e4117e7f715...](https://github.com/opencontainers/runc/commit/0a8e4117e7f715d5fbeef398405813ce8e88558b)

[7]:
[https://github.com/opencontainers/runc/issues?q=race+conditi...](https://github.com/opencontainers/runc/issues?q=race+condition)

[8]: [https://github.com/cyphar/filepath-
securejoin](https://github.com/cyphar/filepath-securejoin)

[9]:
[https://github.com/opencontainers/runc/pull/2207](https://github.com/opencontainers/runc/pull/2207)

[10]:
[https://github.com/opencontainers/runc/issues/2128](https://github.com/opencontainers/runc/issues/2128)

