Have you ever created a Virtual Machine in your system and thought how to reduce the overhead due to this VM? What if I tell you can create a system container which uses the functionality provided by the kernel running on the host system, but the only catch here is that the Opertaing System that your container will have is of the host system. But most of the time that’s all we need right? Now, coming to the main question, who is going to manage all the containers we will create or even the Virtual Machines? There comes our hero, Incus :).

Virtual Machines vs System Container

Incus is a container and VM manager. It provides system containers, which are lightweight environments that run complete operating systems, compared to the more application-specific containers provided by Docker. System Containers in Incus are highly efficient compared to traditional virtual machines. They share the host’s kernel but maintain isolated user-space environments. This makes them suitable for running full Linux distributions with much less overhead compared to full VMs. WE can also create different VMs using incus but in this case Incus uses the hardware of the host system, but the kernel is provided by the virtual machine. Therefore, virtual machines can be used to run, for example, a different operating system.

VM vs System container

Application container vs System Container

You must be wondering what’s a application container then? And if you have used docker, you should have created a docker container as well. The docker container is actually an application container. Application containers package a single process or application. System containers, on the other hand, simulate a full operating system similar to what you would be running on a host or in a virtual machine. You can run Docker in an Incus system container, but you would not run Incus in a Docker application container. You can create different user spaces and isolate all processes belonging to a user using system containers but apllication containers can’t be used for that. This flexibility makes Incus a great tool for use cases where you need to run systemd, networking services, or multiple applications within the same container, providing a more traditional server-like environment.

Application Container vs System container

The difference between a VM, System Container and an Application Container can be summarised as:

VM vs Application Container vs System container

Getting started with Incus

Please make sure you have a linux based OS preferably ubuntu. You can follow this url - https://github.com/zabbly/incus to install incus in your system. Oncus incus is installed, you can launch system containers using the CLI or UI Incus provides.

Incus requires some initial setup for networking and storage. This can be done interactively through:

incus admin init

To launch a new instance, we can choose from a list of all the images that are available on official image server (https://images.linuxcontainers.org/). For managing instances, we use the Incus command line client incus.

  1. Launch a container called myincuscontainer using the Ubuntu 22.04 image:

    incus launch images:ubuntu/22.04 myincuscontainer

  2. Launch a VM called my-incus-vm using the Ubuntu 22.04 image:

    incus launch images:ubuntu/22.04 my-incus-vm --vm

  3. Check the list of instances that you launched:

    incus list

  4. Stop a comtaiter using:

    incus stop myincuscontainer

  5. Delete a container using:

    incus delete myincuscontainer

  6. Interact with an instance using:

    incus exec myincuscontainer -- bash

You can also manage, create instances using Incus UI. To use the UI, you need to install incus-ui-canonical package using

sudo apt-get install incus-ui-canonical

You need to set listener using

incus config set core.https_address :8443

After that, you can access the UI through https://localhost:8443, accept the self-signed certificate and follow the login instructions. Once you login, you should see a screen like below. Happy hacking :)

Incus UI

Running docker container inside an incus container

To run docker inside a system container launched by Incus, we have to set config for nested virtualization.

incus config set myincuscontainer security.nesting=true
incus config set myincuscontainer security.privileged=true
  • security.nesting=true: Allows the use of nested containerization inside the Incus container.
  • security.privileged=true: Provides elevated privileges, enabling Docker to perform tasks that are typically restricted in unprivileged containers.

Docker requires access to certain kernel modules and devices to operate effectively.

incus config device add myincuscontainer fuse unix-char path=/dev/fuse
incus config set myincuscontainer linux.kernel_modules overlay,br_netfilter

Now, we exec into the container and install docker

incus exec myincuscontainer -- /bin/bash

apt-get update
apt-get install -y apt-transport-https ca-certificates curl software-properties-common

# Add Docker's official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -

# Add Docker repository to APT sources
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

# Update package list again and install Docker
apt-get update
apt-get install -y docker-ce

After installing Docker, verify the installation by running:

docker --version

You can test Docker by running a basic container:

docker run hello-world

Conclusion

In this blog, we have seen that Incus can be a powerful tool to manage multiple VMs, containers all at one place. You can also read more about incus from the official documentation https://linuxcontainers.org/incus/docs/main/. All the above details have been taken from the official docs only.

Please drop me a mail if you feel anything in this post can be improved or changed.

Happy learning :)