Skip to content

Instantly share code, notes, and snippets.

@kosyfrances
Last active February 2, 2023 16:32
Show Gist options
  • Save kosyfrances/f8ffd9b76ff6285d60d1b1671c2aa8f6 to your computer and use it in GitHub Desktop.
Save kosyfrances/f8ffd9b76ff6285d60d1b1671c2aa8f6 to your computer and use it in GitHub Desktop.
Spin up a Libvirt VM (that supports nested virtualisation using KVM as Hypervisor) in a docker container.

Dockerfile

FROM ubuntu:18.04
RUN apt-get update -y && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils vagrant && \
    apt-get autoclean && \
    apt-get autoremove && \
    vagrant plugin install vagrant-libvirt
COPY startup.sh /
ENTRYPOINT ["/startup.sh" ]

qemu-kvm is the backend

Libvirt is a toolkit used for managing virtualisation platforms

bridge-utils provides a bridge from your network to the virtual machines

source: https://help.ubuntu.com/community/KVM/Installation

startup.sh

#!/bin/bash
set -eou pipefail

chown root:kvm /dev/kvm
service libvirtd start
service virtlogd start

exec "$@"

Remember to chmod +x startup.sh.

Bring up the container.

docker build -t vmindocker:latest -f Dockerfile .
docker run --privileged -it vmindocker bash

In the container, check for virtualisation support

root@51c19e93d3e5:/# egrep -c '(vmx|svm)' /proc/cpuinfo

If 0 it means that your CPU doesn't support hardware virtualization.

If 1 or more it does - but you still need to make sure that virtualization is enabled in the BIOS.

Alternatively, check that the container can host hardware accelerated KVM virtual machines.

root@51c19e93d3e5:/# kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used

Spin up a VM in the container.

vagrant init generic/alpine37
vagrant up
vagrant ssh

Unprivileged container

I tried to run this process in an unprivileged container and ended up running it this way

docker run -it --device=/dev/kvm --device=/dev/net/tun -v /sys/fs/cgroup:/sys/fs/cgroup:rw --cap-add=NET_ADMIN --cap-add=SYS_ADMIN --security-opt apparmor=unconfined vmindocker bash

The following led me to add the long string of commands above, plus you'd need some of the troubleshooting steps below.

--security-opt apparmor=unconfined --> Because apparmor refused to let me do anything and I did not want to disable it completely on my computer.
This is just an Ubuntu issue https://github.com/docker/labs/tree/master/security/apparmor#no-profile

Error while activating network: Call to virNetworkCreate failed: error creating bridge interface virbr1: Operation not permitted. --> CAP_NET_ADMIN

permission denied --> CAP_SYS_ADMIN

Error while activating network: Call to virNetworkCreate failed: Unable to open /dev/net/tun, is tun module loaded?: No such file or directory. --> create /dev/net/tun

Error while activating network: Call to virNetworkCreate failed: Unable to set bridge virbr1 forward_delay: Read-only file system. --> mount -o remount,rw /sys

Call to virNetworkCreate failed: cannot write to /proc/sys/net/ipv6/conf/virbr1/disable_ipv6 to enable/disable IPv6 on bridge virbr1: Read-only file system --> mount -o remount,rw /proc/sys

Call to virDomainCreateWithFlags failed: Failed to create controller cpu for group: Read-only file system -->  -v /sys/fs/cgroup:/sys/fs/cgroup:rw 
@UmedJadhav
Copy link

Can this be used for m1 mac. ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment