-
Notifications
You must be signed in to change notification settings - Fork 67
feat: add Hermit unikernel backend support #540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -342,6 +342,46 @@ An example of a Redis alpine image transformed to a block file on top of | |
| sudo nerdctl run --rm -ti --runtime io.containerd.urunc.v2 harbor.nbfc.io/nubificus/urunc/redis-firecracker-linux-block:latest | ||
| ``` | ||
|
|
||
| ## Hermit | ||
|
|
||
| [Hermit](https://hermit-os.org/) is a unikernel designed for scalable | ||
| and predictable runtime for high-performance and cloud computing. | ||
| Its a Rust re-write of the Hermit-Core unikernel inorder to laverage the | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. inorder -> in order |
||
| memory/thread-safety guarantees provided by the Rust ownership model. | ||
|
|
||
| The Hermit unikernel provides support for multiple compiled languages which | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "which include" -> "like" |
||
| include Rust, C, C++, Go and Fotran. Hermit OS applications are compiled | ||
| into a unikernel image that includes both the application and the operating system. | ||
| When the unikernel boots, the application starts execution immediately. | ||
|
|
||
| Hermit OS provides support for multithreading, networking, and basic system | ||
| interfaces. It is particularly well-suited for cloud and microservice | ||
| environments where lightweight isolation is required. | ||
|
|
||
| ### VMMs and other sandbox monitors | ||
|
|
||
| Hermit OS unikernels run on top of the [QEMU](https://www.qemu.org/) virtual machine monitor. | ||
| It supports standard virtualization interfaces such as virtio devices for networking. | ||
|
|
||
| When executed with [QEMU](https://www.qemu.org/), Hermit can access the network through | ||
| a `virtio-net` device. Storage support depends on the configuration of the unikernel image. Hermit unikernels support both `virtio-fs` and `initrd`. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Storage support depends on the configuration of the unikernel image. Hermit unikernels support both |
||
|
|
||
| ### Hermit and `urunc` | ||
|
|
||
| In the case of Hermit, `urunc` provides support for running unikernels on | ||
| top of QEMU. If the container is configured with network access, `urunc` will | ||
| attach a `virtio-net` device to enable networking for the Hermit OS unikernel. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should also add a sentence for initrd, since |
||
|
|
||
| For more information on packaging | ||
| [Hermit](https://hermit-os.org/) unikernels for `urunc` take | ||
| a look at our [packaging](../package/) page. | ||
|
|
||
| An example of running a Hermit unikernel with `urunc`: | ||
|
|
||
| ```bash | ||
| sudo nerdctl run --rm -ti --runtime io.containerd.urunc.v2 harbor.nbfc.io/nubificus/urunc/hello-world-qemu-hermit-initrd:latest | ||
| ``` | ||
|
|
||
| ## Future unikernels and frameworks: | ||
|
|
||
| In the near future, we plan to add support for the following frameworks: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| // Copyright (c) 2023-2026, Nubificus LTD | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| package unikernels | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "runtime" | ||
| "strings" | ||
|
|
||
| "github.com/urunc-dev/urunc/pkg/unikontainers/types" | ||
| ) | ||
|
|
||
| const HermitUnikernel string = "hermit" | ||
|
|
||
| type Hermit struct { | ||
| Command string | ||
| Monitor string | ||
| Net HermitNet | ||
| } | ||
|
|
||
| type HermitNet struct { | ||
| Address string | ||
| Mask int | ||
| Gateway string | ||
| } | ||
|
|
||
| func (h *Hermit) CommandString() (string, error) { | ||
| kernelArgs := make([]string, 0, 2) | ||
|
|
||
| if h.Net.Address != "" { | ||
| kernelArgs = append(kernelArgs, fmt.Sprintf("ip=%s/%d", h.Net.Address, h.Net.Mask)) | ||
| } | ||
| if h.Net.Gateway != "" { | ||
| kernelArgs = append(kernelArgs, fmt.Sprintf("gateway=%s", h.Net.Gateway)) | ||
| } | ||
|
|
||
| args := strings.Join(kernelArgs, " ") | ||
| appArgs := strings.TrimSpace(h.Command) | ||
|
|
||
| switch { | ||
| case args != "" && appArgs != "": | ||
| return args + " -- " + appArgs, nil | ||
| case args != "": | ||
| return args, nil | ||
| default: | ||
| return appArgs, nil | ||
| } | ||
| } | ||
|
|
||
| func (h *Hermit) SupportsBlock() bool { | ||
| return false | ||
| } | ||
|
|
||
| func (h *Hermit) SupportsFS(fsType string) bool { | ||
| return fsType == "initrd" | ||
| } | ||
|
|
||
| func (h *Hermit) MonitorNetCli(ifName string, mac string) string { | ||
| switch h.Monitor { | ||
| case "qemu": | ||
| netdev := fmt.Sprintf(" -netdev tap,id=net0,ifname=%s,script=no,downscript=no", ifName) | ||
|
|
||
| var deviceArgs string | ||
|
|
||
| // QEMU on x86_64 typically uses virtio-net-pci. | ||
| // On arm64 virtio-net-device is the safer default. | ||
| if runtime.GOARCH == "arm64" { | ||
| deviceArgs = " -device " + "virtio-net-device" + ",netdev=net0" | ||
| } else { | ||
| deviceArgs = " -device " + "virtio-net-pci" + ",netdev=net0,disable-legacy=on" | ||
| } | ||
|
|
||
| if mac != "" { | ||
| deviceArgs += ",mac=" + mac | ||
| } | ||
|
|
||
| return netdev + deviceArgs | ||
| default: | ||
| return "" | ||
| } | ||
| } | ||
|
|
||
| func (h *Hermit) MonitorBlockCli() []types.MonitorBlockArgs { | ||
| return nil | ||
| } | ||
|
|
||
| func (h *Hermit) MonitorCli() types.MonitorCliArgs { | ||
| return types.MonitorCliArgs{ | ||
| OtherArgs: " -no-reboot", | ||
| } | ||
| } | ||
|
|
||
| func (h *Hermit) Init(data types.UnikernelParams) error { | ||
|
|
||
| if data.Net.Mask != "" { | ||
jim-junior marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| mask, err := subnetMaskToCIDR(data.Net.Mask) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| h.Net.Address = data.Net.IP | ||
| h.Net.Gateway = data.Net.Gateway | ||
| h.Net.Mask = mask | ||
| } | ||
|
|
||
| h.Command = strings.Join(data.CmdLine, " ") | ||
| h.Monitor = data.Monitor | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func newHermit() *Hermit { | ||
| return new(Hermit) | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sentence is not very clear, in particular this part: "designed for scalable and predictable runtime for high-performance and cloud computing".