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
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/
/sys/fs/cgroup/
cgroup1/
cgroup3/
cgroup2/
cgroup4/
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
io
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 https://curiouscat.me/essamhassan
Further readings:
http://man7.org/linux/man-pages/man7/cgroups.7.html