Simon Bisson
Contributor

Understanding Hyperlight, Microsoft’s minimal VM manager

analysis
14 Nov 20248 mins
Cloud ComputingDevelopment ToolsMicrosoft Azure

Microsoft is making its Rust-based, functions-focused VM tool available on Azure at last, ready to help event-driven applications at scale.

aspiration; vision; hand reaching for the light
Credit: Vlue/Shutterstock

Virtualization seemed to be one of those technologies that was done. With Hyper-V, VMware, and KVM all offering similar features and performance, all that was left to do was to support new chipset instructions and fix bugs. But slowly things began to change, as operating systems and platforms adopted virtual machines and containers as key building blocks.

Windows support for virtualization-based security was one key driver, with new paravisor-based features in Hyper-V’s Krypton binding platform and virtual machines together so that users didn’t know that they were using code running in a VM. Security has driven many other recent virtualization developments, with tools like OpenHCL providing a framework for a virtualization-based trusted execution environment.

Modern virtual machines for serverless computing

There’s another increasingly important place where VMs are important. In the cloud-native and serverless computing world, we need to be able to launch code fast to scale with demand and support scaling down to zero when necessary. This is how we run data centers economically, ensuring we don’t need to keep loads running in case a user needs them.

We need to be able to launch small elements of functionality in microseconds, fast enough that users don’t notice any latency. This requires a new form of virtualization, where the hypervisor provides the APIs that would traditionally have been hosted by a guest OS, providing a lightweight set of services that can be accessed through known interfaces.

Introducing Hyperlight: a small, fast VM manager

In 2023 Azure CTO Mark Russinovich mentioned some work being done within Azure on a virtual machine manager designed for use with WASI, the Web Assembly System Interface. Hyperlight would work by eliminating the requirement to have a guest OS in a virtual machine, instead simply exposing a virtual CPU and I/O to guest applications. The resulting minimalist approach was showing good results and allowed either statically linked binaries to boot and run.

Hyperlight is now a public project with a GitHub repository. It’s still very much experimental, but there’s enough to explore what you can do with your own minimal VMs, especially how you can write code for them. Microsoft suggests that Hyperlight is intended for functions as a service where event-driven applications need to scale quickly, but there are other possibilities: for example, microservices in a Kubernetes environment that’s managed using Kubernetes Event-Driven Autoscaling (KEDA), or portable code for edge IoT hardware.

It’s interesting to look at other recent Azure announcements, as many of them could work well with Hyperlight, especially where both latency and density are key. Running Hyperlight on Cobalt Arm hardware would allow Azure to take advantage of its new lower power compute, and it would also allow Drasi workloads to quickly respond to change notifications across many data sources.

Using Hyperlight for functions as a service

So how does Hyperlight work? To start with, all your code needs to run on the Hyperlight virtual CPU. That requires code to be compiled for it, with a set of specialized libraries to provide platform support that needs to be statically linked when compiled. This is currently available as C, though there are plans to also implement it in Rust. That approach makes using a Web Assembly runtime a good choice, as it allows you to build the runtime once and then use WASI to run arbitrary code written in a higher-level language and compiled to Web Assembly’s wasm instruction set. That should allow you to use any language that has a wasm compiler, including .NET languages such as C#.

Hyperlight provides the basic infrastructure for running a thinly provisioned VM. This sets up the necessary memory via the host OS hypervisor APIs, enabling the virtual CPU and its registers, before running a pre-configured app at a set instruction pointer. It’s an approach that’s optimized for running one process per VM, with the app and VM bundled together.

While that may seem like other virtual machine managers, it’s very much optimized for fast cold starts, going from nothing to a fully instantiated application in the minimum possible time. By launching functions quickly, Hyperlight allows Azure to scale its functions-as-a-service tool more effectively by shutting them down completely when not running, ensuring that when a function is active, it’s computing, not simply using power while waiting to be called.

Launching a Hyperlight-hosted VM takes a couple of milliseconds, as opposed to 120 or so for a traditional VM. It’s slower than launching a web assembly runtime on its own, but using a VM provides the added level of security and isolation that’s necessary for multitenant applications.

Developing for and with Hyperlight

Hyperlight is invoked programmatically. Microsoft’s sample code is written in Rust and it takes a handful of lines of code to create a Hyperlight sandbox and load code into it. One useful option is creating a snapshot of the VM once it’s been created, which can be used to launch future instances more quickly.

Once a VM is up and running, you can use the Hyperlight Rust libraries to call a VM-hosted function directly. Your host code needs to run in a loop until the VM function halts successfully or it fails with a known or unknown error. If the function succeeds, the host passes the result on to the calling function. If it fails, it logs the appropriate error message.

Using Rust here makes sense. It’s memory-safe, so it reduces the risk of memory leaks and buffer escapes, helping keep both host and guest code secure. This is essential in a cloud-native environment where function instances are created and destroyed and there is no link between any one instance and the next.

How can you build a guest binary for use in Hyperlight? You need to use the Hyperlight library, with both C and Rust versions available. It’s also important to remember that this is the only one you can use, so don’t start with the standard library, even if that’s what you’ve always worked with in the past. There are other important prerequisites, including a specific entry point for your code, to trap unregistered function calls from the host.

One key point is that there is no access to the host system from the guest application unless it’s explicitly enabled by the host. Even if you have enabled that option, guest applications are strictly limited in what can be delivered, locking down both argument length and type. If what’s sent is not what’s expected, the call will be rejected by the Hyperlight host.

Security is important when building a Hyperlight host. Microsoft has put out a list of requirements that help define the host’s role as a tool for managing guest code. These include ensuring that your host doesn’t do things like create or work with files, access network resources, or even work with encryption tools. When you consider that a host may be loading more than one different function for different owners, these rules begin to make sense. There is no need to expose state or services that can be accessed by malicious actors. And if you are running a public service, you can be sure that they will be trying to do just that.

Designing for cloud economics

It’s still early days for Hyperlight, but there’s a lot to like in what we’ve been shown so far. The idea of a lightweight host for functions is a good one, especially one with the ability to truly scale to zero. As it rolls out in Azure and other cloud platforms, it should have an interesting effect on the economics of cloud-native serverless development, both for users and the cloud providers.

Scaling to zero with minimal startup latency will ensure there are no costs associated with idle functions, and at the same time, will improve overall utilization in data centers. That should be a win for everyone. Now all we need is a Hyperlight Functions runtime, one that hides the plumbing underneath Web Assembly and lets us build code in our language of choice. And that’s what handing the project over to the Cloud Native Computing Foundation should do, encouraging developers to think about how to build using Hyperlight with Kubernetes and Web Assembly.

Simon Bisson
Contributor

Author of InfoWorld's Enterprise Microsoft blog, Simon Bisson prefers to think of “career” as a verb rather than a noun, having worked in academic and telecoms research, as well as having been the CTO of a startup, running the technical side of UK Online (the first national ISP with content as well as connections), before moving into consultancy and technology strategy. He’s built plenty of large-scale web applications, designed architectures for multi-terabyte online image stores, implemented B2B information hubs, and come up with next generation mobile network architectures and knowledge management solutions. In between doing all that, he’s been a freelance journalist since the early days of the web and writes about everything from enterprise architecture down to gadgets.

More from this author

Exit mobile version