GRUPOS DE CONTROL - CGROUP
¿Que es cgroup?
Cgroups es una característica de Linux que permite controlar y limitar el consumo de recursos como CPU, memoria, E/S, etc, garantizando un uso eficiente de los recursos del sistema entre múltiples usuarios o procesos. Esta medida busca mejorar el rendimiento y la estabilidad del sistema al evitar que un usuario acapare todos recursos, lo que a su vez beneficia a otros usuarios y aplicaciones en el mismo entorno compartido.
Configuración
cgroup v2
A partir de Debian 11 Bullseye (2021), Debian utiliza jerarquía de grupos unificados (a.k.a. cgroups-v2). Entonces no es necesario instalar los paquetes cgroup-tools y libcgroup2, ya que las herramientas relacionadas con Cgroups v2 están preinstaladas y funcionando correctamente.
Pero si por alguna razon no se encuentran en el sistema se pueden instalar de la siguiente manera:
apt update
apt install cgroup-tools libcgroup2
-
cgroup-tools: Este paquete incluye las utilidades de línea de comandos que permiten interactuar con cgroups de manera directa y realizar tareas como la creación de cgroups, configuración de límites de recursos y la supervisión de procesos dentro de cgroups.
- cgcreate, cgset, cgexec, cgclassify, etc.
-
libcgroup2: Este paquete contiene la biblioteca libcgroup, que proporciona una interfaz de programación para trabajar con cgroups desde aplicaciones y scripts.
D-bus
Instalación de dbus-user-session. Cuando se instala este paquete,se esta instalando el sistema D-Bus para la sesión del usuario en el sistema.
apt install -y dbus-user-session
systemctl --user start dbus
dbus-user-session o D-Bus es un sistema de comunicación entre procesos que permite que aplicaciones en un sistema Linux se comuniquen entre sí. El paquete dbus-user-session proporciona el sistema de D-Bus para sesiones de usuario, lo que significa que habilita la comunicación entre las aplicaciones que se ejecutan en la sesión de un usuario específico.
- systemctl –user start dbus: Una vez que se instalo dbus-user-session, se necesita iniciar el servicio D-Bus para que las aplicaciones en la sesión de usuario puedan utilizarlo para la comunicación entre procesos.
Habilitar D-bus para todos los usuarios del sistema:
systemctl enable dbus
systemctl start dbus
Cgroup v2
De forma predeterminada, en muchos sistemas Linux, solo los controladores memory y pids se delegan a usuarios no root en cgroups. Esto significa que los usuarios no root pueden controlar y configurar límites de recursos relacionados con la memoria y el número de procesos que pueden crear, pero no se les permite controlar otros controladores, como los relacionados con la CPU o los dispositivos.
La razón de esta limitación es por seguridad. Los controladores de cgroups ofrecen un control detallado sobre los recursos del sistema, es por esta razon que no se deja en manos de cualquier usuarios el control completo sobre todos los controladores.
- A usuarios no root solo se le delegan memory y pids:
-
Memory (Memoria): Controlar la cantidad de memoria RAM que sus procesos pueden consumir.
-
Pids (Procesos): Limitar la cantidad de procesos que se pueden iniciar.
- Para permitir la delegación de otros controladores, se debe cambiar la configuración de systemd de la siguiente manera:
mkdir -p /etc/systemd/system/user@.service.d
cat > /etc/systemd/system/user@.service.d/cgroup-defaul.conf << EOF
[Service]
Delegate=cpu cpuset io memory pids
EOF
systemctl daemon-reload
Esto permite que cada usuario que haga loggin en el sistema pueda hacer uso de los controladores CPU, CPUSET, IO, MEMORY,PIDS.
- cpu: Permite controlar y limitar el uso del CPU .
- cpuset: Permite controlar la asignacion de nucleos a procesos (podemos definir en que nucleo se ejecutara un proceso)
- io: Permite administrar el acceso de E/S al disco.
- memory: Permite controlar y limitar el uso de la memoria RAM
- pips: Permite administrar el numero maximo de procesos que pueden ser creados.
USER-SLICE
El archivo que utiliza systemd para crear los user.slice se encuentra en la ruta /usr/lib/systemd/user-.slicer.d/ y no debe ser modificado.
Ver su contenido:
cat /usr/lib/systemd/system/user-.slice.d/10-defaults.conf
El archivo 10-defaults.conf configura las opciones predeterminadas para todas las Slices de Usuario generadas automáticamente por systemd. Modificar este archivo podría afectar a todos los usuarios en el sistema y no se recomienda. En su lugar, se recomienda crear archivos de configuración personalizados en el directorio /etc/systemd/system/user@.service.d/ para realizar configuraciones específicas para usuarios individuales, las culaes se aplicarán solo a los servicios systemd de los usuarios seleccionados.
Cada usuario que se loguea tiene su propio servicio systemd user@UID.service, donde UID es el identificador único del usuario. Se Pueden crear archivos de configuración personalizados dentro de /etc/systemd/system/user@.service.d/ para ajustar la configuración de recursos y controladores de cgroups para usuarios específicos de manera más precisa sin afectar a otros usuarios del sistema.
- en /etc/systemd/system/user@.service.d/: Se colocan las configuraciones que se aplicarán de manera predeterminada a todos los usuarios que se logueen al sistema. Cualquier archivo de configuración que se coloque aquí afectará a todas las instancias de servicios de usuario generadas automáticamente por systemd.
RESUMEN DE LA CONFIGURACION
script en bash
bash
mkdir -p /tmp/ema
cd /tmp/ema
cat >/etc/systemd/system/user@.service.d/delegate.conf <<EOF
[Unit]
Description=Mi servicio Ema
[Service]
Delegate= cpu cpuset io memory pids
EOF
cat >main.cpp <<EOF
#include <cstdlib>
int main() {
system("id -u >> /tmp/dato/dato");
return 0;
}
EOF
g++ main.cpp -o uid-ema
mv uid-ema /usr/sbin
addgroup ema
chmod o-rwx /usr/sbin/uid-ema
chmod g+rx /usr/sbin/uid-ema
chown root:ema /usr/sbin/uid-ema
usermod -aG ema user1
echo "/usr/sbin/uid-ema" >>/home/user1/.bashrc
mkdir -p /tmp/dato
touch /tmp/dato/dato
sleep 1
chmod -R g+wr /tmp/dato
sleep 1
chmod -R o-wrx /tmp/dato
sleep 1
chown -R root:ema /tmp/dato
mkdir -p /etc/script
cat >/etc/script/cgroup.sh <<EOF
#! /bin/bash
archivo=/tmp/dato/dato
if [ ! -f "$archivo" ] || [ ! -r "$archivo" ]; then
echo "El archivo $archivo no existe o no es legible."
exit 1
fi
# Lee el archivo línea por línea
while IFS= read -r linea; do
# Extrae el UID de la línea utilizando una expresión regular
uid=$(echo "$linea" | grep -oE '[0-9]+')
# Verifica si se pudo extraer un UID válido
if [ -z "$uid" ]; then
echo "No se encontró un UID"
else
# Establece los límites de los recursos para el usuario en función del UID
echo "Estableciendo límite de memoria para el usuario con UID $uid a 1G"
echo "1G" > "/sys/fs/cgroup/user.slice/user-$uid.slice/memory.max"
echo "Estableciendo límite de CPU para el usuario con UID $uid a 50000"
echo "50000" > "/sys/fs/cgroup/user.slice/user-$uid.slice/cpu.max"
fi
done < "$archivo"
echo "Script ejecucion completa."
EOF
chmod +x /etc/script/cgroup.sh
CRONTAB
* * * * * /etc/script/cgroup.sh
CRONTAB
* * * * * /etc/script/cgroup.sh