How to Configure cGroups v2 on Linux

cGroups (Control Groups) adalah fitur kernel Linux yang memungkinkan Anda untuk mengelola dan mengontrol resource system seperti CPU, memori, I/O, dan jumlah task yang dapat dijalankan.

Jika Anda sering menggunakan Kubernetes, mungkin Anda sudah mengenal fitur cGroups karena fitur ini digunakan untuk mengontrol penggunaan resource pada service pod. Namun, dalam panduan ini, kita akan mengimplementasikan cGroups untuk mengontrol penggunaan resource pada user Linux.

Prequites

Periksa apakah cGroups v2 didukung oleh sistem operasi.

# grep cgroup /proc/filesystems
nodev   cgroup
nodev   cgroup2

Output dari perintah diatas menunjukan jika sistem operasi yang digunakan mendukung cgroup v1 dan v2.

Selanjutnya, tambahkan systemd.unified_cgroup_hierarchy=1" pada baris GRUB_CMDLINE_LINUX di dalam file /etc/default/grub.

GRUB_TIMEOUT=1
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL="serial console"
GRUB_SERIAL_COMMAND="serial --speed=115200"
GRUB_CMDLINE_LINUX="crashkernel=auto biosdevname=0 net.ifnames=0 console=ttyS0,115200 rhgb scsi_mod.scan=sync systemd.unified_cgroup_hierarchy=1"
GRUB_DISABLE_RECOVERY="true"
GRUB_GFXPAYLOAD_LINUX=auto
GRUB_ENABLE_BLSCFG=true

Update konfigurasi GRUB dengan menjalankan perintah berikut.

grub2-mkconfig -o /boot/efi/EFI/rocky/grub.cfg

Lalu reboot server untuk menerapkan perubahan.

reboot

Setelah server di-reboot, cek untuk memastikan cgroupv2 telah aktif.

# stat -fc %T /sys/fs/cgroup
cgroup2fs 

Using systemd

Berikut adalah cara untuk mengonfigurasi resource menggunakan cgroups-v2 dan systemd.

Buat file cgroups.service lalu tambahkan baris berikut.

nano /etc/systemd/system/cgroup.service
[Unit]
Description=Move processes of users to their cgroups

[Service]
ExecStart=/usr/local/bin/cgroup.sh

[Install]
WantedBy=multi-user.target

Selanjutnya buat file cgroup.sh lalu tambahkan baris berikut.

nano /usr/local/bin/cgroup.sh
#!/bin/bash

pids=$(ls /proc | grep [0-9])
cgroupusers=$(cat /opt/cgroups/cgroupusers)
declare -A users
for uid in $cgroupusers; do
    uids[$uid]=1
done

while sleep 5; do
        newpids=$(ls /proc | grep [0-9])
        diff=$(grep -Fxv "${pids[*]}" <(printf '%s\n' ${newpids[@]}))
        for pid in ${diff[@]}; do
                if [ -d /proc/$pid ]; then
                        uid=$(ps -o uid= -p $pid | awk '{$1=$1;print}')
                        if [ ${uids[$uid]} ]; then
                                echo $pid >> "/sys/fs/cgroup/"$uid".slice/cgroup.procs"
                        fi
                fi
        done
        pids=$newpids
done

Atur permission file cgroup.sh supaya dapat dieksekusi.

chmod 755 /usr/local/bin/cgroup.sh

Tentukan user yang akan disetting cgroups lalu cek uid user dengan perintah.

# id web1
uid=1000(web1) gid=1000(web1) groups=1000(web1)

Kemudian tambahkan uid user ke dalam file /opt/cgroups/cgroupusers.

mkdir -p /opt/cgroups
nano /opt/cgroups/cgroupusers
1000

Lalu buat file dengan format $uid.slice seperti contoh berikut.

nano /etc/systemd/system/1000.slice
[Unit]
Description=User Slice

[Slice]
CPUQuota=30%
IOReadBandwidthMax=/ 20M
IOWriteBandwidthMax=/ 20M
IOReadIOPSMax=/ 1024
IOWriteIOPSMax=/ 1024
MemoryMax=256M
MemoryHigh=128M
TasksMax=30

[Install]
WantedBy=multi-user.target

Restart service cgroup dan 1000.slice.

systemctl daemon-reload
systemctl enable --now cgroup 1000.slice

Using /sys/fs/cgroup

Buat folder Example di dalam path /sys/fs/cgroup.

mkdir /sys/fs/cgroup/Example/

Sebagai contoh, kita akan mencoba membatasi penggunaan CPU untuk service mariadbd.

# pidof mariadbd
845

Untuk membatasi penggunaan CPU hingga 30%.

echo "30000 100000" > /sys/fs/cgroup/Example/cpu.stat

Lalu tambahkan PID mariadbd ke dalam file cgroup.procs.

echo "845" > /sys/fs/cgroup/Example/cgroup.procs

Verifikasi bahwa mariadbd telah berjalan pada cgroup yang ditentukan.

# cat /proc/845/cgroup
0::/Example