wtf series - wtf is cgroups?

This is the first of a series of posts explaining cryptic tech terms in an introductory way.

Disclaimer: this series is not intended to be a main learning source. However, there might be follow up posts with hands-on experiments or deeper technical content for some of these topics.


Cgroups, or control groups, are Linux kernel features that provide mechanisms allowing processes to be organized into hierarchical groups whose usage of various types of resources ( ram, cpu, disk i/o, network i/o ) can then be limited and monitored. There are two major versions of cgroups with some differences in groups' hierarchies and the fact that multiple cgroups per process is not supported in cgroupsv2 unlike cgroupsv1. We will be discussing only cgroupsv2 here with little references to v1.

Cgroups configuration structure usually looks like this
* assuming it's mounted at /sys/fs/cgroup/


This means rules/limits assigned to cgroups1 affects both cgroups1 processes and the processes of children cgroups of cgroups1, cgroups3 in this example.

It should be noted that not all cgroup controllers are available in the v2 yet as it was only marked available in kernel version 4.5.  Currently, memory, io, rdma, pids, perf_event and cpu controllers are available.

Example use cases

- Limiting network access for a process so that it can't connect to network. net_io
- Prioritizing disk I/O from high priority processes like database servers and/or static servers. blkio in cgroupsv1 io in cgroupsv2
- Apply inbound/outbound network firewalls to a certain cgroup. net_cls in cgroupsv1 and xt_cgroup iptable filter in cgroupsv2
- Prioritizing outgoing network traffic for web crawlers and content aggregator processes. net_prio and xt_cgroup iptable filter in cgroupsv2
- Monitor CPU usage of all sideloaded tools. cpu_acct

Quick hands-on: Setting network I/O priority higher for MySQLdb server

Setting up cgroups

Install libcgroup2 package on your distro. It can take different names in different distributions.

Mount cgroup2 to /cgroups

$ mount -t cgroup2 nodev /cgroups

Creating cgroups

$ mkdir /cgroup2/highiopriority

This creates a cgroup called highiopriority. Now we want to add io to cgroup.subtree_control to be able to use its controller.

$ echo "+io" > /cgroups/cgroup.subtree_control

Now if we printed cgroup.controller file for the highiopriority cgroup, we should find io enabled.

$ cat /cgroups/highiopriority/cgroup.controllers

Now we can change io.weight [10,1000] to give our new cgroup higher io priority than default value 100 by adding the new weight to /cgroups/highiopriority/io.weight

echo "1000" > io.weight

Assigning processes to cgroups

Now that we have a cgroup with high io priority, the only missing thing is adding processes to this cgroup. To do so, we should add pids of the processes we want to prioritize their io, mysqldb server in our case, to cgroup.procs file in the cgroup directory.

cat /var/lib/mysql/{yourservername}.pid > /cgroups/highiopriority/cgroup.procs

Now we have mysql io prioritized over default cgroup. There are so many interesting things you can do with cgroups on your own workstation. My recommendation is: try to extend this tutorial with limiting your default browser RAM usage and instead of figuring out the pid this old fashioned way, search of a way on how you can auto capture an executable pid and assign it to a certain cgroup on the fly.

What's next

The next couple of topics I have in the queue are all Linux, Golang and some networks. I'm also planning to work on a mini-docker project implementing some of linux concepts that I will be explained in the coming topics to build a mini-docker engine and experiment with different kernel features. Please feel free to post suggestions and feedback here

Further readings:

Essam Hassan

Essam Hassan

A pragmatic software engineer, cyber security enthusiast and a Linux geek. I curse at my machine on a daily basis. My views are my own.
Zurich, Switzerland