how is this different from docker?
how is this different from docker?
In a unikernel, that overhead is removed by having only a single address space. You can see it as taking the full source of the kernel and the database server, linking it into a single executable, and stripping everything you don’t need, including everything the kernel would need if it supported multiple processes.
Is that a good idea? Not if the service you’re running wants to be multi-process, not if you trust your kernel code more than the code of the service you run on top of it, and not if you want the ability to look inside your containers (e.g. by ssh-ing into it)
What you do get in exchange is smaller containers (does anybody know why the image in this example is so enormous? I expected something that easily fits in 64 kB), a smaller attack surface, and faster boot times.
(See also https://en.m.wikipedia.org/wiki/Unikernel)
A kernel may or may not exist in a separate address space depending on hardware and software features (e.g. the arm split paging regime or the meltdown mitigations). It's just that the kernel memory is not accessible to userspace code.
You can run multiple VMs. That's probably easier to use too, since you tooling for VMs is based around spinning up more machines, not processes.
> not if you trust your kernel code more than the code of the service you run on top of it
I don't really see how that applies. The application code is still the same. It's just that the OS doesn't exist any more. If it doesn't exist, it can't have bugs.
> and not if you want the ability to look inside your containers (e.g. by ssh-ing into it)
True. But I can't easily ssh inside a process either, which is what a unikernel is more comparable to. The only reason I ssh into my VMs is because the application process is wrapped up in an OS. If that OS did not exist, there would be less reason to peek into it.
If you run five containers on a host, you're not running five kernels. You're running five instances of a Linux userspace/application, sharing the same kernel, but isolated from each other.
1) FWK (full weight kernel) a stripped-down version of a full featured kernel only having the things needed to run a particular application. Remember as the upstream kernel progresses you have to some how find a way to update your modified kernel to keep up with security fixes and all.
2) A LWK (light weight kernel) a small kernel built from scratch that is added as a library to an application (it will likely be incompatible with many existing applications built for other systems) - a pro is that system updates are practically non-existent. You don't have to rebuild your image with Debian patches or anything like that since the kernel is minimal and unique. And exploits have minimal impact in any case.
3) Then there is the hybrid approach where you have a LWK that runs along side a FWK with the light weight kernel handling most of the system calls while the full weight kernel (e.g Linux) handles system calls for compatibility. A multi-kernel approach.
I have no idea what route Nanos takes since I can't see the code and its not mentioned anywhere. Keep in mind a Unikernel is usually a single address space kind of thing, so you shouldn't be able to fork or exec. Since Ops permits arbitrary Go/C/C++/Ruby programs I wonder what happens if you try to exec something.
In any case these systems are more secure than containers because an exploit in the code running in the container can affect the host kernel (There is no real isolation). With Unikernels, in some cases, the system will actually unplug cores from the host kernel and boot the Unikernels on those cores utilizing available NUMA features of the CPU. This allows for more isolation and the kernel itself is minimal so it has small attack surface and, in some cases, added performance characteristics.
There are good debugging tools these days for libOS's (Unikernels) and they date back all the way to MIT's exokernel design and even further back. They have caught traction recently because:
1) They are easy to make (You are either stripping down a working kernel or building a very small one - think smaller than minix3).
2) Cloud computing (security) and HPC (performance on commodity) make them relevant again.
3) Not to mention they are fundamentally a better technology than containers, IMHO there is no debate, containers will be replaced by libos(s)/unikernels.
Additionally, I think that unikernels are less secure if anything. If you break into the application you are already in kernel mode and can access any file or privilege resources belonging to the unikernel. Also, there is no hope for defense in depth techniques like sandboxing or resource brokers. With a normal application you would need to do some sort of privilege escalation or sandbox escape after hacking the application.
Also, the key is that there is very little to exploit so the likely hood of it being exploited is reduced.
Yes, I've exploited them myself with script-kiddy tools. Its not hard. Remember those your average libos application may not have any of those things (if not only an simple IP stack).
What resources?
Privileged compared to what?
There is only one application and the kernel lib's only purpose is to serve it.
And sure, a kernel's containment mechanism is subject to exploits. But so are hypervisors. At least if you exploit an application in a (properly made) container, you're just an unprivileged user inside the container. You're not root, in the container or out. If you exploit a unikernel application, you can directly go and target the hypervisor.
That is like saying you have to be a kernel developer to work with containers.
A unikernel is quite different. It allows you to create a bootable application with built-in operating system.
One really doesn't have much in common with the other.
You could have a very minimal OS underneath, but Docker containers don't have their own kernel so they can't talk to hardware.