top | item 14487805

Linux Container Internals

235 points| archrabbit | 8 years ago |rabbitstack.github.io | reply

21 comments

order
[+] kragniz|8 years ago|reply
Writing the basics of a container runtime is easier than it sounds. Last summer I was curious how they work and wrote something simple in python that can run docker images:

https://github.com/kragniz/omochabako/blob/master/omochabako

https://asciinema.org/a/77296?speed=2&autoplay=true

I learned a lot doing this, and I'd recommend it to anyone who's interested about containers.

[+] pooktrain|8 years ago|reply
Thanks for sharing!

When you set out to do this, had you studied docker's source code at all? Or did you just have a basic understanding of containers? Other than the link from OP, are there any resources you'd recommend to get one to the point where you have enough understanding of the concepts without having to "cheat" and look at the docker implementation?

I want to do this too, but it's not as much fun if you need to go to the source due to not understanding the fundamentals.

[+] bogomipz|8 years ago|reply
Thanks for the links. What was your starting point the Docker/Golang source?
[+] jbb67|8 years ago|reply
Which language is the sample code written in? Looks.... awful.
[+] deathanatos|8 years ago|reply
There's some places where this example could be better written. For example, this:

  let oldrootfs = String::from(format!("{}/.oldrootfs", rootfs.clone()));
can be reduced to either of:

  let oldrootfs = format!("{}/.oldrootfs", rootfs);
  let oldrootfs = rootfs.clone() + "/.oldrootfs";     
You could also do something like

  Path::new(rootfs).join(".oldrootfs")
but I'm not entirely sure how to get that to a pointer for the FFI stuff. It seems like the smartest way would be to go through OsStr, and if one wanted to use Path instead (which seems like the appropriate type), then sys_pivot_root should probably be changed to accept them instead.

A lot of the complexity here is that you're interfacing with C, which is inherently unsafe, and cdecl is very simple in what can be passed. (And stuff like POSIX file paths are just hard to statically type around, because they're not text strings.) Normally, you'd write some wrappers (which the original author is well on the way to), and the rest of the code should look much simpler.

Similarly here:

  create_dir(oldrootfs.clone());
The clone isn't needed; you can simply borrow oldrootfs:

  create_dir(&oldrootfs);
If you change rootfs in both pivot_root and sys_pivot_root to a &str, you can then call it as just

  pivot_root("/")
which is simpler than

  pivot_root(String::from("/"))
(I generally find that taking &str is simpler than String, if you're not going to modify the String object.)
[+] mhh__|8 years ago|reply
Rust?
[+] archrabbit|8 years ago|reply
it's Rust. Btw, did you see erlang or clojure? ;p