DevOps в серията K8s bootcamp

Забележете, пълната мисловна карта „DevOps в K8s“ е достъпна на: „DevOps в мисловната карта на K8s

Linux Cgroups е един от основните принципи за внедряване на контейнерната технология. Той помага при контролирането и изолирането на използването на ресурси от различни групи процеси и позволява по-добър контрол и управление на системните ресурси.

Контейнерите използват Linux Cgroups, защото предоставят удобен и ефективен начин за изолиране и управление на използването на ресурси за множество процеси, изпълнявани на един хост. Когато стартирате контейнер, той обикновено се състои от множество процеси, които работят заедно, за да предоставят конкретна услуга.

С Cgroups можете да създадете отделна cgroup за всеки контейнер и да зададете ограничения на ресурсите за всяка cgroup. Това ви позволява да контролирате и изолирате използването на ресурсите на всеки контейнер, така че един контейнер да не може да консумира ресурси, които биха повлияли отрицателно на производителността на други контейнери.

Какво е Linux Cgroups

Linux Cgroups (Control Groups) е функция на ядрото на Linux, която позволява да се управлява и ограничава количеството системни ресурси, като време на процесора, памет и I/O честотна лента, които процес или група от процеси може да използва.

Например, можете да използвате Cgroups, за да гарантирате, че определен процес или група от процеси не консумира твърде много CPU или памет, или за да ограничите количеството I/O на диска, извършвано от процес.

Cgroups се създават и управляват с помощта на файловата система cgroup, която е монтирана като част от йерархията на файловата система на Linux. Процесите могат да бъдат присвоени на cgroups с помощта на йерархията на cgroup, а ограниченията на ресурсите за cgroup могат да бъдат задавани и актуализирани динамично. Това прави cgroups мощен и гъвкав инструмент за управление на системни ресурси в Linux.

Например, по-долу е даден пример как да използвате Cgroups за ограничаване на използването на паметта:

  • Създайте нова Cgroup:
$ mkdir /sys/fs/cgroup/memory/test_cgroup
  • Задайте ограничение на паметта:
$ sh -c "echo 200M > /sys/fs/cgroup/memory/test_cgroup/memory.limit_in_bytes"
$ cat /sys/fs/cgroup/memory/test_cgroup/memory.limit_in_bytes
20971520
  • Добавете процес към test_cgroup:
$ echo $PID > /sys/fs/cgroup/memory/test_group/tasks

В горния пример монтирахме файловата система на cgroup, създадохме нова cgroup, наречена „test_cgroup“, зададохме лимита на паметта й на 200 MB и преместихме процес с PID $PID в cgroup. Сега процесът и всички негови дъщерни процеси ще бъдат ограничени до използването на само 200 MB памет. Ако процесът се опита да използва повече от 200 MB, той ще бъде прекратен от ядрото на Linux.

Основни понятия на Linux Cgroup

Йерархия

Cgroups са организирани в йерархия, с основна контролна група в горната част и дъщерни контролни групи, вложени в родителските контролни групи. Това позволява йерархично управление на ресурсите, където ограниченията могат да се задават на основно ниво и да се наследяват от дъщерни cgroups.

Контролери

Cgroups използват различни контролери за управление и ограничаване на различни ресурси, като време на процесора, памет и I/O честотна лента. Всеки контролер има набор от регулируеми параметри, които определят ограниченията на ресурсите за cgroup.

Задачи

Задачите са процеси, които са присвоени на cgroup. Когато даден процес е присвоен на cgroup, всички негови дъщерни процеси автоматично ще бъдат присвоени на същата cgroup.

Ограничения на ресурсите

Ограниченията на ресурсите определят количеството ресурси, които една cgroup може да използва. Например ограничението на паметта определя максималното количество памет, което една cgroup може да използва, докато ограничението на CPU определя максималното количество CPU време, което една cgroup може да използва.

Известия за събития

Cgroups може да генерира известия за събития, когато са изпълнени определени условия, като например когато cgroup превиши ограничението на паметта си. Тези известия могат да се използват за задействане на автоматизирани действия, като спиране на процес или регистриране на предупреждение.

Файлова система

Cgroups се управляват с помощта на файловата система cgroup, която е монтирана като част от йерархията на файловата система на Linux. Файловата система cgroup предоставя унифициран интерфейс за създаване, управление и наблюдение на cgroups.

Linux Cgroup подсистеми

CGroups поддържаните подсистеми включват следните категории, които определят подсистема за всеки ресурс, който може да се контролира:

  • cpuset: Разпределете отделен CPU възел за процеса в cgroup, т.е. той може да бъде обвързан с конкретен CPU
  • cpuacct: Статистика на използването на процесора от процесите в cgroup
  • memory: Ограничете използването на паметта на процеса в cgroup и можете да докладвате използването на паметта
  • devices: Контролирайте до кои файлови устройства имат достъп процесите в cgroup (създаване, четене и запис на файлове на устройства)
  • freezer: Спиране или възобновяване на задачата в cgroup
  • net_cls: Можете да маркирате мрежовите пакети на процесите в cgroups и след това да използвате tc модула (контрол на трафика), за да контролирате пакетите
  • blkio: Ограничете IO на блоковото устройство на процеса в cgroup
  • perf_event: Наблюдавайте времето за изпълнение на процеса в cgroup, което може да се използва за настройка на производителността
  • hugetlb: функция за контрол на ресурсите на hugetlb
  • pids: Ограничете броя процеси, които могат да бъдат създадени в cgroup
  • net_prio: Позволете на администраторите динамично да задават приоритета на мрежовото предаване чрез различни приложения

Можете да намерите подсистемата, поддържана от текущата система, като прегледате /proc/cgroupsфайла CGroups:

$ cat /proc/cgroups
#subsys_name hierarchy num_cgroups enabled
cpuset       10        3           1
cpu          3         63          1
cpuacct      3         63          1
blkio        7         63          1
memory       8         69          1
devices      9         63          1
freezer      4         3           1
net_cls      2         3           1
perf_event   6         3           1
net_prio     2         3           1
hugetlb      11        3           1
pids         5         63          1

Можете също да използвате командата mount --type cgroupthe, за да проверите кои cgroups са монтирани в текущата система:

$ mount --type cgroup
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)

Linux Cgroup поддиректория

В Linux cgroups всяка cgroup е представена от директория във файловата система на cgroup. Пътят до тази директория се конструира чрез свързване на имената на cgroup и нейните родителски cgroups, разделени с наклонени черти.

Да предположим например, че имате йерархия на cgroup с две нива: основна cgroup и две дъщерни cgroups, наречени „group1“ и „group2“. Пътят до cgroup „group1“ ще бъде „/group1“, а пътят до cgroup „group2“ ще бъде „/group1/group2“.

Например точката на монтиране на подсистемата cpu се намира на /sys/fs/cgroup/cpu/ и изглежда така:

$ ll /sys/fs/cgroup/cpu/
total 0
-rw-r--r--  1 root root 0 Feb 12 15:32 cgroup.clone_children
-rw-r--r--  1 root root 0 Jan 29 15:34 cgroup.procs
-r--r--r--  1 root root 0 Feb 12 15:32 cgroup.sane_behavior
-r--r--r--  1 root root 0 Feb 12 15:32 cpuacct.stat
-rw-r--r--  1 root root 0 Feb 12 15:32 cpuacct.usage
-r--r--r--  1 root root 0 Feb 12 15:32 cpuacct.usage_all
-r--r--r--  1 root root 0 Feb 12 15:32 cpuacct.usage_percpu
-r--r--r--  1 root root 0 Feb 12 15:32 cpuacct.usage_percpu_sys
-r--r--r--  1 root root 0 Feb 12 15:32 cpuacct.usage_percpu_user
-r--r--r--  1 root root 0 Feb 12 15:32 cpuacct.usage_sys
-r--r--r--  1 root root 0 Feb 12 15:32 cpuacct.usage_user
-rw-r--r--  1 root root 0 Feb 12 15:32 cpu.cfs_period_us
-rw-r--r--  1 root root 0 Feb  4 14:55 cpu.cfs_quota_us
-rw-r--r--  1 root root 0 Feb  4 14:55 cpu.rt_period_us
-rw-r--r--  1 root root 0 Feb 12 15:32 cpu.rt_runtime_us
-rw-r--r--  1 root root 0 Feb  4 14:55 cpu.shares
-r--r--r--  1 root root 0 Feb 12 15:32 cpu.stat
drwxr-xr-x  3 root root 0 Feb  4 15:04 docker
-rw-r--r--  1 root root 0 Feb 12 15:32 notify_on_release
-rw-r--r--  1 root root 0 Feb 12 15:32 release_agent
drwxr-xr-x 60 root root 0 Feb  4 14:55 system.slice
-rw-r--r--  1 root root 0 Feb 12 15:32 tasks
drwxr-xr-x  2 root root 0 Feb  4 14:55 user.slice

Ако проверим услугата docker, ще видите:

$ systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: active (running) since Sat 2023-02-04 14:55:06 UTC; 1 weeks 1 days ago
     Docs: https://docs.docker.com
  Process: 26807 ExecStartPre=/usr/libexec/docker/docker-setup-runtimes.sh (code=exited, status=0/SUCCESS)
  Process: 26805 ExecStartPre=/bin/mkdir -p /run/docker (code=exited, status=0/SUCCESS)
 Main PID: 26810 (dockerd)
    Tasks: 18
   Memory: 249.3M
   CGroup: /system.slice/docker.service
           └─26810 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --default-ulimit nofile=32768:65536

Можете да видите docker.service Cgroup се намира на /system.slice/docker.service , но това е само относителен път и действителната директория на файловата система е под съответната подсистема, например /sys/fs/cgroup/cpu/system.slice/docker.service .

Заключение