The closed source CPanel has some great resource management tools, but open source control panels like Vesta Control Panel haven’t yet caught up to that. So, what I want to show you is how you can apply CPU and RAM limits to your web hosting service using CGroups. First things first,
What are CGroups?
CGroups, or Control Groups, are a linux kernel feature that allow you to manage resource allocation really efficiently. They’ve been around for quite a while now. I’m not going to go into an in depth analysis of systemd, slices, processes, etc. Rather, I’d like to point you to this video which goes into all that good stuff if you’re interested. For now, let’s jump to the way you’d limit a user’s CPU.
Demonstration: Limiting CPU
To limit a user’s CPU, you need to install the `libcgroup` package. On RHEL/CentOS, do:
sudo yum install libcgroup
On Arch Linux, assuming you have an AUR helper, install the `libcgroup` package from the AUR. On ubuntu/debian,
sudo apt-get install libcgroup
Now, the `libcgroup` package isn’t supposed to install CGroups, it’s just a set of utilites that allow you to interact with the cgroup kernel feature. Let’s start using it
Let’s limit the cpu of a user to 1 core, 50%. Open up `/etc/cgconfig.conf` in your text editor of choice (I recommend nano), and add these lines
group limit0cpu50 { cpu { cpu.cfs_quota_us="500000"; cpu.cfs_period_us="1000000"; } cpuset { cpuset.cpus="0"; cpuset.mems="0"; } }
This creates a cgroup which has the subsystems cpu, cpuset
. In the cpu subsystems, we’re saying that for every second (`cpu.cfs_period_us`) any process within that cgroup has access to the CPU for 0.5 seconds. So that limits the cpu to 50%. Now to limit the cpu to a single core, we can set the cpuset.cpus parameter to 0 to limit it to core 0. The cpuset.cpus value can be comma separated ranges too, so for example
cpuset.cpus="0-2,4"
And the `cpuset.mems` allocates the memory nodes. Now to assign every process spawned by the user, let’s say, cocoa
to that cgroup. Open up the file /etc/cgrules.conf
and type in this:
cocoa cpuset,cpu /limit0cpu50
This assigns the user cocoa to the cgroup limit0cpu50
, and under the subsystems cpuset
and cpu
. If I had a `memory` subsystem too, then it wouldn’t have restricted memory (assuming I hadn’t added `memory` in there too). And finally, the cgroup we want to limit to is the `limit0cpu50` cgroup.
One last thing we need to do. If you’re on CentOS or RHEL, run:
sudo systemctl start cgconfig sudo systemctl start cgred sudo systemctl enable cgconfig sudo systemctl enable cgred
This starts the cgconfig and cgred services, and enables them to run on boot.
And that’s it! That’s all you need to do to enable that cgroup!
Also, Flaunt7 is currently planning to develop a webgui to automate all of this, so all you’ll have to do is just install that webgui and turn some knobs to get your cgroups up and running!
Finally, I want to point you to the Red Hat documentation on CGroups to help you out more.
Happy Linuxing!