CGroups – Zarządzanie zasobami w Linux – rlimit (ulimit) do lamusa?

Stara metoda limitowania:
rlimit – pam_limits, limits.conf, /proc/[pid]/limits
część programów jej nie respektuje, niejasna konfiguracja, limity nieprzestrzegane przez programy.

Aktualna:
CGroups – Mechanizm do hierarchicznego (w postaci wirtualnego systemu plików / pseudo-filesystemu) grupowania procesów w celu przypisania im określonych parametrów w ramach określonych podsystemów (modułów), w celu kontroli zasobów i nie tylko.

Podsystemy:
  • cpu —  podsystem korzysta ze schedulera w celu zapewnienia procesom CGroup dostępu do CPU, dzieli czas procesora dynamicznie pomiędzy grupy.
  • cpuacct – zliczanie zużytych zasobów procesora w grupie – statystyki ustawień podsystemu  cpu.
  • cpusets – przypisywanie procesów do poszczególnych procesorów.
  • devices – kontrola dostępu do urządzeń.
  • freezer – zatrzymywanie i wznawianie procesów.
  • memory – kontrola nad ilością dostępnej pamięci i raportowanie jej zużycia przez procesy w grupie.
  • blkio – kontrola nad limitami I/O do i z urządzeń blokowych.
  • net_cls – tagowanie pakietów sieciowych klasami tc (classid) pozwalające na identyfikacje przez kontroler ruchu pakietów wychodzących od zadań w grupie.
  • net_prio – dynamiczne przydzielanie priorytetu ruchu sieciowego do interfejsów
  • ns – namespace.
Instalujemy pakiety do obsługi CGroups (środowisko uproszczone) :
# apt-get install cgroup-lite 
cgroup-mount      cgroup-umount
# /etc/init.d/cgroup-lite start

lub (środowisko pełne)
# apt-get install cgroup-bin
cgclassify      cgconfigparser  cgdelete        cgget           cgset           
cgclear         cgcreate        cgexec          cgrulesengd     cgsnapshot
Konfigurujemy grupy w hierarchii:
 vim /etc/cgconfig.conf
konfigurujemy reguły przydzielania procesów do odpowiednich grup:
# vim /etc/cgrules.conf
zamontowanie cgroup i modułów, oraz wczytanie konfiguracji z plików:
# service cgconfig start

Zamontują CGroups według poniższego (można z palca, ale pamiętamy o przestrzeganiu „distribution way”, używamy dystrybucji a nie „Linux from Scratch”, możemy dowolnie podmontowywać podsystemy i tworzyć własne struktury drzewiaste cgroup, pamiętając że jeden moduł możemy użyć tylko w jednej hierarchii):

# mkdir /sys/fs/cgroup
# mount -t tmpfs cgroup_root /sys/fs/cgroup
oraz moduły:
# mkdir /sys/fs/cgroup/cpuset
# mount -t cgroup -ocpuset cpuset /sys/fs/cgroup/cpuset
i tak po kolei dla poszczególnych modułów.

W pliku konfiguracyjnym cgconfig.conf mamy to zapisane jako:
mount {
        cpu = /sys/fs/cgroup/cpu;
        cpuacct = /sys/fs/cgroup/cpuacct;
        devices = /sys/fs/cgroup/devices;
        memory = /sys/fs/cgroup/memory;
        freezer = /sys/fs/cgroup/freezer;
}
Tworzymy własną grupę:
przykładowa grupa kontrolna w podsystemie memory:
# mkdir -p /sys/fs/cgroup/memory/applications/firefox
Ustawiamy limity:
# cat /sys/fs/cgroup/memory/applications/firefox/memory.limit_in_bytes
9223372036854775807
# echo 1024M > /sys/fs/cgroup/memory/applications/firefox/memory.limit_in_bytes 
# cat /sys/fs/cgroup/memory/applications/firefox/memory.limit_in_bytes
1073741824
# cat /sys/fs/cgroup/memory/applications/firefox/memory.memsw.limit_in_bytes 
9223372036854775807
# echo 1024M > /sys/fs/cgroup/memory/applications/firefox/memory.memsw.limit_in_bytes
# cat /sys/fs/cgroup/memory/applications/firefox/memory.memsw.limit_in_bytes 
1073741824
Uprawnienia dla użytkownika/użytkowników do kontroli zapisu PIDów:
# chown user1:group1 /sys/fs/cgroup/memory/applications/firefox/tasks

lub za pomocą:
# cgcreate -t user1:group1 -a root:root -g memory:applications/firefox/
# cgset -r memory.limit_in_bytes=1024M applications/firefox/
# cgset -r memory.limit_in_bytes=1024M applications/firefox/

Dodatkowo możemy ustawić że w przypadku braku pamięci ma nastąpić jej „odzyskanie” kosztem naszej grupy do wartości 512MB:

# cgset -r memory.soft_limit_in_bytes=512M applications/firefox/

to samo w /etc/cgconfig.conf :
group applications/firefox {
       perm {
               task {
                       uid = user1; # zapis do pliku task ma user1 i root
                       gid = group1; # zapis do pliku task ma group1 i root
               }
               admin {
                       uid = root; # zapis do pozostałych plików ustawień ma root
                       gid = root; # zapis do pozostałych plików ustawień ma grupa root
               }
       }
       memory {
                memory.limit_in_bytes = 1024M;
                memory.memsw.limit_in_bytes = 1024M;
       }
}

załadowanie ustawień:
# cgconfigparser -l /etc/cgconfig.conf
robi to usługa cgconfig (zamiast utworzenia domyślnej grupy dla wszystkich procesów) o ile ustawimy:
# vim /etc/default/cgconfig
CREATE_DEFAULT=no
CGCONFIG=/etc/cgconfig.conf

teraz gdy user1 uruchomi firefox poprzez:
$ cgexec -g memory:applications/firefox firefox

wszystkie PIDy podprocesów firefox-a (wywołane przez jego proces) zostaną zapisane do /sys/fs/cgroup/memory/applications/firefox/tasksi cała grupa będzie posiadała ograniczenie RAM do 1024MB (bez korzystania ze swap-a, ustawiliśmy jego brak).

alternatywnie:

$ sh -c „echo \$$ > /sys/fs/cgroup/memory/applications/firefox/tasks && firefox” &

lub w przypadku już uruchomionych procesów (przeanalizuj output ps):
$ ps -eLf | grep firefox | awk ‚{print $4}’ | while read pid; do echo $pid >> /sys/fs/cgroup/memory/applications/firefox/tasks ; done

lub za pomocą  cglassify

Możemy to zautomatyzować poprzez dodanie reguł  w /etc/cgrules.conf :
# vim /etc/cgrules.conf
user1:firefox        memory       applications/firefox/
@group1:firefox      memory       applications/firefox/

testujemy reguły za pomocą:
# cgrulesengd -d -n | grep firefox

Uruchamiamy usługę cgred:
# service cgred start
(skrypt uruchomi cgrulesengd)

każdy proces firefox-a (i podprocesy) uruchomiony przez użytkownika user1 lub kogoś z grupy group1 zostanie przeniesiony do cgroupapplications/firefox/ w podsystemie memory, czyli PIDy zostaną zapisane w:
# cat /sys/fs/cgroup/memory/applications/firefox/tasks
64577
64578

zrzut aktualnych ustawień cgroup w systemie (w formacie cgconfig.conf) do pliku:
# cgsnapshot -s > /etc/cgconfig-temp.conf

Odmontowanie CGroups:
odmontowanie zamontowanych podsystemów:
# umount -f /sys/fs/cgroup/*
odmontowanie cgroups:
# umount -f /sys/fs/cgroup

Do czego jeszcze możemy używać CGroups:
– szczegółowe statystyki wykorzystania zasobów przez proces lub grupę procesów
– limitowanie kontenerów



Kilka przydatnych poleceń:
CGroup procesu:
# cat /proc/$PID/cgroup

…  


lista aktywnie używanych hierarchii CGroup:
# grep ‚^cgroup’ /proc/mounts
cgroups /sys/fs/cgroup tmpfs rw,relatime,mode=755 0 0
cgroup /sys/fs/cgroup/cpu cgroup rw,relatime,cpu,release_agent=/usr/lib/ulatencyd/ulatencyd_cleanup.lua 0 0

lista typów grup:
# cat /proc/cgroups
#subsys_name    hierarchy   num_cgroups     enabled
cpuset           6             1               1
cpu              1             46              1
cpuacct          2             1               1
# cat /proc/self/cgroup
7:blkio:/grp_7552
6:cpuset:/
5:freezer:/
CGroups

lxc-linux-containers-cgroups-control-groups-proces-container

5 komentarzy do “CGroups – Zarządzanie zasobami w Linux – rlimit (ulimit) do lamusa?

  1. CGroups na desktopie – zwiększenia responsywności używanych aplikacjiNajłatwiejszym i najszybszym sposobem wykorzystania CGroups na desktopie (i zmniejszenie opóźnień oraz zwiększenia responsywności używanych aplikacji) jest zainstalowanie ulatencyd. Demon dynamicznie będzie przydzielał aplika[…]

    Polubienie

Dodaj komentarz