21 - 12 - 2024

Libvirt + cgroups settings = keep VMs limited

Cgroups are with us for a long time and it's very powerful feature. You can limit everything, everywhere... It's also integrated into systemd and libvirt, and it's a shame not to use it. For me the biggest advantage of this solution is making of common groups within we can keep specific machines.

 

To start with it we need to install the cgroups tools itself. The tools are:

zypper in libcgroup-tools

Create the configuration for /etc/cgconfig.conf

#### 1. NEED TO SPLIT MEMORY FROM CPU* FOR CHILDRENS
#### 2. NEED TO KEEP PARENTS ASSIGNED FOR RESOURCE I.E. CPUSET FOR PARENT HAVE TO HAVE THE CHILDER CPU ID WITHIN RANGE (PARENT 1-3, CHILD 0 is wrong!!)
#### 3. ASSIGN PROCESS TO LIMITS (SEE BELOW) BY CGRED.CONF

### MOUNT THE CGROUPS SCHEMA INTO SYSTEMD DEFAULT DIRECTORY
mount {
       cpuset = /sys/fs/cgroup/cpuset;
        cpu = /sys/fs/cgroup/cpu,cpuacct;
        cpuacct = /sys/fs/cgroup/cpu,cpuacct;
        memory = /sys/fs/cgroup/memory;
        devices = /sys/fs/cgroup/devices;
        freezer = /sys/fs/cgroup/freezer;
        net_cls = /sys/fs/cgroup/net_cls;
        blkio = /sys/fs/cgroup/blkio;
        perf_event = /sys/fs/cgroup/perf_event;
        hugetlb = /sys/fs/cgroup/hugetlb;
}

The Configuration above would be in same cases needed. It was required on Fedora 19 to properly working

######          ALL USERS AND SERVICES          ######
group USERS.slice {
        cpuset {
                cgroup.clone_children="1";
                cpuset.cpus="1-3";
        }

        memory {
        }
}

### ARCHIPEL -- VMs MGMT
group USERS.slice/archipel {
        cpu     {
                cpu.shares="512";
        }

        cpuset  {
                cpuset.cpus="1";
        }

        cpuacct {
        }
}

# NEEDS TO BE IN SEPARATE CATEGORY - WHY ?
group USERS.slice/archipel {
        memory {
                memory.limit_in_bytes="536870912";
        }
}

######          VIRTUAL MACHINES RESTRICTIONS           ######
group ASA.slice {
        cpuset  {
                cpuset.cpus="3";
        }
 
       cpu     {
                cpu.shares="256";
        }
}

group NEXUS.slice {
        cpuset  {
               cpuset.cpus="2";
        }
        cpu     {
                cpu.shares="512";
        }
}

group CSR1000v.slice {
        cpuset  {
                cpuset.cpus="2";
        }

        cpu     {
                cpu.shares="256";
        }
}

group XR.slice {
        cpuset  {
               cpuset.cpus="2";
        }

        cpu     {
                cpu.shares="256";
        }
}

Create systemd cgconfig.service

[Unit]
Description=CGROUPS for LIBVIRT MACHINES
#After=libvirtd.service
Before=libvirtd.service

[Service]
User=root
Type=oneshot
ExecStartPre=-/usr/sbin/cgconfigparser -l/etc/cgconfig.conf
ExecStart=/usr/sbin/cgconfigparser -l/etc/cgconfig.conf
ExecStop=/usr/sbin/cgclear -l /etc/cgconfig.conf
TimeoutSec=0

[Install]
WantedBy=multi-user.target

Activate the service

$ systemctl enable cgconfig.service

Configure libvirt Virtual Machine, and reboot physical host

$ virsh edit 

  <vcpu placement='static'>1</vcpu>
  <resource>
    <partition>/NEXUS</partition>
  </resource>
  <os>
$ systemctl reboot

After this we should have seen .slice containers created under cgroups fs.

$ cat /sys/fs/cgroup/cpuset/CSR1000v.slice/cpuset.cpus
2
$ cat /sys/fs/cgroup/memory/USERS.slice/archipel/memory.limit_in_bytes
536870912
That's it, have fun !
Attachments:
Download this file (cgconfig.conf)cgconfig.conf[ ]1 kB
Download this file (cgconfig.service)cgconfig.service[ ]0.6 kB