From VMs to Unikernels: The Evolution of Application Deployment

While many millennials and Gen-Z engineers haven't witnessed the full journey of computing evolution, it's fascinating to explore how hardware and software abstraction has transformed over the years — especially with the rise of the cloud. One of the most impactful areas of this evolution is in how we deploy and run services: through virtualization, containerization, and more recently, unikernels Virtualization Virtualization is the practice of abstracting physical hardware to run multiple isolated environments (virtual machines) on a single physical host. This is typically achieved through a hypervisor — such as VMware ESXi, KVM, Xen, or Hyper-V — which manages and allocates resources to each VM. Let’s say you have two services: Service A and Service B. To deploy them using virtualization: You create two separate VMs. Each VM runs its own guest OS and kernel. You deploy one service per VM. Great! Your services are isolated and running. But here's the catch... Each VM carries a full OS stack, leading to duplicate resource usage, longer boot times, and heavier system overhead. Containerization Containerization — popularized by Docker — addressed these inefficiencies. Instead of virtualizing the entire hardware stack, containers share the host OS kernel, isolating applications only at the process level using namespaces and cgroups. With containers: Service A and B run as isolated containers. They share the same kernel but maintain isolated user spaces. Containers are lighter, faster to start, and use less memory and disk. Boot times are significantly reduced, and resource utilization improves dramatically. However, containers still rely on the underlying host OS and a container runtime (e.g., Docker Engine or containerd), which introduces some attack surface and runtime dependencies. Unikernels Unikernels take minimalism to the next level. A unikernel is a single-purpose, single-address-space image that includes: Only the required parts of the OS. The application logic. No shells, no package managers, no unused ports. This makes them ultra-secure (smaller attack surface), blazing fast to boot, and extremely lightweight. Inside Unikernels Traditional Operating System Architecture In traditional operating systems (like Linux or Windows), the system is divided into two separate address spaces: User Space: This is where user applications (like your web browser, database, or backend services) run. It includes user-level libraries that the app uses to interact with the system. However, it doesn't have direct access to hardware or low-level resources for safety and security. Kernel Space: This is the core of the OS and has full control over the system's hardware. It includes essential components like the process scheduler, memory manager, networking stack, and device drivers. All user applications must make system calls to request services from the kernel (like file I/O, network access, etc.). So essentially, applications (user space) rely on the kernel(kernel space) to function. This separation enforces security, stability, and resource control — but it also adds layers of abstraction and overhead. Unikernel Architecture In the unikernel model, things are drastically simplified. There is no separation between user space and kernel space — instead, both the application and only the essential parts of the OS are compiled into a single binary that runs directly on hardware or a hypervisor. Here's what makes it unique: Single-purpose: A unikernel is built to run just one application — nothing more. App + OS as one: The application is bundled with exactly the OS functionalities it needs (e.g., TCP/IP stack, filesystem, scheduler). No shell, no package manager, no general-purpose OS features — which also means: Reduced attack surface Fast boot time Smaller memory and disk footprint Because everything exists in a single address space, function calls (even system-level ones) are just regular function calls — no costly system calls or context switches Unikernel Providers Here are a few notable unikernel implementations: MirageOS – Functional, OCaml-based unikernel. IncludeOS – C++ based unikernel. OSv – Designed to run single-application workloads (Java, etc.). NanoVMs – Commercial unikernel platform for production deployment. Reference: http://unikernel.org/ https://www.oreilly.com/library/view/unikernels/9781492042815/ https://www.electronicdesign.com/technologies/embedded/article/21250583/lynx-software-whats-the-difference-between-unikernels-and-operating-systems https://github.com/cetic/unikernels

Apr 13, 2025 - 20:30
 0
From VMs to Unikernels: The Evolution of Application Deployment

While many millennials and Gen-Z engineers haven't witnessed the full journey of computing evolution, it's fascinating to explore how hardware and software abstraction has transformed over the years — especially with the rise of the cloud.

One of the most impactful areas of this evolution is in how we deploy and run services: through virtualization, containerization, and more recently, unikernels

VM-Container-Unikerls

Virtualization

Virtualization is the practice of abstracting physical hardware to run multiple isolated environments (virtual machines) on a single physical host. This is typically achieved through a hypervisor — such as VMware ESXi, KVM, Xen, or Hyper-V — which manages and allocates resources to each VM.

Let’s say you have two services: Service A and Service B.

To deploy them using virtualization:

  • You create two separate VMs.
  • Each VM runs its own guest OS and kernel.
  • You deploy one service per VM.

Great! Your services are isolated and running.

But here's the catch...

Each VM carries a full OS stack, leading to duplicate resource usage, longer boot times, and heavier system overhead.

Containerization

Containerization — popularized by Docker — addressed these inefficiencies. Instead of virtualizing the entire hardware stack, containers share the host OS kernel, isolating applications only at the process level using namespaces and cgroups.

With containers:

  • Service A and B run as isolated containers.
  • They share the same kernel but maintain isolated user spaces.
  • Containers are lighter, faster to start, and use less memory and disk.

Boot times are significantly reduced, and resource utilization improves dramatically.

However, containers still rely on the underlying host OS and a container runtime (e.g., Docker Engine or containerd), which introduces some attack surface and runtime dependencies.

Unikernels

Unikernels take minimalism to the next level.

A unikernel is a single-purpose, single-address-space image that includes:

  • Only the required parts of the OS.
  • The application logic.
  • No shells, no package managers, no unused ports.

This makes them ultra-secure (smaller attack surface), blazing fast to boot, and extremely lightweight.

Inside Unikernels

Traditional Operating System Architecture

Normal application stack

In traditional operating systems (like Linux or Windows), the system is divided into two separate address spaces:

  • User Space:

    • This is where user applications (like your web browser, database, or backend services) run.
    • It includes user-level libraries that the app uses to interact with the system.
    • However, it doesn't have direct access to hardware or low-level resources for safety and security.
  • Kernel Space:

    • This is the core of the OS and has full control over the system's hardware.
    • It includes essential components like the process scheduler, memory manager, networking stack, and device drivers.
    • All user applications must make system calls to request services from the kernel (like file I/O, network access, etc.).

So essentially, applications (user space) rely on the kernel(kernel space) to function. This separation enforces security, stability, and resource control — but it also adds layers of abstraction and overhead.

Unikernel Architecture

Unikernel application stack

In the unikernel model, things are drastically simplified.

There is no separation between user space and kernel space — instead, both the application and only the essential parts of the OS are compiled into a single binary that runs directly on hardware or a hypervisor.

Here's what makes it unique:

  • Single-purpose: A unikernel is built to run just one application — nothing more.
  • App + OS as one: The application is bundled with exactly the OS functionalities it needs (e.g., TCP/IP stack, filesystem, scheduler).
  • No shell, no package manager, no general-purpose OS features — which also means:
    • Reduced attack surface
    • Fast boot time
    • Smaller memory and disk footprint

Because everything exists in a single address space, function calls (even system-level ones) are just regular function calls — no costly system calls or context switches

Unikernel Providers

Here are a few notable unikernel implementations:

MirageOS – Functional, OCaml-based unikernel.
IncludeOS – C++ based unikernel.
OSv – Designed to run single-application workloads (Java, etc.).
NanoVMs – Commercial unikernel platform for production deployment.

Reference:

  1. http://unikernel.org/
  2. https://www.oreilly.com/library/view/unikernels/9781492042815/
  3. https://www.electronicdesign.com/technologies/embedded/article/21250583/lynx-software-whats-the-difference-between-unikernels-and-operating-systems
  4. https://github.com/cetic/unikernels