Utilice Cgroup para la gestión de recursos en Docker

1. Método de configuración de recursos de Cgroup

1. Docker controla las cuotas de recursos que utilizan los contenedores a través de Cgroup, incluidos los tres aspectos principales de CPU, memoria y disco, que básicamente cubre las cuotas de recursos comunes y el control de uso.

2. Cgroup es la abreviatura de Grupos de control. Es un mecanismo proporcionado por el kernel de Linux para limitar, registrar y aislar los recursos físicos (como CPU, memoria, disco I0, etc.) utilizados por los grupos de procesos. Se utiliza por muchos proyectos como LXC y Docker. Se utiliza para implementar el control de recursos del proceso. Cgroup en sí es la estructura básica que proporciona funciones e interfaces para los procesos de agrupación. La gestión de recursos específicos, como E / S o control de asignación de memoria, se realiza a través de esta función.
Estas funciones específicas de gestión de recursos se denominan subsistemas de Cgroup. Se implementan los siguientes subsistemas principales:

  • blkio: Establecer para limitar el control de entrada y salida de cada dispositivo de bloque. Por ejemplo: disco, CD, usb, etc.
  • CPU: utilice el programador para proporcionar acceso a la CPU para las tareas de cgroup.
  • cpuacct: genera informes de recursos de CPU para tareas de cgroup.
  • cpuset: si se trata de una CPU de varios núcleos, este subsistema asignará CPU y memoria por separado para las tareas de cgroup.
  • dispositivos: permite o niega el acceso a dispositivos mediante tareas de cgroup.
  • freezer: pausa y reanuda las tareas de cgroup.
  • memoria: establezca el límite de memoria de cada cgroup y genere informes de recursos de memoria.
  • net_cls: Marque cada paquete de red para un uso conveniente por parte de cgroups.
  • ns: subsistema de espacio de nombres.
  • perf_event: se agregó la capacidad de monitorear y rastrear cada grupo, que puede monitorear todos los subprocesos que pertenecen a un grupo específico y los subprocesos que se ejecutan en una CPU específica.

Comencemos a usar la herramienta de prueba de esfuerzo para probar el uso de la CPU y la memoria.

2. Utilice la herramienta de estrés para probar la CPU y la memoria

Primero use Dockerfile para crear una imagen de herramienta de estrés basada en Centos

[root@localhost ~]# mkdir /opt/stress
[root@localhost ~]# vim /opt/stress/Dockerfile
FROM centos:7
MAINTAINER panrj
RUN yum install -y wget
RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
RUN yum install -y stress
[root@localhost ~]# cd /opt/stress/
[root@localhost stress]# docker build -t centos:stress .
[root@localhost stress]# docker run -itd --cpu-shares 100 centos:stress

Inserte la descripción de la imagen aquí
Descripción: De forma predeterminada, el recurso compartido de CPU de cada contenedor Docker es 1024. La participación de un solo recipiente no tiene sentido. Solo cuando se ejecutan varios contenedores al mismo tiempo, se puede reflejar el efecto de la ponderación de la CPU del contenedor.
Por ejemplo, los recursos compartidos de CPU de dos contenedores A y B son respectivamente 1000 y 500. Cuando la CPU asigna segmentos de tiempo, el contenedor A tiene el doble de posibilidades de obtener segmentos de tiempo de CPU que el contenedor B.
Sin embargo, el resultado de la asignación depende del estado de ejecución del host y otros contenedores en ese momento.De hecho, no hay garantía de que el contenedor A pueda obtener segmentos de tiempo de CPU. Por ejemplo, el proceso del contenedor A siempre está inactivo,
entonces el contenedor B puede obtener más segmentos de tiempo de CPU que el contenedor A. En casos extremos, por ejemplo, solo hay un contenedor ejecutándose en el host, incluso si su CPU compartida es solo 50, puede monopolizar los recursos de CPU de todo el host.

Cgroups solo tendrá efecto cuando los recursos asignados por el contenedor sean escasos, es decir, cuando los recursos utilizados por el contenedor deban restringirse. Por lo tanto, es imposible determinar cuántos recursos de CPU se asignan a un contenedor basándose únicamente en el
recurso compartido de CPU de un contenedor. El resultado de la asignación de recursos depende de la asignación de CPU de otros contenedores que se ejecutan al mismo tiempo y del estado de ejecución del Procesos en el contenedor.
Puede establecer la prioridad del contenedor para usar la CPU a través del recurso compartido de la CPU, como iniciar dos contenedores y ejecutarlos para ver el porcentaje de uso de la CPU.

[root@localhost stress]# docker run -tid --name cpu512 --cpu-shares 512 centos:stress stress -c 10 //容器产生10个子函数进程
[root@localhost stress]# docker exec -it f4953c0d7e76 bash //进入容器使用top查看cpu使用情况

Inserte la descripción de la imagen aquí

Enciéndalo en este momento: un contenedor para comparar

[root@localhost stress]# docker run -tid --name cpu1024 --cpu-shares 1024 centos:stress stress -c 10

[root@localhost stress]# docker exec -it 5590c57d27b0 bash //进容器使用top对比两个容器的%CPU,比例是1:2

Inserte la descripción de la imagen aquí

Comparar y ver resultados
Inserte la descripción de la imagen aquí

Tres, límite de ciclo de la CPU

Docker proporciona dos parámetros --cpu-period y --cpu-quota para controlar los ciclos de reloj de la CPU que el contenedor puede asignar.

--cpu-periodSe utiliza para especificar cuánto tiempo se debe reasignar el uso de CPU del contenedor.

--cpu-quotaSe utiliza para especificar cuánto tiempo se puede utilizar para ejecutar este contenedor en este ciclo.

A diferencia de -cpu-shares, esta configuración especifica un valor absoluto, y el uso de recursos de CPU por parte del contenedor nunca excederá el valor configurado.
La unidad de cpu-period y cpu-quota es microsegundo (us). El valor mínimo de cpu-period es 1000 microsegundos, el valor máximo es 1 segundo (10 ^ 6μs) y el valor predeterminado es 0.1 segundo (100000 us).

El valor predeterminado de cpu-quota es -1, lo que significa que no hay control. Los parámetros cpu-period y cpu-quota se utilizan generalmente en combinación.

P.ej: El proceso del contenedor necesita usar una sola CPU durante 0,2 segundos cada 1 segundo. Puede establecer el período de cpu en 1000000 (es decir, 1 segundo) y el cpu-quota en 200000 (0,2 segundos).

Por supuesto, en el caso de varios núcleos, si se permite que el proceso contenedor ocupe completamente dos CPU, puede establecer el período de cpu en 100000 (es decir, 0,1 segundos) y la cuota de cpu en 200000 (0,2 segundos) .

[root@localhost stress]# docker run -tid --cpu-period 100000 --cpu-quota 200000 centos:stress
[root@localhost stress]# docker exec -it 3a61d26ac823 bash
[root@98d2aaa50019 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_period_us
100000
[root@98d2aaa50019 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us
200000

Inserte la descripción de la imagen aquí

Cuatro, control del núcleo de la CPU

Para los servidores con CPU de varios núcleos, Docker también puede controlar qué núcleos de CPU ejecuta el contenedor, es decir, usar el parámetro -cpuset-cpus.
Esto es especialmente útil para servidores con varias CPU y se puede configurar con un rendimiento óptimo para contenedores que requieren informática de alto rendimiento.

[root@localhost stress]# docker run -tid --name cpu1 --cpuset-cpus 0-1 centos:stress
执行以上命令需要宿主机为双核,表示创建的容器只能用01两个内核。最终生成的cgroup的 CPU 内核配置如下:
[root@localhost stress]# docker exec -it 631eea630b21 bash

[root@631eea630b21 /# cat /sys/fs/cgroup/cpuset/cpuset.cpus
0-1
通过下面指令可以看到容器中进程与CPU内核的绑定关系,达到绑定CPU内核的目的。
[root@localhost stress]# docker exec 631eea630b21 taskset -c -p 1 //容器内部第- 个进程号pid为1被绑定到指定CPU上运行
pid 1's current affinity list:0,1

5. Uso mixto de parámetros de control de cuotas de la CPU

Use el parámetro cpuset-cpus para especificar que el contenedor A usa el núcleo de CPU 0 y el contenedor B solo usa el núcleo de CPU 1.
En el host, solo estos dos contenedores usan los núcleos de CPU correspondientes y cada uno de ellos ocupa todos los recursos del núcleo y la CPU. -las acciones no tienen ningún efecto obvio.
Los parámetros cpuset-cpus y cpuset-mems solo son válidos en servidores con nodos de múltiples núcleos y múltiples memorias, y deben coincidir con la configuración física real; de lo contrario, no se puede lograr el propósito del control de recursos.

Cuando el sistema tiene varios núcleos de CPU, es necesario configurar el núcleo de la CPU del contenedor a través del parámetro cpuset-cpus para facilitar la prueba.

//宿主系统修改为4核心CPU
[root@localhost stress]# docker run -tid --name cpu3 --cpuset-cpus 1 --cpu-shares 512 centos:stress stress -c 1
[root@localhost stress]# docker exec -it 84598dfadd34 bash
[root@localhost stress]# exit


[root@localhost stress]# docker run -tid --name cpu4 --cpuset-cpus 3 --cpu-shares 1024 centos:stress stress -c 1
[root@localhost stress]# top //记住按1查看每个核心的占用

Tasks: 172 total, 2 running, 170 sleeping, 0 stopped, 0 zombie
%Cpu0 : 0.0us, 0.0sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0si, 0.0 st
%Cpu1 : 0.0us, 0.0sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0si, 0.0 st
%Cpu2 : 0.0us, 0.0sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0si, 0.0 st
%Cpu3 :100.0us, 0.0sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0si, 0.0 st
KiB Mem : 7994072 total, 6394056 free, 450124 used, 1149892 buff/cache
KiB Swap: 4194300 total, 4194300 free,  0 used.7174064 avail Mem

[root@localhost stress]# docker exec -it 0eed2c8a20df bash
总结:上面的centos:stress镜像安装了stress工具,用来测试CPU和内存的负载。通过在两个容器上分别执行stress-c 1命令,
将会给系统- 个随机负载,产生1个进程。这个进程都反复不停的计算由rand()产生随机数的平方根,直到资源耗尽。
观察到宿主机上的CPU使用率,第三个内核的使用率接近100%, 并且一批进程的CPU使用率明显存在2:1的使用比例的对比。

Inserte la descripción de la imagen aquí

Sexto, límite de memoria

Al igual que en el sistema operativo, la memoria que puede utilizar el contenedor incluye dos partes: memoria física e intercambio.

Docker controla el uso de la memoria del contenedor a través de los siguientes dos conjuntos de parámetros.

-m或--memory: 设置内存的使用限额,例如100M、1024M。
--memory-swap: 设置内存+swap的使用限额。

Ejecute el siguiente comando para permitir que el contenedor utilice hasta 200 M de memoria y 300 M de intercambio.

[root@localhost stress]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
--vm 1: 启动1个内存工作线程。
--vm-bytes 280M: 每个线程分配280M内存。

Inserte la descripción de la imagen aquí

De forma predeterminada, el contenedor puede utilizar toda la memoria libre del host.
Similar a la configuración de cgroups de la CPU, Docker creará automáticamente /sys/fs/cgroup/memory/docker/<容器的完整长ID>el archivo de configuración de cgroup correspondiente para el contenedor en el directorio

Si la memoria asignada por el subproceso de trabajo excede los 300M y la memoria asignada excede el límite, el subproceso de estrés informa un error y el contenedor se cierra.

[root@localhost stress]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 310M

Inserte la descripción de la imagen aquí

Siete, limitaciones de Block IO

De forma predeterminada, todos los contenedores pueden leer y escribir en el disco por igual.Puede cambiar la prioridad del bloque contenedor IO configurando el parámetro -blkio-weight.
–Blkio-weight es similar a –cpu-shares. Establece el valor de peso relativo y el valor predeterminado es 500.

En el siguiente ejemplo, el ancho de banda del contenedor A para leer y escribir en el disco es el doble que el del contenedor B

[root@localhost ~]#docker run -it --name container_A --blkio-weight 600 centos:stress
[root@0d16f3608f62 /]# cat /sys/fs/cgroup/blkio/blkio.weight
600

[root@localhost ~]#docker run -it --name container_B --blkio-weight 300 centos:stress
[root@ae6c2a3370b6 /]# cat /sys/fs/cgroup/blkio/blkio.weight
300

Inserte la descripción de la imagen aquí

8. Limitaciones de bps e iops

bps Es byte por segundo, la cantidad de datos leídos y escritos por segundo.
iops Es io por segundo, el número de IO por segundo.

Los bps y iops del contenedor se pueden controlar mediante los siguientes parámetros:

–device-read-bps,限制读某个设备的 bps。
–device-write-bps,限制写某个设备的 bps。
–device-read-iops,限制读某个设备的 iops。
–device-write-iops,限制写某个设备的 iops。

El siguiente ejemplo limita la velocidad a la que el contenedor escribe / dev / sda a 5 MB / s.

[root@localhost docker]# docker run -it --device-write-bps /dev/sda:5MB centos:stress

[root@c4a16f026e5a /]# dd if=/dev/zero of=test bs=1M count=1024 oflag=direct   //可以按ctrl+c中断查看
906+0 records in
906+0 records out
950009856 bytes (950 MB) copied, 181.202 s, 5.2 MB/s

Inserte la descripción de la imagen aquí

Utilice el comando dd para probar la velocidad de escritura en el disco del contenedor. Debido a que el sistema de archivos del contenedor está en el host / dev / sda
, escribir archivos en el contenedor es equivalente a escribir en el host / dev / sda. Además, oflag = direct especifica IO directo para escribir archivos, de
modo que --device-write-bps pueda tener efecto.

El resultado muestra que el límite de velocidad es de aproximadamente 5 MB / s. Como prueba comparativa, si la velocidad no está limitada, los resultados son los siguientes.

[root@localhost docker]# docker run -it centos:stress

[root@012ab0128349 /]# dd if=/dev/zero of=test bs=1M count=1024 oflag=direct
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 0.928611 s, 1.2 GB/s

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/panrenjun/article/details/115324493
Recomendado
Clasificación