Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Say a non-OS hacker wants a unikernel. What's the sanest way to go about getting to that?

Options that come to mind are:

- build your application as a linux kernel module, load it into a normal kernel, and generally ignore the userspace that runs anyway

- take Linux and hack it down pretty aggressively plus splice your code into it

- find some github unikernel effort and go from there (which I think the OP does)

- take some other OS - freebsd? - and similarly hack out parts

Other?

I like the idea of a x64 machine running a VM connected to a network card as a generic compute resource that does whatever tasks are assigned by sending it data over the network. It's not been worth the hassle relative to a userspace daemon, but one day I may find the time and would be interested in the HN perspective on where best to start the OS level hackery.



RedHat has been looking at Linux-as-unikernel since 2018, https://research.redhat.com/blog/article/unikernel-linux-ukl...

> The Unikernel Linux (UKL) project started as an effort to exploit Linux’s configurability.. Our experience has led us to a more general goal: creating a kernel that can be configured to span the spectrum between a general-purpose operating system, amenable to a large class of applications, and a highly optimized, possibly application- and hardware-specialized, unikernel... other technologies occupying a similar space have come along, especially io_uring and eBPF. io_uring is interesting because it amortizes syscall overhead. eBPF is interesting because it’s another way to run code in kernel space (albeit for a very limited definition of “code”).

Code, https://github.com/unikernelLinux/ukl

> Unikernel Linux (UKL) is a small patch to Linux and glibc which allows you to build many programs, unmodified, as unikernels. That means they are linked with the Linux kernel into a final vmlinuz and run in kernel space. You can boot these kernels on baremetal or inside a virtual machine. Almost all features and drivers in Linux are available for use by the unikernel.


For starters, assuming the Linux variant, build a statically compiled application, pack it into an initramfs as the only file there, for simplicity name it `/init`, bundle the initramfs with the kernel, boot. At this point, your app should be the PID 1 and the only process running (with the exception of a bunch of kernel threads). At this point you can do whatever you want.


This is the most realistic comment on this thread (so far).


Realistic, yes, but it's not a unikernel.

There are projects that permit statically linking a traditional kernel with a traditional application into a unikernel. NetBSD pioneered this with their rump kernel build framework, and I believe there's at least one Linux build framework that mimics this. The build frameworks cut out the syscall layer; an application calling read(2) is basically calling the kernel's read syscall implementation directly. Often you don't need to change any application source code. The build frameworks handle configuring and building the kernel image, and statically linking the kernel image with your application binary to produce the unikernel image.


I probably should have mentioned I've built unikernels with some of the tooling you've described here. It just seems very academic and edge case compared to a single static user space Linux binary that while technically isn't a by the book unikernel, all I guess I meant was that it's diminishing returns beyond that.


You should also probably check out Unikraft (https://unikraft.org) , supports many languages/apps, x86/ARM64 and QEMU/Firecracker. Is also able to run an ELF built under Linux as a unikernel (see https://unikraft.org/guides/bincompat). Discord is at https://unikraft.org/discord .


There is a framework for OCaml for this: https://mirage.io/ So if you are interested in learning OCaml and want a unikernel, this would be a possible path to take.


OCaml is a good language but perhaps unikernel does not mean what I thought it did:

> fully-standalone, specialised unikernel that runs under a Xen or KVM hypervisor.

Or maybe xen / kvm are no longer called operating systems?

I'm interested in having my code be responsible for thread scheduling and page tables - no OS layer to syscall into - but am not as keen on DIYing the device drivers to get it talking to the rest of the world.


MirageOS unikernels run directly on Xen, e.g. http://roscidus.com/blog/blog/2016/01/01/a-unikernel-firewal...

> I replace the [QubesOS] Linux firewall VM with a MirageOS unikernel. The resulting VM uses safe (bounds-checked, type-checked) OCaml code to process network traffic, uses less than a tenth of the memory of the default FirewallVM, boots several times faster, and should be much simpler to audit or extend.

NanoVMs has OSS tools for golang unikernels on multiple hypervisors and cloud platforms, https://nanovms.com/dev/tutorials/running-go-unikernels


Nanos runs not just go but pretty much any language you want to throw at it:

https://github.com/nanovms/ops-examples .


> I'm interested in having my code be responsible for thread scheduling and page tables

But MirageOS does exactly that, last I looked. As does RustyHermit.


> Or maybe xen / kvm are no longer called operating systems?

> I'm interested in having my code be responsible for thread scheduling and page tables - no OS layer to syscall into [...]

You might be confusing Xen and KVM here? Xen and KVM are rather different in this regard.

KVM runs on a full Linux kernel (as far as I know). But running your application as unikernels on top of Xen is more comparable to the old Exokernel concept.


There are essentially three ways to put together a unikernel:

1. Minimizing an existing general-purpose OS

2. By-passing the OS

3. Starting from scratch

You can read more in detail about this here from Unikraft's documentation[0].

[0]: https://unikraft.org/docs/concepts/design-principles#approac...


I'd go with:

- take Linux and hack it down pretty aggressively plus splice your code into it

But rather than starting with a Linux distro and hacking it down, I'd start the other way: Boot the kernel directly (via a UEFI bootloader). You can embed a basic filesystem structure (/dev, /proc, /etc, etc.) in a binary blob inside the kernel file itself on build (kind of dumb that this is required at all, but it is)). The kernel itself has basically everything you'd need (for any reason you'd want a unikernel).


Hack Linux all the way down until you're just left with Linux


Is there a cloud service similar to cloudflare workers designed to work with unikernels?


Anything that can run VMs on Xen should work.


This would be interesting.


The problem with Unikernels is that there is no middle ground between a button smashing user and a kernel hacker. If you open the hood everything is part of the kernel and most (all?) existing examples of Unikernels lack proper tracing and debugging support. It will feel like debugging an eight bit MCU (printf() and GPIO writes) running a far larger (and complex) code base through upward emulation.



Actually this isn't a fundamental issue with unikernels, but rather an implementation one. For instance, check out debugging in Unikraft: https://unikraft.org/docs/internals/debugging .


A matter of tooling, nothing related to unikernels.


A couple unikernel projects that caught my eye in the past may be of interest to you. I have no experience with them, so I can't speak to their quality though.

https://unikraft.org/

https://github.com/nanovms/nanos


A very basic kernel isn't that hard to make. I think currently the easiest way would be to follow this series of blogpost by Philip Oppermann: https://os.phil-opp.com/

He made a few crates which handles the boot process, paging, x86 structures and more.


I'm completely biased since I cut these packages but for this particular example of "run a wasm payload inside of a unikernel":

    ops pkg load eyberg/wasmedge:0.9.1 -c config.json
You could replicate this is seconds and then push that image to AWS or GCP also in seconds.


NetBSD. Someone already did this hacking over 10 years ago. https://en.wikipedia.org/wiki/Rump_kernel


The Xen sources used to include a minimal unikernel written in C.


It still exists: https://wiki.xenproject.org/wiki/Mini-OS . But beware that this is no more than a small reference OS, there's a massive gap between getting it to just boot and running real-world applications with it.


If you don't mind working in OCaml, I get in the impression that MirageOS is probably your best bet.

That's a lot more mature than RustyHermit, last I looked.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: