<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://training-course-material.com/index.php?action=history&amp;feed=atom&amp;title=Not_Only_Docker</id>
	<title>Not Only Docker - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://training-course-material.com/index.php?action=history&amp;feed=atom&amp;title=Not_Only_Docker"/>
	<link rel="alternate" type="text/html" href="https://training-course-material.com/index.php?title=Not_Only_Docker&amp;action=history"/>
	<updated>2026-04-21T09:04:09Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://training-course-material.com/index.php?title=Not_Only_Docker&amp;diff=53832&amp;oldid=prev</id>
		<title>Apatrakov: /* Now you understand bocker! ⌘ */</title>
		<link rel="alternate" type="text/html" href="https://training-course-material.com/index.php?title=Not_Only_Docker&amp;diff=53832&amp;oldid=prev"/>
		<updated>2017-04-15T16:21:20Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Now you understand bocker! ⌘&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;[[Category:private]]&lt;br /&gt;
&amp;lt;slideshow style=&amp;quot;nobleprog&amp;quot; headingmark=&amp;quot;⌘&amp;quot; incmark=&amp;quot;…&amp;quot; scaled=&amp;quot;true&amp;quot; font=&amp;quot;Trebuchet MS&amp;quot; &amp;gt;&lt;br /&gt;
;title: Linux Containers: Not Only Docker&lt;br /&gt;
;author: Alexander Patrakov&lt;br /&gt;
&amp;lt;/slideshow&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Virtualization ⌘==&lt;br /&gt;
&lt;br /&gt;
* Run another OS (including another copy of the kernel) in a virtual machine&lt;br /&gt;
** OK to run Windows VM on Linux&lt;br /&gt;
* Good level of security &amp;amp; isolation&lt;br /&gt;
** Separate virtual disks, network stack&lt;br /&gt;
** Hacked VM != hacked host&lt;br /&gt;
** Can run any OS&lt;br /&gt;
* A lot of performance overhead related to emulation of virtual hardware&lt;br /&gt;
** Somewhat solved by paravirtualization&lt;br /&gt;
** Virtual machines eat memory for caches - partially solved by ballooning&lt;br /&gt;
&lt;br /&gt;
== Containerization ⌘==&lt;br /&gt;
&lt;br /&gt;
* Running another tree of processes under the same kernel&lt;br /&gt;
** They don&amp;#039;t see other processes&lt;br /&gt;
** They have their own view of the filesystem&lt;br /&gt;
** They have their own copy of the network stack&lt;br /&gt;
** They look and feel like a virtual machine in some sense&lt;br /&gt;
* No overhead&lt;br /&gt;
** Native performance of e.g. disks&lt;br /&gt;
** Only as much memory occupied as when running directly on the host&lt;br /&gt;
* Somewhat less secure than a virtual machine&lt;br /&gt;
** But still good enough for many use cases&lt;br /&gt;
* Good only for runnng Linux software&lt;br /&gt;
&lt;br /&gt;
== Why people use containers and VMs ⌘==&lt;br /&gt;
&lt;br /&gt;
* Reproducible deployment of services&lt;br /&gt;
** Just copy a VM or container image onto a host, and start it&lt;br /&gt;
** No need to configure the application inside&lt;br /&gt;
** No need to worry about compatibility with the host&lt;br /&gt;
* Multi-tenant setups&lt;br /&gt;
** Isolation and security matter here&lt;br /&gt;
&lt;br /&gt;
== Popular container runtimes ⌘==&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;big&amp;gt;&amp;#039;&amp;#039;&amp;#039;Docker&amp;#039;&amp;#039;&amp;#039;&amp;lt;/big&amp;gt;&lt;br /&gt;
** Many people don&amp;#039;t know that alternatives even exist!&lt;br /&gt;
* Everything else server-side&lt;br /&gt;
** LXC/LXD&lt;br /&gt;
** systemd-nspawn&lt;br /&gt;
** runc&lt;br /&gt;
** Rocket&lt;br /&gt;
* On the desktop&lt;br /&gt;
** Flatpak&lt;br /&gt;
** Snap&lt;br /&gt;
&lt;br /&gt;
== Container building blocks ⌘==&lt;br /&gt;
&lt;br /&gt;
* Namespaces&lt;br /&gt;
** man 7 namespaces&lt;br /&gt;
** UTS, PID, User, Mount, Network, IPC, Cgroup&lt;br /&gt;
* Cgroups&lt;br /&gt;
* Management software&lt;br /&gt;
&lt;br /&gt;
== Chroot ⌘==&lt;br /&gt;
&lt;br /&gt;
* A mechanism that allows to change the view of the filesystem&lt;br /&gt;
** Some existing directory is treated as root directory for a process&lt;br /&gt;
** Chroots are entered using a chroot() system call&lt;br /&gt;
*** Not bulletproof - root can escape&lt;br /&gt;
*** No other security - processes in a chroot can send signals and use network as usual&lt;br /&gt;
&lt;br /&gt;
== Let&amp;#039;s create a chroot ⌘==&lt;br /&gt;
&lt;br /&gt;
* Chroot with Debian or Ubuntu:&lt;br /&gt;
** Use [https://wiki.debian.org/Debootstrap debootstrap], it is packaged for many distributions&lt;br /&gt;
** debootstrap jessie /tmp/jessie&lt;br /&gt;
* Chroot with Fedora/CentOS/OpenSUSE:&lt;br /&gt;
** Use [https://collab-maint.alioth.debian.org/rinse/ rinse], it is packaged for Debian and Ubuntu&lt;br /&gt;
*** On other distributions install from source&lt;br /&gt;
*** If you are on CentOS/Fedora and want to create a chroot of the same kind, you can use supermin instead&lt;br /&gt;
** rinse --arch amd64 --directory /tmp/centos --distribution centos-7&lt;br /&gt;
&lt;br /&gt;
== Entering a chroot ⌘==&lt;br /&gt;
&lt;br /&gt;
 mount -t proc proc /tmp/jessie/proc&lt;br /&gt;
 mount -t sysfs sysfs /tmp/jessie/sys&lt;br /&gt;
 chroot /tmp/jessie&lt;br /&gt;
 . /etc/profile   # to set the correct $PATH&lt;br /&gt;
 ls               # runs in a chroot&lt;br /&gt;
 exit&lt;br /&gt;
&lt;br /&gt;
== Some thoughts about chroots ⌘==&lt;br /&gt;
&lt;br /&gt;
* Chroot is a privileged operation&lt;br /&gt;
** Can you think why?&lt;br /&gt;
* Chroot can be escaped from by root&lt;br /&gt;
** Let&amp;#039;s say &amp;quot;escaped&amp;quot; means &amp;quot;/etc/hacked&amp;quot; created outside of the chroot&lt;br /&gt;
** Can you think of a few ways?&lt;br /&gt;
*** [https://filippo.io/escaping-a-chroot-jail-slash-1/ The &amp;quot;textbook&amp;quot; answer] is relying on chroot(&amp;#039;..&amp;#039;) but there are other ways to do it&lt;br /&gt;
&lt;br /&gt;
== Trying Out Namespaces ⌘==&lt;br /&gt;
&lt;br /&gt;
* C programmers use these system calls:&lt;br /&gt;
** To create a new namespace for the current process: unshare&lt;br /&gt;
** To create a new process in a new namespace: clone&lt;br /&gt;
** To enter an existing namespace: setns&lt;br /&gt;
* Shell utilities:&lt;br /&gt;
** unshare: creates new namespaces, runs a shell (or anything else) there&lt;br /&gt;
** nsenter: enters existing namespaces&lt;br /&gt;
&lt;br /&gt;
== Some examples ⌘==&lt;br /&gt;
&lt;br /&gt;
* Bad example: PID namespace created but /proc still refers to the old one&lt;br /&gt;
&lt;br /&gt;
 # unshare --fork -p /bin/bash&lt;br /&gt;
 # echo $$&lt;br /&gt;
 1&lt;br /&gt;
 # pstree&lt;br /&gt;
 ... lots of processes ...&lt;br /&gt;
 # exit&lt;br /&gt;
&lt;br /&gt;
* Proper way to create PID namespace&lt;br /&gt;
** Combine it with a mount namespace&lt;br /&gt;
** Mount a private copy of /proc&lt;br /&gt;
&lt;br /&gt;
 # unshare --fork -p -m --mount-proc /bin/bash&lt;br /&gt;
 # pstree&lt;br /&gt;
 bash───pstree&lt;br /&gt;
 # exit&lt;br /&gt;
&lt;br /&gt;
== Exercise ⌘==&lt;br /&gt;
&lt;br /&gt;
* Create PID and mount namespaces for a new bash process&lt;br /&gt;
* Verify by mounting a tmpfs on /mnt that the mount namespace works&lt;br /&gt;
* Enter this namespace with nsenter&lt;br /&gt;
&lt;br /&gt;
== Network namespaces ⌘==&lt;br /&gt;
&lt;br /&gt;
* Separate set of interfaces, routing tables, iptables/ip6tables rules&lt;br /&gt;
* How to create:&lt;br /&gt;
 # ip netns add &amp;lt;namespace_name&amp;gt;&lt;br /&gt;
* How to move an interface (cannot be undone):&lt;br /&gt;
 # ip link set &amp;lt;interface&amp;gt; netns &amp;lt;namespace_name&amp;gt;&lt;br /&gt;
* How to run commands:&lt;br /&gt;
 # ip netns exec &amp;lt;namespace_name&amp;gt; &amp;lt;command&amp;gt; &amp;lt;arguments...&amp;gt;&lt;br /&gt;
* Clean up:&lt;br /&gt;
 # ip netns del &amp;lt;namespace_name&amp;gt;&lt;br /&gt;
* [http://blog.scottlowe.org/2013/09/04/introducing-linux-network-namespaces/ Helpful blog post]&lt;br /&gt;
&lt;br /&gt;
== Exercise ⌘==&lt;br /&gt;
&lt;br /&gt;
* Connect to a free OpenVPN server: https://www.vpnkeys.com/get-free-vpn-instantly/&lt;br /&gt;
** Known issue: MTU must be limited&lt;br /&gt;
** Don&amp;#039;t allow openvpn to pull routes, as this may interfere with VNC&lt;br /&gt;
** Set the DNS server to 8.8.8.8 on the host&lt;br /&gt;
* Move the tun0 interface to a separate network namespace&lt;br /&gt;
* Set up tun0 as the default route in that namespace&lt;br /&gt;
* Run the other browser there, as your user&lt;br /&gt;
** Verify that you are accessing the internet via the VPN from the namespace&lt;br /&gt;
* Can you create a nested connection to the same VPN server?&lt;br /&gt;
* Try to predict what happens if you stop the VPN&lt;br /&gt;
&lt;br /&gt;
== Cgroups ⌘==&lt;br /&gt;
&lt;br /&gt;
* Hierarchical organization of processes in a system&lt;br /&gt;
** Used e.g. by systemd to track when a service terminates&lt;br /&gt;
* Resource limiting via controllers&lt;br /&gt;
** CPU, ram, block i/o, bandwidth, ...&lt;br /&gt;
* Controlled via a special filesystem, cgroupfs&lt;br /&gt;
* Documented e.g. in:&lt;br /&gt;
** [https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/index.html RedHat Linux Resource Management Guide]&lt;br /&gt;
** man 7 cgroups&lt;br /&gt;
&lt;br /&gt;
== Cgroup security model ⌘==&lt;br /&gt;
&lt;br /&gt;
* To move a task to a different cgroup, write access to the target cgroup is required&lt;br /&gt;
** This means: root can escape, i.e. evade resource limits&lt;br /&gt;
&lt;br /&gt;
== Controlling the cgroup hierarchy ⌘==&lt;br /&gt;
&lt;br /&gt;
* Direct way: you can modify files under /sys/fs/cgroup&lt;br /&gt;
* Convenient shell wrappers: cgcreate, cgexec&lt;br /&gt;
** Parts of cgroup-tools in Ubuntu, libcgroup-tools in CentOS&lt;br /&gt;
** Use lscgroup to see the available cgroups&lt;br /&gt;
&lt;br /&gt;
== Now you understand bocker! ⌘==&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/p8952/bocker Bocker] is a toy container engine&lt;br /&gt;
** ~100 lines of bash code&lt;br /&gt;
* Read the code, play with it&lt;br /&gt;
** &amp;#039;&amp;#039;&amp;#039;bocker pull&amp;#039;&amp;#039;&amp;#039; doesn&amp;#039;t work due to Docker registry API change, use &amp;#039;&amp;#039;&amp;#039;bocker init&amp;#039;&amp;#039;&amp;#039; instead&lt;br /&gt;
** Debootstrap a directory, configure openssh-server there, create an image and a container from it&lt;br /&gt;
** See if you can ssh there&lt;br /&gt;
** Can you escape?&lt;/div&gt;</summary>
		<author><name>Apatrakov</name></author>
	</entry>
</feed>