Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a unikernel?

I am new to unikernels and the following links didn't help me much to understand them:

  • https://searchitoperations.techtarget.com/definition/unikernel
  • https://en.wikipedia.org/wiki/Unikernel
  1. When is it better to use a unikernel?
  2. How is a unikernel smaller than a microkernel in terms of code size?
like image 883
sniper Avatar asked Jan 04 '23 07:01

sniper


2 Answers

The terms "unikernel" and "microkernel" mean different things and are not two really two opposites or two choices you need to choose from:

"microkernel" is an older term, and is a type of kernel design, contrasting with a monolithic kernel. In a monolithic kernel, as its name says, the entire kernel is a single program, which implements the kernel APIs which the user's applications needs (e.g., Unix system calls, threads, processes, file system, etc.). Contrasting with that, in a microkernel design, we have a "microkernel", a very small kernel which implements a small API (e.g., a very basic concept of threads of execution, permissions, and message passing), and on top of it sits a much larger piece of the kernel which implements the full APIs that the applications need - the actual filesystem, processes that behave like Unix processes, system calls, and so on. In the early 1990s there was an academic understanding that writing monolithic kernels has become too hard and too bug-prone, and microkernels are the way of the future, but then came Linux (which is a monolithic kernel) and made this conclusion into a joke. Today, you shouldn't choose a kernel depending a whether it uses a microkernel or a monolithic kernel. This is an implementation detail that users will rarely care about.

"unikernel" is a newer concept. Traditional kernels took pride in being able to multiplex many different users and applications on the same physical machines. The famous 1974 paper about Unix was called "The UNIX time-sharing system", because time-sharing (i.e., multiplexing multiple users and applications) was one of the most important goals of the OS. But today, with a focus on virtual machines instead of physical machines, there is a different way (namely, a hypervisor) in which a physical machine can be split to different virtual machines. So very often, each virtual machine only runs a single application belonging to a single owner. This presents an opportunity to run a trimmed-down kernel which doesn't need to support a lot of the things which traditional kernels supported: No need to support isolation between different users; No need to support thousands of drivers (there is a tiny set that all known hypervisors need); No need to support isolation between different processes.

Trimming all that unnecessary stuff makes the kernel smaller which is a great benefit for the quick deployment of new VMs, lowers memory use, and can also improve performance. For example, you may have heard that recently, the Linux kernel was patched to fix the "Meltdown" vulnerability in contemporary CPUs. The fix slows down system calls and context switches on Linux, and was needed because without it one process could read the memory of other processes. But if we know that there is NO other process - there is just one application running on the VM - we don't care. So a unikernel does not need to slow itself down with meltdown workarounds. System calls can be as quick as function calls, context switches are much faster, etc.

Some unikernels like OSv for example, did the above, and provided a kernel which mimics to the application a traditional kernel (i.e., Linux) but without the unsupported features such as multiple users or multiple isolated processes (though un-isolated threads are supported). Other unikernels went even further in the quest to trim down the kernel, and provide a different kernel build to each application, which includes exactly the specific features that this specific application needs. For example, to run a TCP application you can use a kernel which only supports the TCP protocol, but not UDP. You can look at this as if the kernel and the application are linked together to form one unified kernel-application, which is run directly on the hypervisor.

When, and why, to use a unikernel (of any of the variants described above) is an open question. Certainly, if using tiny amounts of disk or memory is a concern, a unikernel is a good option to consider. If you're worried about security and plan to audit your code, a unikernel has much less code to audit. In applications that need to start very quickly (e.g., implementing a "function as a service"), unikernels allow very quick boot, significantly less than 1 second, because the boot does far fewer "generic" stuff and focuses on what your application really needs. These examples can also tell you when you shouldn't bother to consider a unikernel: If your application anyway uses huge amounts of disk and memory (e.g., a database application), reducing a bit from the size of the kernel won't help much. If your application runs for hours, quick boot is not important. If your application uses a lot of OS features, many of the more specialized unikernels I described above may not provide all the features which your application needs.

like image 99
Nadav Har'El Avatar answered Jan 05 '23 19:01

Nadav Har'El


In one line, (application + unikernel) called a workload running on hypervisor(cloud) is equivalent to a standalone application running on bare metal in embedded world.

Unikernel in cloud is better when app(workload) dont use most of the OS & device driver services.

Unikernel is compiled with only the used features of kernel NOT with necessary features as in microkernel, hence size is small.

like image 25
sniper Avatar answered Jan 05 '23 21:01

sniper