Administre cgroups de la manera difícil, manualmente

Dentro parte uno, analicé la función y el uso de los grupos de control para la administración del sistema y la optimización del rendimiento. Dentro segunda parte, noté la complejidad de los valores de cgroups y CPUShares. Aquí, en la tercera parte, me centro en las tareas administrativas manuales para los grupos de control.

Asegúrese de leer la Parte 4 sobre cómo funcionan los grupos de control con Systemd.

Índice

    Haz grupos de control de la manera difícil

    Veamos cómo crear grupos de control sin ninguna de las herramientas que los rodean. Básicamente, cgroups son solo una estructura de directorio con cgroups montado en ellos. Se pueden ubicar en cualquier parte del sistema de archivos, pero encontrará los cgroups creados por el sistema en /sys/fs/cgroup por defecto. Entonces, ¿cómo se crean grupos de control? Comience creando el siguiente directorio de nivel superior:

    # mkdir -p /my_cgroups

    Una vez que se haya creado, decida qué controladores desea usar. Recuerde que la estructura cgroup de la versión 1 se ve así:

    /my_cgroups
    ├── <controller type>
    │   ├── <group 1>
    │   ├── <group 2>
    │   ├── <group 3>

    Todos los grupos que desea crear se anidan por separado en cada tipo de controlador. Entonces, grupo 1 bajo el controlador memory es totalmente independiente de grupo 1 dentro blkio. Con eso en mente, creemos un ejemplo básico de CPUShares.

    Para simplificar, generaré una carga en el sistema ejecutando:

    # cat /dev/urandom

    Esto pone una carga artificial en el sistema para facilitar la medición. Este no es un ejemplo de carga real, pero destaca los puntos principales de CPUShares. También configuré una máquina virtual que ejecuta CentOS 8 con una sola vCPU para que los cálculos sean realmente simples. Con eso en mente, el primer paso es crear directorios para nuestros controladores cgroup:

    # mkdir -p /my_cgroups/{memory,cpusets,cpu}

    Luego monte los grupos de control en estas carpetas:

    # mount -t cgroup -o memory none /my_cgroups/memory
    # mount -t cgroup -o cpu,cpuacct none /my_cgroups/cpu
    # mount -t cgroup -o cpuset none /my_cgroups/cpusets

    Para crear sus propios cgroups, simplemente cree un nuevo directorio bajo el controlador que desea usar. En este caso, me ocupo del archivo. cpu.shares, que está en el cpu directorio telefónico. Así que vamos a crear algunos grupos de control bajo el cpu controlador:

    # mkdir -p /my_cgroups/cpu/{user1,user2,user3}

    Tenga en cuenta que el controlador llena automáticamente los directorios:

    # ls -l /my_cgroup/cpu/user1/
    -rw-r--r--. 1 root root 0 Sep  5 10:26 cgroup.clone_children
    -rw-r--r--. 1 root root 0 Sep  5 10:26 cgroup.procs
    -r--r--r--. 1 root root 0 Sep  5 10:26 cpuacct.stat
    -rw-r--r--. 1 root root 0 Sep  5 10:26 cpuacct.usage
    -r--r--r--. 1 root root 0 Sep  5 10:26 cpuacct.usage_all
    -r--r--r--. 1 root root 0 Sep  5 10:26 cpuacct.usage_percpu
    -r--r--r--. 1 root root 0 Sep  5 10:26 cpuacct.usage_percpu_sys
    -r--r--r--. 1 root root 0 Sep  5 10:26 cpuacct.usage_percpu_user
    -r--r--r--. 1 root root 0 Sep  5 10:26 cpuacct.usage_sys
    -r--r--r--. 1 root root 0 Sep  5 10:26 cpuacct.usage_user
    -rw-r--r--. 1 root root 0 Sep  5 10:26 cpu.cfs_period_us
    -rw-r--r--. 1 root root 0 Sep  5 10:26 cpu.cfs_quota_us
    -rw-r--r--. 1 root root 0 Sep  5 10:26 cpu.rt_period_us
    -rw-r--r--. 1 root root 0 Sep  5 10:26 cpu.rt_runtime_us
    -rw-r--r--. 1 root root 0 Sep  5 10:20 cpu.shares
    -r--r--r--. 1 root root 0 Sep  5 10:26 cpu.stat
    -rw-r--r--. 1 root root 0 Sep  5 10:26 notify_on_release
    -rw-r--r--. 1 root root 0 Sep  5 10:23 tasks

    Ahora que configuré algunos grupos de control, es hora de generar una carga. Para eso, simplemente abro tres sesiones SSH y ejecuto el siguiente comando en primer plano:

    # cat /dev/urandom

    Puedes ver los resultados en top:

    NOTA IMPORTANTE: Recuerde que los CPUShares se basan en el cgroup de nivel superior, que no está restringido de forma predeterminada. Esto significa que si un proceso más alto en el árbol solicita CPUShares, el sistema priorizará ese proceso. Puede confundir a la gente. Tener una representación visual del diseño del grupo de control en un sistema es esencial para evitar confusiones.

    En la captura de pantalla anterior, puede ver que todos cat los procesos reciben más o menos la misma cantidad de tiempo de CPU. Esto se debe a que, de forma predeterminada, a cgroups se le asigna un valor de 1024 en cpu.shares. Estas acciones están limitadas por la relación de la matriz con otros cgroups, como se discutió anteriormente. En nuestro ejemplo, no ajusté el peso de ninguno de los padres. Por lo tanto, si todos los cgroups principales solicitan recursos simultáneamente, se aplica el peso predeterminado de 1024 CPUShares.

    Volviendo a nuestro ejemplo, creé un cgroup con valores predeterminados. Esto significa que cada grupo tiene el peso predeterminado de 1024. Para cambiar esto, simplemente cambie los valores en el cpu.shares archivar:

    # echo 2048 > user1/cpu.shares
    # echo 768 > user2/cpu.shares
    # echo 512 > user3/cpu.shares

    Excelente, ahora tengo un cálculo de peso más complicado, pero en realidad no agregué ningún proceso al grupo de control. Por lo tanto, el grupo de control está inactivo. Para agregar un proceso a un grupo de control, simplemente agregue el PID deseado al tasks archivar:

    # echo 2023 > user1/tasks

    Aquí está el resultado de agregar un proceso en un grupo de control como se ve en top:

    Como puede ver en la captura de pantalla anterior, el proceso del nuevo cgroup está obteniendo aproximadamente la mitad del tiempo de CPU. Esto se debe a la ecuación de antes:

    Avancemos y agreguemos los otros dos procesos en sus respectivos grupos de control y observemos los resultados:

    # echo 2024 > user2/tasks
    # echo 2025 > user3/tasks

    Ahora podemos ver que la ponderación ha tenido efecto, con el cgroup usuario1 tomando alrededor del 61% del tiempo de CPU:

    El tiempo restante se comparte entre usuario2 y usuario3.

    Hay, por supuesto, varios problemas con nuestra configuración de prueba.

    1. Todos estos son creados a mano. ¿Qué pasa si el proceso que pones en un cgroup cambia su PID?
    2. Los archivos y carpetas personalizados creados no sobrevivirán a un reinicio.
    3. Es mucho trabajo manual. ¿Dónde están las herramientas?

    No teman mis amigos, systemd lo tiene cubierto.

    Conclusión

    Ahora que comprendemos mejor la administración manual de los grupos de control, podemos apreciar mejor el valor de la colaboración entre los grupos de control y systemd. Examino esta idea en la cuarta parte de esta serie. Por cierto, la cuarta parte es la conclusión.

    Artículos de interés

    Subir