Containers in 2007: bk99.de with OpenVZ
Summary
In May 2007 bk99.de ran with OpenVZ, the free edition of Virtuozzo, and on 5 May I created an FAQ for the container users covering the typical questions, from the clock to Apache’s appetite for memory. That was six years before Docker and eleven years before Podman. This post from my old blog shows how containers worked in everyday use back then and compares OpenVZ with LXC, to which Proxmox VE switched in 2015.
OpenVZ and Virtuozzo
Containers were nothing new on Linux in 2007, just little known. Unix has had chroot since 1979, which gives a process its own root directory. FreeBSD introduced jails in 2000; on Linux came Linux-VServer and the commercial Virtuozzo from SWsoft, which launched in 2000 as the first commercial container technology at operating system level.
SWsoft released the core of Virtuozzo as OpenVZ in 2005. As early as April 2006, OpenVZ could move running containers to another server without stopping them. In 2006 there was also a first attempt to get OpenVZ into the official Linux kernel, which Golem reported on at the time.
bk99.de as containers
During the server move in October 2006 I had already locked the Teamspeak and Counter-Strike servers into their own chroot environments. Shortly afterwards my server itself ran as an OpenVZ host: services and users worked in containers, then usually called VPS, each with its own root access, its own processes and its own IP address, but all sharing my server’s kernel.
This is documented by my OpenVZ FAQ, which I created on 5 May 2007 for the users of the server. It collected the questions that came up in everyday use:
- How do I restart a VPS?
- Why is the time on my VPS wrong?
- Do I need an NTP server?
- Is there an initial iptables script for the VPS?
- Why does the Apache2 web server use so much RAM?
- How do I get up-to-date antivirus software?
- How do I get lighttpd into a chroot?
- How can I run precompiled 32-bit programs?
Only one of the answers has survived in the Web Archive. The questions still show where OpenVZ differed from a machine of your own in everyday use.
One kernel for all
All containers on an OpenVZ server share one kernel. Several of the questions follow from that. The clock belongs to the kernel, and a container cannot set it itself; running your own NTP service in the container is therefore pointless, and the host has to keep the time right. Only the host loads kernel modules too, and for iptables the container only had the modules the host had enabled. A firewall in the container was therefore always a compromise between what you wanted and what was allowed.
The memory trap with Apache
The only surviving answer in the FAQ is about an error that appeared in my web server’s log in May 2007 (archived version):
/var/log/apache2/error.log
[alert] (12)Cannot allocate memory: apr_thread_create: unable to create worker thread
[alert] (12)Cannot allocate memory: apr_thread_create: unable to create worker threadThe explanation back then: the Apache worker reserves 8 MB of stack for each thread, so with the default 25 threads that is 200 MB of virtual memory. I advised lowering StartServers and the spare values, or simply using the frugal web server thttpd.
Why this became a problem under OpenVZ of all places lies in the user beancounters, which OpenVZ used to limit each container’s resources. One of the limits, privvmpages, counted reserved virtual memory, not memory actually in use. A program that reserves a lot of memory but uses little therefore failed at the limit even though the server had plenty of free RAM. A smaller stack helps more precisely than fewer threads, for example with Apache’s ThreadStackSize directive or ulimit -s before starting. Later OpenVZ kernels simplified the limits to RAM and swap with VSwap.
What has changed since: OpenVZ and LXC
Docker only appeared in March 2013 and initially used LXC; Podman followed in 2018 and reached version 1.0 in January 2019. A lot had happened under the hood by then. OpenVZ needed a specially patched kernel, usually based on the Red Hat Enterprise Linux kernel and therefore lagging behind current Linux. Meanwhile the building blocks for containers moved into the official kernel: Google started on “process containers” in 2006, which appeared as cgroups in early 2008 with Linux 2.6.24, and namespaces isolate processes, networking and file systems. LXC put these building blocks together into containers in August 2008. The OpenVZ and Virtuozzo developers themselves contributed heavily to the namespaces and to CRIU, the tool that can freeze and restore running processes.
| OpenVZ | LXC | |
|---|---|---|
| Kernel | own patched kernel (mostly RHEL-based) | unmodified Linux kernel |
| Isolation | own kernel extensions | kernel namespaces |
| Resources | user beancounters, later VSwap | cgroups |
| Live migration | built in, since 2006 | via CRIU |
| Management | vzctl, templates | lxc tools, pct in Proxmox |
| In Proxmox VE | up to version 3.4 | from version 4.0 (October 2015) |
That is exactly why Proxmox VE switched. Proxmox was started in 2005 because OpenVZ had neither a backup tool nor a management interface; the first version from April 2008 combined OpenVZ containers with KVM machines. With version 4.0 in October 2015, LXC replaced OpenVZ, and Proxmox could finally use current kernels. Existing OpenVZ containers could be converted to LXC during the upgrade.
System containers and application containers
OpenVZ and LXC follow the same idea: a container is a complete Linux system with init, services, users and package management, just without its own kernel. These are called system containers. Docker and Podman, by contrast, rely on application containers: one image per application, immutable, built in layers and quickly replaced rather than maintained.
Both have their place. For a small server that should feel like a machine of its own, a system container is still the simpler choice; today I run Proxmox VE, which manages virtual machines and LXC containers side by side. Incidentally, the questions from my 2007 FAQ still apply there almost unchanged: an LXC container does not set its own clock either, loads no kernel modules and lives within limits set by the host.
Numbers at a glance
- SWsoft’s Virtuozzo launched in 2000; in 2005 its core was released as OpenVZ.
- My OpenVZ FAQ for bk99.de dates from 5 May 2007, six years before the first Docker release in March 2013.
- cgroups appeared in early 2008 with Linux 2.6.24, LXC in August 2008, Proxmox VE in April 2008.
- Proxmox VE used OpenVZ up to version 3.4 and switched to LXC with version 4.0 in October 2015.
- Podman appeared in 2018, version 1.0 in January 2019.
References
- bk99.de 2007: OpenVZ FAQ (Web Archive, German)
- bk99.de 2007: Why does the Apache2 web server use so much RAM? (Web Archive, German)
- Wikipedia: Proxmox VE (German)
- heise online, 8 Oct 2015: Proxmox VE 4.0 released (German)
- Wikipedia: OpenVZ
- Wikipedia: LXC
- Wikipedia: Virtuozzo
- CRIU: Checkpoint/Restore in Userspace
- Apache: ThreadStackSize
- Curated post: OpenVZ to be brought into the Linux kernel (g, 2006)
- Curated post: Linux-VServer 2 for kernel 2.6 (hß, 2005)
Remarks
- This post is based on my OpenVZ FAQ of 5 May 2007 from the old Plone blog; in 2026 I retrieved it from the Web Archive, wrote it out and added the later development. Only the list of questions survives there, and the answers are lost except for the one about Apache. The explanations about the clock, kernel modules and memory limits in this post are my present-day assessment, not the text of the time.
- SWsoft renamed itself Parallels at the end of 2007; Virtuozzo has been an independent company again since December 2015.
OpenVZ FAQ from 2007 in the Web Archive
Links to the original source and the Web Archive open in a new tab.