Where are unikernels widely used?
Where are unikernels widely used?
To me, unikernels feel quite a bit like statically linked server binaries running under an unprivileged UID - but you're choosing not to trust Linux' (or any other kernel's) user separation facilities, but your hypervisor's domU separation facilities instead. In exchange, you lose virtually all of your existing OS's amazing debugging and performance analysis/tuning tools. It's not a tradeoff I'd readily consider.
If you want a shell, that is what stuff like JMX, or server side REPLs are for.
"Lisp at NASA: using a REPL to debug Deep Space 1 while it was 100 million miles away"
The point (for me at least) is discarding features that you don't need in return for performance and simplicity gains. Those gains are not insubstantial when you're scaling your system and you don't want to spend your money on admin staff.
That is a simplified view, and there are other advantages as well: you probably don't need to exit to your hypervisor quite as often as you do with syscalls, so you benefit from reduced overhead. One disadvantage is that memory allocation is almost static (unless you do ballooning which is tricky to get right), so you "waste" some memory compared to a bare-metal deployment where unused memory can be used for the page cache instead.
Tooling/Perf/etc is not needed when running (do you really want to debug in production) but tooling can be used in the process of development.
Why consider unikernels? 1) they’re stupid fast. You have only the things you need (booting in nanoseconds? yepp) 2) small attack surface (because you only have your app that’s the only attack surface. you don’t have cruft that build up in you os/kernel over years) 3) light resource usage (you could run thousands of these on the same physical machine) 4) true isolation via the hypervisor
definitely worth keeping an eye on the developments in this space
Whether or not you want to debug in production, reality often means that you will see things in a live environment that you will not see in other environments.
Unikernels are very interesting and have a number of compelling attributes, but let's not pretend that the current state of available tooling for troubleshooting, instrumentation, and general debugging isn't a challenge.
so I actually believe there is an opportunity here to focus on the important pieces (network messages, control flow tracing, memory footprints, etc) after ejecting a huge amount of irrelevant stuff
Definitely excited to see how the technology evolves over the next few years. It hasn't moved as fast as I'd have expected over the last 2-3 years but I'd love to see that accelerate.
Do I want to debug in production? No.
Do I have to do it anyways? All the fucking time. I'm not perfect, I sometimes ship bugs, and when they show up in production, I need to diagnose, determine if rolling back will solve them, or whether I need to fix forward and how. Not being able to debug in production is simply unacceptable.
I want to ship perfect code. But I don't. So, instead, I debug. If the issue shows up in production, I debug in production.
If I can't attach a profiler to find, for example, the code that contains a regex that's doing too much backtracking with production data, then I'm dead in the water. If I can't get a sample out of a system that's received a query of death, then I'm dead in the water. If I can't attach dtrace (or the equivalent) and get stats on how much I/O a system is doing in response to various events, I'm dead in the water.
Being able to dive into the depths of a system is the #1 criteria for confidently being able to put it into production.
I don’t follow. Are you saying that development should build normal user space binaries, and you should only build the unikernel for production?
You will inevitably run into a behavior difference between the unikernel and user space outputs. Even if you’re not debugging in production (shudder) you need to be able to debug the unikernel.
The original unikernel paper used a streaming media device as an example and the numbers they provided were really good.
Or the Docker TCP/IP stack on macOS, using parts of MirageOS.
Basically, you've taken the whole /sbin/init link out of the OS init chain, and replaced it with... A single binary you may remember.
To do this took a little extra work. Your glibc and any other dependency ended up in kernel space.
Single-use virtual machines obviously have the biggest boost, but other uses exist. Your kerberos-daemon isolated into its own vm on the network. Someone's gotta serve network filesystems. Apache servers for various websites you may host - the possibilities are endless.
The processor itself has a Massive timesink for isolating kernel-space from user-space (even root is just another user at this level, I'm afraid). Even Server-side admins have simply gotten used to it - every application, server, program Ever runs on that user-space.
So you have a bunch of single use VMs... and that much "context-switching" between virtual-drivers and memory allocation on one side, and the actual server the vm is for on the other. Now these VMs are running on an OS's hypervisor with the same context-switching performance problem!
So, we package each vm as a unikernel - shove each virtualized server into the kernel. We avoid that context switching.
Build that kernel lean enough, and sometimes the unikernel VM can perform almost at baremetal speeds.
What if we did the same for the Host OS - built a hypervisor Unikernel to delegate hardware and nothing else? zomg folks are squeeing with excitement about a new way to frame building a lean system...
But it gets us compiling in-house again instead of using COTS (commercial, off-the-shelf software). Got an old Gentoo-user hanging around that can debug kernel code, harden the kernel against attack, and compile it all lean?
That guy is who we're gonna need to figure out what goes wrong with any of this. Because Murphy's law is unreliably unreliable, yet ultimately absolute.