Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/wy-z/container-vm
A simple way to run QEMU/KVM VM inside a container (supports Windows VM and all others)
https://github.com/wy-z/container-vm
container kvm linux opengl qemu vm vnc windows
Last synced: about 13 hours ago
JSON representation
A simple way to run QEMU/KVM VM inside a container (supports Windows VM and all others)
- Host: GitHub
- URL: https://github.com/wy-z/container-vm
- Owner: wy-z
- License: mit
- Created: 2024-02-05T08:24:43.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2024-03-08T15:03:56.000Z (9 months ago)
- Last Synced: 2024-03-09T11:49:13.980Z (8 months ago)
- Topics: container, kvm, linux, opengl, qemu, vm, vnc, windows
- Language: Python
- Homepage:
- Size: 141 KB
- Stars: 187
- Watchers: 14
- Forks: 24
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# container-vm
[![Pulls]][hub_url]
[![image](https://raw.githubusercontent.com/wy-z/container-vm/main/tests/coverage.svg)](https://github.com/wy-z/container-vm)Run qemu/kvm VM inside a docker container
## Quick Start
### Linux
```sh
mkdir tmp && cp tmp
wget https://dl-cdn.alpinelinux.org/alpine/v3.19/releases/x86_64/alpine-virt-3.19.1-x86_64.iso
docker run --name container-vm --rm -v $PWD:/storage --cap-add=NET_ADMIN \
--device=/dev/kvm -p 8080:8080 weiyang/container-vm run --iso /storage/alpine-virt-3.19.1-x86_64.iso
```### MacOS
```sh
mkdir tmp && cp tmp
wget https://dl-cdn.alpinelinux.org/alpine/v3.19/releases/x86_64/alpine-virt-3.19.1-x86_64.iso
docker run --name container-vm --rm -v $PWD:/storage --cap-add=NET_ADMIN --device-cgroup-rule='c *:* rwm' \
-p 8080:8080 weiyang/container-vm run --macvlan --iso /storage/alpine-virt-3.19.1-x86_64.iso
```Then you can:
- Open `http://localhost:8080` to visit VM graphic
- `docker exec -it container-vm telnet 127.0.0.1 10000` to visit VM console
- `Ctrl-A-C` -> Qemu monitor console
- `Ctrl-]` + `quit` to exit telnet## Features
- Simplicity: Utilizes a clean, straightforward QEMU setup for hassle-free virtualization, focusing on ease of use.
- Flexibility: Offers full compatibility and extensibility with customizable configurations, catering to diverse needs and ensuring easy adaptability for future expansions.
- Native Performance: Delivers exceptional efficiency and optimal performance through the use of advanced technologies such as Tap, MacVlan, and KVM acceleration.## Windows VM
1. Download windows iso (`Win11_23H2_x64v2.iso` or [tiny11](https://archive.org/details/tiny11-2311))
2. Download VirtIO from `https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio` (`virtio-win.iso`)If the hard drive is not detected, remember to install the drivers from the VirtIO ISO
3. Start container
Linux
```sh
docker run --rm -v $PWD:/storage --cap-add=NET_ADMIN --device /dev/kvm \
-p 8080:8080 weiyang/container-vm run -c 4 -m 8192 \
--iso /storage/Win11_23H2_x64v2.iso windows --virtio-iso /storage/virtio-win.iso \
apply-disk -s 64G -n hda ext-args -- -cpu host
```MacOS
```sh
docker run --rm -v $PWD:/storage --cap-add=NET_ADMIN --device-cgroup-rule='c *:* rwm' \
-p 8080:8080 weiyang/container-vm run --macvlan -c 4 -m 8192 \
--iso /storage/Win11_23H2_x64v2.iso windows --virtio-iso /storage/virtio-win.iso \
apply-disk -s 64G -n hda
```On MacOS, rm `--device=/dev/kvm` and `ext-args -- -cpu host`
1. `--cap-add=NET_ADMIN` is necessary for network configuration
2. `--device-cgroup-rule='c *:* rwm'` is necessary for macvlan, or disable by `--no-macvlan`
3. `-c 4 -m 8192` 4 cpu cores, 8G memory
4. `--iso /storage/Win11_23H2_x64v2.iso` add boot cdrom
5. `windows --virtio-iso /storage/virtio-win.iso` add virtio iso
6. `apply-disk -s 64G -n hda` create a 64G disk if not exists
7. `ext-args -- -cpu host` host-passthrough cpu mode, all flags after `ext-args --` will be passed to qemu
8. VirtIO iso is recommended for best performance#### OpenGL Support
Install Mesa3D driver https://github.com/pal1000/mesa-dist-win/releases
#### Better Graphical Performance
1. Run docker with `--device=/dev/dri`
2. Run image with `run *** --vga - ext-args -- -display egl-headless -device virtio-vga-gl`## Container capability limits
1. Minimum capability requirement is `--cap-add=NET_ADMIN`, run with `--no-accel`
2. `--device-cgroup-rule='c *:* rwm'`/`--macvlan` will enable macvlan, otherwise use tap bridge
3. `--device=/dev/kvm`/`--no-accel` will disable IO acceleration, not recommended## Custom Actions
1. Write custom shell script to `/tmp/setup.sh`, e.g.
```sh
set -e
apt update
apt install -y glusterfs-common
```2. Run docker with `-v /tmp:/tmp`
3. Run image with `run *** exec-sh -f /tmp/setup.sh`
## Podman Support
The testing for Podman is not yet complete; you may submit an Issue if needed.
- May need to add more capabilities, such as `--cap-add NET_RAW`
- May need to add more devices, such as `--device=/dev/net/tun`## CLI Commands
### Run
Commands are chainable, e.g. `run xxx windows xxx apply-disk xxx port-forward xxx ext-args -- xxx xxx`
```
❯ python main.py run --helpUsage: main.py run [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...
╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --cpu -c INTEGER CPU cores [default: None] │
│ --mem -m INTEGER RANGE [x>=1] Memory size in MB [default: None] │
│ --arch [alpha|sparc|nios2|sh4|xtensa|avr|sparc64|riscv32|m68k|tricore|microblaze VM arch [default: x86_64] │
│ |cris|mipsel|sh4eb|aarch64|loongarch64|ppc|hppa|mips64el|or1k|i386|mips64 │
│ |rx|microblazeel|riscv64|xtensaeb|mips|x86_64|s390x|arm|ppc64] │
│ --iso TEXT ISO file path or drive url [default: None] │
│ --accel --no-accel Enable acceleration [default: accel] │
│ --macvlan --no-macvlan Enable macvlan network, otherwise use bridge network [default: no-macvlan] │
│ --netdev --no-netdev Setup netdev or not [default: netdev] │
│ --dhcp --no-dhcp Enable DHCP [default: dhcp] │
│ --vnc-web --no-vnc-web Enable VNC web client (noVNC) [default: vnc-web] │
│ --console --no-console Enable Qemu monitor (mon+telnet+qmp) [default: console] │
│ --machine TEXT Machine type [default: None] │
│ --boot STR_OR_NONE Boot options (Set to '-' to disable) [default: once=dc] │
│ --vga STR_OR_NONE Setup VGA (Set to '-' to disable) [default: virtio] │
│ --boot-mode [uefi|secure|windows|legacy] Boot mode [default: legacy] │
│ --iface TEXT (multiple) Special VM network interface (e.g. eth1) │
│ --network TEXT (multiple) Special VM network CIDR (IPv4) (e.g. 192.168.1.0/24) │
│ --dry --no-dry Dry run [default: no-dry] │
│ --help Show this message and exit. │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ apply-disk Apply VM disk │
│ exec-sh Exec shell script files before start Qemu │
│ ext-args External Qemu args │
│ port-forward Forward VM ports │
│ windows Windows specific options │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
```### Apply Disk
`run xxx apply-disk -s 64G -n hda apply-disk -s 32G -n hdb`
```
❯ python main.py run apply-disk --helpUsage: main.py run apply-disk [OPTIONS]
Apply VM disk
╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * --name -n TEXT Disk name (e.g. disk1) [default: None] [required] │
│ --size -s TEXT Disk size (e.g. 32G) [default: 16G] │
│ --file-type TEXT Drive file type (e.g. qcow2,raw) [default: qcow2] │
│ --if-type TEXT Drive interface type (e.g. virtio,ide) [default: None] │
│ --opts TEXT External drive options (e.g. index=i,format=f) [default: None] │
│ --help Show this message and exit. │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
```### Windows
`run xxx windows --virtio-iso /storage/virtio-iso.iso`
```
❯ python main.py run windows --helpUsage: main.py run windows [OPTIONS]
Windows specific options
╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --virtio-iso PATH Window virtio driver iso, download from https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio [default: None] │
│ --tpm --no-tpm Enable TPM [default: tpm] │
│ --help Show this message and exit. │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
```### Port Forwarding
`run xxx port-forward -p 22:22 -p 3389:3389`
Ports 22 and 3389 are set to forward automatically by default```
❯ python main.py run port-forward --helpUsage: main.py run port-forward [OPTIONS]
Forward VM ports
╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --port -p TEXT (multiple) Port forward spec (e.g. 80:8088) [default: None] │
│ --help Show this message and exit. │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
```### External Arguments
`run xxx ext-args -- -cpu host -netdev xxx`
```
❯ python main.py run ext-args --helpUsage: main.py run ext-args [OPTIONS] ARGS...
External Qemu args
╭─ Arguments ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * args ARGS... External Qemu args [default: None] [required] │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
```### Execute shell script
`run xxx exec-sh -f xxx.sh`
```
❯ python main.py run exec-sh --helpUsage: main.py run exec-sh [OPTIONS]
Exec shell script files before start Qemu
╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --file -f PATH (multiple) shell script file [default: None] │
│ --help Show this message and exit. │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
```## Similar Projects
- https://github.com/BBVA/kvm
- https://github.com/qemus/qemu-docker## License
MIT
[hub_url]: https://hub.docker.com/r/weiyang/container-vm/
[Pulls]: https://img.shields.io/docker/pulls/weiyang/container-vm.svg?style=flat&label=pulls&logo=docker