239 lines
5 KiB
Markdown
239 lines
5 KiB
Markdown
|
|
|
|||
|
|
# 🚀 MNMIVM
|
|||
|
|
|
|||
|
|
### *Fire-and-Forget Virtual Machines*
|
|||
|
|
|
|||
|
|

|
|||
|
|
|
|||
|
|
**MNMIVM** is a minimal, single-binary VM launcher built on **QEMU + KVM + cloud-init**.
|
|||
|
|
It is designed for *fast iteration*, *ephemeral usage*, and *zero ceremony*.
|
|||
|
|
|
|||
|
|
If Docker feels too constrained, and OpenStack / Proxmox feel like overkill — MNMIVM sits comfortably in the middle.
|
|||
|
|
|
|||
|
|
> Spin it up.
|
|||
|
|
> Get a random port.
|
|||
|
|
> SSH in.
|
|||
|
|
> Done.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ✨ What MNMIVM Is
|
|||
|
|
|
|||
|
|
* A **fire-and-forget VM launcher**
|
|||
|
|
* A **CLI-first** virtualization tool
|
|||
|
|
* A **thin orchestration layer**, not a platform
|
|||
|
|
* A way to spin up *real Linux VMs* without running a control plane
|
|||
|
|
|
|||
|
|
MNMIVM intentionally avoids:
|
|||
|
|
|
|||
|
|
* Long-lived port bindings
|
|||
|
|
* Static network assumptions
|
|||
|
|
* Cluster state
|
|||
|
|
* Databases
|
|||
|
|
* APIs
|
|||
|
|
* Daemons
|
|||
|
|
|
|||
|
|
It launches a VM, hands you SSH + VNC, and gets out of the way.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🧠 Design Philosophy
|
|||
|
|
|
|||
|
|
MNMIVM is built around a few hard rules:
|
|||
|
|
|
|||
|
|
* **No background services**
|
|||
|
|
* **No required config files**
|
|||
|
|
* **No global state beyond `/var/lib/microvm`**
|
|||
|
|
* **Every VM is self-contained**
|
|||
|
|
* **Cloud-init is the source of truth**
|
|||
|
|
* **Root-only, explicit control**
|
|||
|
|
|
|||
|
|
This makes MNMIVM ideal for:
|
|||
|
|
|
|||
|
|
* Homelabs
|
|||
|
|
* CI runners
|
|||
|
|
* Testing OS images
|
|||
|
|
* Disposable dev environments
|
|||
|
|
* Learning QEMU/KVM internals
|
|||
|
|
* “I just need a VM *right now*”
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🆚 How It Compares (At a Glance)
|
|||
|
|
|
|||
|
|
| Feature | MNMIVM | Docker | LXC/LXD | Proxmox | OpenStack |
|
|||
|
|
| ---------------------- | ----------- | ------- | ------- | ------- | --------- |
|
|||
|
|
| Real VMs | ✅ | ❌ | ⚠️ | ✅ | ✅ |
|
|||
|
|
| Cloud-init | ✅ | ❌ | ⚠️ | ✅ | ✅ |
|
|||
|
|
| Requires Daemons | ❌ | ✅ | ✅ | ✅ | ✅ |
|
|||
|
|
| Random Ports | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|||
|
|
| Cluster-aware | ❌ | ❌ | ⚠️ | ✅ | ✅ |
|
|||
|
|
| Stateful Control Plane | ❌ | ❌ | ⚠️ | ✅ | ✅ |
|
|||
|
|
| Setup Time | **Seconds** | Minutes | Minutes | Hours | Days |
|
|||
|
|
|
|||
|
|
> MNMIVM behaves more like **`docker run` for VMs**, not like a cloud.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🧱 Architecture Overview
|
|||
|
|
|
|||
|
|
* **QEMU + KVM** for virtualization
|
|||
|
|
* **User-mode networking** (no bridges required)
|
|||
|
|
* **Cloud-init seed ISO** (`cidata`) for provisioning
|
|||
|
|
* **QCOW2 backing images**
|
|||
|
|
* **Ephemeral SSH + VNC ports**
|
|||
|
|
* **State stored on disk only**
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
/var/lib/microvm/
|
|||
|
|
├── images/ # Base cloud images
|
|||
|
|
└── vms/
|
|||
|
|
└── vm1/
|
|||
|
|
├── disk.qcow2
|
|||
|
|
├── seed.iso
|
|||
|
|
├── pubkey.pub
|
|||
|
|
├── os.name
|
|||
|
|
├── ssh.port
|
|||
|
|
├── vnc.port
|
|||
|
|
└── vm.pid
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
No database.
|
|||
|
|
No API.
|
|||
|
|
No daemon.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📦 Supported Operating Systems
|
|||
|
|
|
|||
|
|
| OS | Version | Boot Mode |
|
|||
|
|
| ------ | ----------- | --------- |
|
|||
|
|
| Ubuntu | 24.04 LTS | BIOS |
|
|||
|
|
| Debian | 13 (Trixie) | BIOS |
|
|||
|
|
| Fedora | 43 Cloud | BIOS |
|
|||
|
|
| Alpine | 3.22 | BIOS |
|
|||
|
|
|
|||
|
|
> UEFI images are intentionally avoided for simplicity and reliability.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔑 SSH & Identity Management
|
|||
|
|
|
|||
|
|
* SSH keys are injected via **cloud-init**
|
|||
|
|
* Keys are **fully replaced**, not appended
|
|||
|
|
* Old keys are **revoked**
|
|||
|
|
* `update-cloud` regenerates the seed ISO
|
|||
|
|
* Changes apply on **next boot**
|
|||
|
|
|
|||
|
|
This gives you **real identity revocation**, not just key sprawl.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📀 Disk Behavior
|
|||
|
|
|
|||
|
|
* Base disk size is **12GB** (configurable constant)
|
|||
|
|
* Uses **QCOW2 backing images**
|
|||
|
|
* Root filesystem auto-expands on first boot
|
|||
|
|
* Predictable, uniform VM sizing
|
|||
|
|
|
|||
|
|
This keeps resource usage balanced and intentional.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🧰 CLI Usage
|
|||
|
|
|
|||
|
|
### Create a VM
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
sudo mnmivm create vm1 --os debian --pubkey-path ~/.ssh/id_ed25519.pub
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Start a VM
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
sudo mnmivm start vm1
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Stop a VM
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
sudo mnmivm stop vm1
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Update SSH key (cloud-init)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
sudo mnmivm update-cloud vm1 --pubkey-path newkey.pub
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### List VMs
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
sudo mnmivm list
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Delete a VM
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
sudo mnmivm delete vm1
|
|||
|
|
# Requires typing YES in all caps
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📊 VM List Output
|
|||
|
|
|
|||
|
|
MNMIVM renders a clean Unicode table showing:
|
|||
|
|
|
|||
|
|
* Name
|
|||
|
|
* Running state
|
|||
|
|
* OS
|
|||
|
|
* SSH endpoint
|
|||
|
|
* VNC endpoint
|
|||
|
|
* SSH public key path
|
|||
|
|
|
|||
|
|
This makes it usable *without* scripting.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ⚠️ What MNMIVM Is Not
|
|||
|
|
|
|||
|
|
* ❌ A cloud platform
|
|||
|
|
* ❌ A hypervisor manager
|
|||
|
|
* ❌ A replacement for Proxmox
|
|||
|
|
* ❌ A Kubernetes node orchestrator
|
|||
|
|
* ❌ A long-lived VM manager
|
|||
|
|
|
|||
|
|
If you want **policy, HA, scheduling, quotas, tenants** — use Proxmox or OpenStack.
|
|||
|
|
|
|||
|
|
If you want **a VM right now**, MNMIVM wins.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🧪 Project Status
|
|||
|
|
|
|||
|
|
* ✅ Actively working
|
|||
|
|
* ✅ Under ~600 lines of Go
|
|||
|
|
* ✅ No external Go dependencies
|
|||
|
|
* ⚠️ API not stabilized yet
|
|||
|
|
* ⚠️ CLI flags may evolve
|
|||
|
|
|
|||
|
|
This project is intentionally **hackable** and **readable**.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🐧 Why MNMIVM Exists
|
|||
|
|
|
|||
|
|
Sometimes you don’t want:
|
|||
|
|
|
|||
|
|
* A cluster
|
|||
|
|
* A UI
|
|||
|
|
* A dashboard
|
|||
|
|
* A service mesh
|
|||
|
|
|
|||
|
|
You just want to:
|
|||
|
|
|
|||
|
|
> “Launch a VM and throw it into orbit.”
|
|||
|
|
|
|||
|
|
That’s MNMIVM.
|
|||
|
|
|