Prepare your VM with Virtualization Tools - caprivm/virtualization GitHub Wiki

Introduction

Even though it is not good practice, this guide is intended to explain you how use some virtualization tools for enable test environments in linux. Basically, the idea is to build architectures like the example shown in the figure. Its main intention is to create virtualized environments that allow testing applications or custom developments.

Example of environment

This is an adaptation of an script using in the deployment of AMCOP Tool.

Reference: https://www.aarnanetworks.com/amcop

Hardware Requirements

This guide was build based on real experimentation on the following hardware:

  • CentOS 7
  • 8 vCPU
  • 32 GB RAM
  • 500 GB HDD Storage
  • Enable the nested virtualization

As can be seen, the hardware requirements are from a relatively big virtual o physic machine. However, the reason is that using the machine as a host for virtualization requires multiple vCPU and RAM. Particularly, the storage is used for the .iso images that will be downloaded. A quick way to validate that the nested virtualization is enabled is execute lscpu command and look for virtualization flags.

Install the Virtualization Tools

First, you need to install the virtualization tools in your VM. Remember that the goal is to create VMs inside VMs, thus you add a new virtualization level what can cause problems at the moment of tests. You must be sure that you are at an appropriate virtualization level or layer before proceeding because, although things seem to be fine as internet connection or connectivity test, adding more virtualization layers brings instability issues in downloads or connections to remote repositories.

# Install virtualization tools
sudo apt-get update -y
sudo apt-get install git python3 -y
sudo apt-get update -y
sudo apt-get install qemu-kvm qemu-utils genisoimage libvirt-bin bridge-utils virtinst libguestfs-tools virt-top -y
sudo usermod -aG libvirt $USER
sudo usermod -aG kvm $USER
sudo apt-get install cpu-checker -y

Now, going to setup libvirt default network and storage pool.

# libvirt configurations
sudo virsh pool-define-as --name default --type dir --target /var/lib/libvirt/images/
sudo virsh pool-autostart default
sudo virsh pool-start default
sudo virsh pool-list --all
sudo virsh net-autostart default
sudo virsh net-list --all

Install python3 pip and next install ansible.

# pip3 and ansible installation
sudo apt-get install jq sed curl python3-pip -y
sudo pip3 install ansible
sudo pip3 install ruamel.yaml
sudo pip3 install netaddr

Example: Create a VM with Ubuntu 18.04

First, download the image. It is important to mention that if you have already downloaded an image you do not have to do again. In this case only execute the export commands.

# Define variables
export CONFIG_FOLDER_PATH=/tmp/config
export URL="https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img"
export IMAGE="bionic-server-cloudimg-amd64.img"
sudo mkdir -p $CONFIG_FOLDER_PATH
# Create directory for base images
sudo mkdir -p /var/lib/libvirt/images/base
wget $URL
sudo mv $IMAGE /var/lib/libvirt/images/base/

Now, create a directory for the instance images and create the disk based on the desired image. In this example, the disk size is 50 GB. Use the variables configured in the previous step.

# Define variables
export VM_NAME="amcop-vm-01"
export DISK_SIZE=50
# Create a disk image based on the Ubuntu image
sudo mkdir /var/lib/libvirt/images/$VM_NAME
sudo qemu-img create -f qcow2 -o backing_file=/var/lib/libvirt/images/base/$IMAGE /var/lib/libvirt/images/$VM_NAME/"$VM_NAME".qcow2
# Setting size to $DISK_SIZE GB
sudo qemu-img resize /var/lib/libvirt/images/$VM_NAME/$VM_NAME.qcow2 "$DISK_SIZE"G

Next create user-data and metadata files under a temporary directory.

# Define variables
export VM_CONFIG_DIR=$CONFIG_FOLDER_PATH/$VM_NAME
export META_DATA_FILE_PATH=meta-data
export USER_DATA_FILE_PATH=user-data
export SSH_PUB_KEY=$HOME/.ssh/id_rsa.pub
export PUB_KEY=$(cat $SSH_PUB_KEY)
export USER_NAME=ubuntu
export DIST="ubuntu"
mkdir -p $VM_CONFIG_DIR
touch $VM_CONFIG_DIR/$USER_DATA_FILE_PATH
touch $VM_CONFIG_DIR/$META_DATA_FILE_PATH
# Create metadata
cat >$VM_CONFIG_DIR/$META_DATA_FILE_PATH <<EOF
local-hostname: $VM_NAME
EOF
# Create user-data
cat >$VM_CONFIG_DIR/$USER_DATA_FILE_PATH <<EOF
#cloud-config
users:
- name: $USER_NAME
  ssh-authorized-keys:
    - $PUB_KEY
  sudo: ['ALL=(ALL) NOPASSWD:ALL']
  groups: sudo
  shell: /bin/bash
runcmd:
- echo "AllowUsers $DIST" >> /etc/ssh/sshd_config
- restart ssh
EOF

Create a disk to attach with Cloud-Init configuration.

sudo genisoimage -output /var/lib/libvirt/images/$VM_NAME/$VM_NAME-cidata.iso -volid cidata -joliet -rock $VM_CONFIG_DIR/$USER_DATA_FILE_PATH $VM_CONFIG_DIR/$META_DATA_FILE_PATH

Starts the virtual machine with two disks attached: root disk and disk with Cloud-Init configuration.

# Define variables
export vCPU=4 # vCPU assigned to the VM.
export MEM=16 # RAM in GiB.
export OS_VARIANT="ubuntu18.04"
# Starts the virtual machine
virt-install --connect qemu:///system --name $VM_NAME --ram $(($MEM << 10)) --vcpus=$vCPU --os-type linux --os-variant $OS_VARIANT --disk path=/var/lib/libvirt/images/$VM_NAME/"$VM_NAME".qcow2,format=qcow2 --disk /var/lib/libvirt/images/$VM_NAME/$VM_NAME-cidata.iso,device=cdrom --import --network network=default --noautoconsole

After the machine starts, you can access it using SSH.

# Get the machine name
sudo virsh list --all 
sudo virsh domifaddr <machine_name>
ssh <user>@<machine_ip>

In this guide, the machine_name must be amcop-vm-01 and the user is ubuntu.

⚠️ **GitHub.com Fallback** ⚠️