├── README.md ├── .gitignore ├── 88x31.png ├── rootdir.png ├── psauxinit.png ├── pstreeinit.png ├── porquenolosdos.png ├── ansible_docker_blog.png ├── debiantreecontents.png ├── dockerimagetarcontents.png ├── Dockerfile ├── README └── docker-without-docker.slide /README.md: -------------------------------------------------------------------------------- 1 | README -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.swo 3 | *.swn 4 | -------------------------------------------------------------------------------- /88x31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChimeraCoder/docker-without-docker/HEAD/88x31.png -------------------------------------------------------------------------------- /rootdir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChimeraCoder/docker-without-docker/HEAD/rootdir.png -------------------------------------------------------------------------------- /psauxinit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChimeraCoder/docker-without-docker/HEAD/psauxinit.png -------------------------------------------------------------------------------- /pstreeinit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChimeraCoder/docker-without-docker/HEAD/pstreeinit.png -------------------------------------------------------------------------------- /porquenolosdos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChimeraCoder/docker-without-docker/HEAD/porquenolosdos.png -------------------------------------------------------------------------------- /ansible_docker_blog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChimeraCoder/docker-without-docker/HEAD/ansible_docker_blog.png -------------------------------------------------------------------------------- /debiantreecontents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChimeraCoder/docker-without-docker/HEAD/debiantreecontents.png -------------------------------------------------------------------------------- /dockerimagetarcontents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChimeraCoder/docker-without-docker/HEAD/dockerimagetarcontents.png -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:wheezy 2 | MAINTAINER Aditya Mukerjee 3 | 4 | RUN apt-get update 5 | RUN apt-get install -y procps psmisc 6 | CMD ["/bin/bash"] 7 | 8 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Docker Without Docker 2 | =============================== 3 | 4 | This presentation was a given at the [Recurse Center](https://www.recurse.com) on 16 April 2015 5 | 6 | 7 | Fully rendered slides are available on the [project page](https://chimeracoder.github.io/docker-without-docker/#1) 8 | 9 | 10 | License 11 | ------------- 12 | 13 | All slides provided under the [CC-BY-SA](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US) license. 14 | 15 | All code is provided under version 3 of the GNU Public License (GPLv3), unless otherwise noted. 16 | -------------------------------------------------------------------------------- /docker-without-docker.slide: -------------------------------------------------------------------------------- 1 | Docker Without Docker 2 | Recurse Center 3 | 16 Apr 2015 4 | 5 | Aditya Mukerjee 6 | 7 | http://www.adityamukerjee.net 8 | @chimeracoder 9 | 10 | * 11 | .image 88x31.png 12 | 13 | * Some common questions 14 | 15 | - What is Docker? Do I really need it? 16 | - How does Docker actually work? 17 | - How can I set up a single dev environment to work on any computer? 18 | - My code works on my computer. Now how do I put it on a production server? 19 | - Can't I just write code and have it "just work" everywhere? 20 | - Package managers suck. What's a better way? 21 | - Can I make my virtual machine run faster? 22 | - Is it possible to run Docker containers without even running Docker? 23 | 24 | * Wouldn't it be nice if 25 | - We could use `git` to manage an entire server or desktop? 26 | - We could provision/deprovision an entire machine with a single command? 27 | 28 | 29 | * Why not virtualize 30 | - Performance 31 | - Interoperability (inter-communication) 32 | 33 | 34 | * What is an operating system ("distro")? 35 | - At its core, your OS is just a bunch of files 36 | - Along with an `/sbin/init` file 37 | - Different distributions distribute different files 38 | 39 | That's basically it. 40 | 41 | .image rootdir.png 42 | 43 | * Inspecting processes 44 | .image psauxinit.png 45 | .image pstreeinit.png 46 | 47 | 48 | 49 | * But what's actually in /sbin/init? 50 | - There is *nothing*particularly*special* about what goes here! 51 | - ...But it's almost always the same thing 52 | - `sysvinit` (1983 - ~2010) 53 | - `systemd` (2010 - ?) 54 | 55 | *Within*9*days,*all*of*the*top*10*Linux*distributions*will*use*systemd*by*default,*or*descend*from*one*that*does.* 56 | 57 | 58 | * What tools does systemd provide? 59 | - `systemctl` (system management, daemonization, etc.) 60 | - `journactl` (logging) 61 | - `systemd-analyze` (system profiling) 62 | - `machinectl` (machine management) 63 | 64 | These are all *already* available on any machine using systemd 65 | 66 | 67 | * How do you create a distribution from scratch? 68 | 0. Create a directory that represents the new root directory (ie, "/") 69 | 1. Move all the right files there, either manually, or with a tool like deboostrap, pacstrap, yum, etc.) 70 | 2) Tar your directory and ship it 71 | 72 | Congratulations! This directory is a pseudo-snapshot of your new distro! 73 | 74 | 75 | * Where does Docker come in? 76 | - Docker can also create these 'snapshots', using a `Dockerfile` 77 | 78 | .code Dockerfile 79 | 80 | 81 | Build and run: 82 | 83 | $ docker build -t bashtest . 84 | $ docker run -it bashtest 85 | 86 | (as with Git hashes, you can use the container ID or a prefix instead of the name) 87 | 88 | 89 | - Question: What runs as PID 1? 90 | 91 | 92 | * Dissecting the Dockerfile 93 | 94 | .code Dockerfile 95 | 96 | $ docker ps 97 | $ docker exec ps aux 98 | 99 | 100 | * Can I access this 'snapshot'? 101 | - Yes! 102 | 103 | $ docker export > img.tar 104 | 105 | Let's inspect that: 106 | 107 | $ mkdir ~/bashtestcontainer 108 | $ tar -C ~/bashtestcontainer -xvf img.tar 109 | 110 | 111 | * What's inside the tarfile? 112 | 113 | .image dockerimagetarcontents.png 114 | 115 | Does this look familiar? 116 | 117 | 118 | * Can I do this without Docker? 119 | - Yes! 120 | 121 | $ mkdir debian-tree 122 | $ debootstrap --arch=amd64 unstable debian-tree 123 | 124 | .image debiantreecontents.png 125 | 126 | Does *this* look familiar? 127 | 128 | 129 | * How do we run the Debian image, though? 130 | - The *systemd-nspawn* command runs a command or OS in a lightweight namespace container 131 | - _"In_many_ways_it_is_similar_to_chroot(1),_but_more_powerful_since_it_fully_virtualizes_the_file_system_hierarchy,_as_well_as_the_process_tree,_the_various_IPC_subsystems_and_the_host_and_domain_name."_ 132 | 133 | 134 | * Let's try this out 135 | 136 | $ systemd-nspawn -D debian-tree/ /bin/echo "hello, outside world!" 137 | $ systemd-nspawn -D debian-tree/ /bin/bash 138 | $ systemd-nspawn -D debian-tree/ /sbin/init 139 | 140 | 141 | * We can manage our containers with machinectl 142 | 143 | $ machinectl list 144 | $ machinectl status debian-tree 145 | $ machinectl reboot debian-tree 146 | $ machinectl poweroff debian-tree 147 | 148 | Note that these are analogous to 149 | 150 | $ systemctl reboot 151 | $ systemctl poweroff 152 | 153 | which we use for managing our systemd (host) servers 154 | 155 | 156 | * But all this has to be on our local machine, right? 157 | 158 | - Nope. 159 | 160 | $ machinectl -H foo@example.com 161 | $ machinectl -H foo@example.com:debian-tree 162 | 163 | 164 | 165 | * Daemons, services, and units 166 | 167 | 168 | * Daemonizing, the old way: 169 | - Write a shell script 170 | - Implementing each target 171 | - Which executes sequentially with others 172 | - Make sure your program remembers to fork twice, not just once! 173 | - Oh, but hopefully it didn't call setuid 174 | - Which file is the PID written in again? 175 | - But wait, did the PID get reused? 176 | 177 | All in all, it requires [[http://www.netzmafia.de/skripten/unix/linux-daemon-howto.html][fifteen different steps]], with serious consequences for even small mistakes 178 | 179 | * Really? 180 | - Yes, and that's just for one daemon. 181 | 182 | - Also, "Process monitoring? What's that?" 183 | 184 | * Daemonizing, the new way: 185 | 186 | - Write a single `.service` file for your program. 187 | 188 | 189 | [Service] 190 | ExecStart=/usr/bin/foobard 191 | 192 | [Install] 193 | WantedBy=multi-user.target 194 | 195 | No fork. No pain. 196 | 197 | 198 | 199 | * Daemonizing containers 200 | 201 | $ mv ~/debian-tree /var/lib/container/debian-tree 202 | $ systemctl start systemd-nspawn@debian-tree.service # start now 203 | $ systemctl enable systemd-nspawn@debian-tree.service # autostart on boot 204 | 205 | 206 | 207 | * How do we get logs? 208 | 209 | - Easy. On the host, we normally view logs by executing: 210 | 211 | $ journalctl 212 | 213 | - If we have a container running on the host, we can do: 214 | 215 | $ journalctl -M debian-tree 216 | 217 | 218 | * What about profiling? 219 | 220 | Same thing. 221 | 222 | $ systemd-analyze -M debian-tree # list startup time 223 | $ systemd-analyze blame -M debian-tree # break down the boot time per-unit 224 | 225 | 226 | * But what about networking? 227 | 228 | * Networking just works 229 | 230 | - The defaults are probably what you want 231 | - But you can also configure specific network interfaces, network bridges, `macvlan`, and more 232 | - Docker doesn't let you do this (...or so a lot of people *think*!) 233 | 234 | 235 | 236 | 237 | * How can I control resources for a container? 238 | 239 | $ systemd-cgroup 240 | 241 | *cgroups* (control groups) are a kernel feature for managing resources for a single process or collection of processes, such as: 242 | 243 | - Limiting memory/CPU usage 244 | - Limiting I/O access 245 | - Prioritizing important tasks over others 246 | - etc. 247 | 248 | 249 | * Is this all specific to systemd, or can I use Docker? 250 | 251 | .image porquenolosdos.png 252 | 253 | $ systemd-nspawn --machine bashtest --directory ~/bashtestcontainer /bin/bash 254 | 255 | or even: 256 | 257 | $ machinectl pull-dkr chimeracoder/nginx-nspawn --dkr-index-url https://index.docker.io 258 | 259 | 260 | * Wait. 261 | _what?!_ 262 | 263 | 264 | * Remember what we said at the beginning 265 | - _At_its_core,_your_OS_is_just_a_bunch_of_files_ 266 | - _Along_with_an_ /sbin/init _file_ 267 | - _Different_distributions_distribute_different_files_ 268 | - _That's_basically_it._ 269 | 270 | Containers let you virtualize *parts* of your OS, without requiring you to virtualize the *whole* OS. 271 | 272 | 273 | Containers let you virtualize the filesystem, the process tree, the network stack,`/proc`, `/sys`, and more *selectively*. 274 | 275 | 276 | * So why use Docker at all? 277 | 278 | - For many use cases, it may not matter one way or the other 279 | - Docker is not the only containerization tool around, but it is probably the most popular 280 | - Docker has a healthy ecosystem (the container equivalent of "package support") 281 | - Try it yourself both ways. As you can see, it's easy to switch back and forth 282 | 283 | 284 | * Try it yourself! 285 | 286 | Some cool things you can do with systemd-nspawn: 287 | 288 | - "Execute this command on my root filesystem, but roll back any changes at the end" 289 | - "Run nginx inside its own container on boot, but limit it to 512 MB of RAM and 200% CPU" 290 | - "Give me a container that has its own private network and its own IP and MAC addresses, but map certain ports on the host to the container" 291 | - "Run this container with its own daemons in it, and monitor them to make sure they don't fail" 292 | - "Download this container from the Docker Hub and run it every time I boot, but without installing Docker" 293 | 294 | --------------------------------------------------------------------------------