Use Cgroup para gerenciamento de recursos no Docker

1. Método de configuração de recursos Cgroup

1. Docker controla as cotas de recursos usados ​​por contêineres por meio do Cgroup, incluindo os três aspectos principais de CPU, memória e disco, que basicamente cobre cotas de recursos comuns e controle de uso.

2. Cgroup é a abreviatura de Control Groups. É um mecanismo fornecido pelo kernel Linux para limitar, registrar e isolar os recursos físicos (como CPU, memória, disco I0, etc.) usados ​​por grupos de processos. É usado por muitos projetos, como LXC e docker. Usado para implementar o controle de recursos do processo. O próprio Cgroup é a estrutura básica que fornece funções e interfaces para agrupar processos. O gerenciamento de recursos específicos, como E / S ou controle de alocação de memória, é realizado por meio desta função.
Essas funções específicas de gerenciamento de recursos são chamadas de subsistemas Cgroup. Os seguintes subsistemas principais são implementados:

  • blkio: Defina para limitar o controle de entrada e saída de cada dispositivo de bloco. Por exemplo: disco, CD, USB e assim por diante.
  • CPU: Use o agendador para fornecer acesso à CPU para tarefas cgroup.
  • cpuacct: Gera relatórios de recursos de CPU para tarefas cgroup.
  • cpuset: Se for uma CPU multi-core, este subsistema irá alocar CPU e memória separadas para tarefas cgroup.
  • dispositivos: Permitir ou negar acesso a dispositivos por tarefas cgroup.
  • freezer: Pause e retome as tarefas do cgroup.
  • memory: Defina o limite de memória de cada cgroup e gere relatórios de recursos de memória.
  • net_cls: Marque cada pacote de rede para uso conveniente pelos cgroups.
  • ns: subsistema de namespace.
  • perf_event: Adicionada a capacidade de monitorar e rastrear cada grupo, que pode monitorar todos os threads pertencentes a um grupo específico e threads em execução em uma CPU específica.

Vamos começar a usar a ferramenta de teste de estresse para testar o uso da CPU e da memória.

2. Use a ferramenta de estresse para testar a CPU e a memória

Primeiro, use o Dockerfile para criar uma imagem de ferramenta de estresse baseada em 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

Insira a descrição da imagem aqui
Descrição: Por padrão, o compartilhamento de CPU de cada contêiner do Docker é 1024. O compartilhamento de um único contêiner não faz sentido. Somente quando vários contêineres estão em execução ao mesmo tempo, o efeito do peso da CPU do contêiner pode ser refletido.
Por exemplo, os compartilhamentos de CPU de dois contêineres A e B são 1000 e 500, respectivamente. Quando a CPU aloca fatias de tempo, o contêiner A tem duas vezes mais chance de obter fatias de tempo de CPU do que o contêiner B.
No entanto, o resultado da alocação depende do status de execução do host e de outros contêineres no momento.Na verdade, não há garantia de que o contêiner A será capaz de obter fatias de tempo da CPU. Por exemplo, o processo do contêiner A está sempre ocioso,
então o contêiner B pode obter mais frações de tempo de CPU do que o contêiner A. Em casos extremos, por exemplo, há apenas um contêiner em execução no host, mesmo que seu compartilhamento de CPU seja de apenas 50, ele pode monopolizar os recursos de CPU de todo o host.

Os cgroups só terão efeito quando os recursos alocados pelo contêiner forem escassos, ou seja, quando os recursos usados ​​pelo contêiner precisarem ser restritos. Portanto, é impossível determinar quantos recursos de CPU são alocados para um contêiner com base apenas na participação da CPU de um contêiner. O
resultado da alocação de recursos depende da alocação de CPU de outros contêineres em execução ao mesmo tempo e do status de execução do processos no contêiner.
Você pode definir a prioridade do contêiner para usar a CPU por meio do compartilhamento de cpu, como iniciar dois contêineres e executar para visualizar a porcentagem de uso da 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使用情况

Insira a descrição da imagem aqui

Ligue-o neste momento - um contêiner para comparação

[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

Insira a descrição da imagem aqui

Compare e veja os resultados
Insira a descrição da imagem aqui

Três, limite de ciclo de CPU

O Docker fornece dois parâmetros --cpu-period e --cpu-quota para controlar os ciclos de clock da CPU que o contêiner pode alocar.

--cpu-periodÉ usado para especificar por quanto tempo o uso da CPU do contêiner deve ser realocado.

--cpu-quotaÉ usado para especificar quanto tempo pode ser usado para executar este contêiner neste ciclo.

Ao contrário de -cpu-shares, esta configuração especifica um valor absoluto e o uso de recursos da CPU do contêiner nunca excederá o valor configurado.
A unidade de cpu-period e cpu-quota é microssegundo (us). O valor mínimo de cpu-period é 1000 microssegundos, o valor máximo é 1 segundo (10 ^ 6μs) e o valor padrão é 0,1 segundo (100000 us).

O valor padrão de cpu-quota é -1, o que significa nenhum controle. Os parâmetros cpu-period e cpu-quota são geralmente usados ​​em combinação.

Por exemplo: O processo do contêiner precisa usar uma única CPU por 0,2 segundos a cada 1 segundo. Você pode definir o período da CPU para 1000000 (ou seja, 1 segundo) e a cota da CPU para 200000 (0,2 segundos).

Claro, no caso de multi-core, se o processo do contêiner ocupar completamente duas CPUs, você pode definir o período da CPU para 100000 (ou seja, 0,1 segundo) e a cpu-quota para 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

Insira a descrição da imagem aqui

Quatro, controle do núcleo da CPU

Para servidores com CPUs de vários núcleos, o Docker também pode controlar quais núcleos de CPU o contêiner executa, ou seja, usar o parâmetro -cpuset-cpus.
Isso é especialmente útil para servidores com várias CPUs e pode ser configurado com desempenho ideal para contêineres que requerem computação de alto desempenho.

[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 misto de parâmetros de controle de cota de CPU

Use o parâmetro cpuset-cpus para especificar que o contêiner A usa CPU core 0 e o contêiner B apenas CPU core 1.
No host, apenas esses dois contêineres usam os núcleos de CPU correspondentes, e cada um deles ocupa todos os recursos principais e cpu -shares não têm efeito óbvio.
Os parâmetros cpuset-cpus e cpuset-mems são válidos apenas em servidores com nós multi-core e multi-memória e devem corresponder à configuração física real, caso contrário, o objetivo do controle de recursos não pode ser alcançado.

Quando o sistema tem vários núcleos de CPU, é necessário definir o núcleo de CPU do contêiner por meio do parâmetro cpuset-cpus para facilitar o teste.

//宿主系统修改为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的使用比例的对比。

Insira a descrição da imagem aqui

Sexto, limite de memória

Semelhante ao sistema operacional, a memória que pode ser usada pelo contêiner inclui duas partes: memória física e swap.

O Docker controla o uso da memória do contêiner por meio dos dois conjuntos de parâmetros a seguir.

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

Execute o seguinte comando para permitir que o contêiner use até 200 MB de memória e 300 MB de troca.

[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内存。

Insira a descrição da imagem aqui

Por padrão, o contêiner pode usar toda a memória livre no host.
Semelhante à configuração cgroups da CPU, o Docker criará automaticamente /sys/fs/cgroup/memory/docker/<容器的完整长ID>o arquivo de configuração cgroup correspondente para o contêiner no diretório

Se a memória alocada pelo thread de trabalho exceder 300 MB e a memória alocada exceder o limite, o thread de estresse reporta um erro e o contêiner sai.

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

Insira a descrição da imagem aqui

Sete, limitações de bloco IO

Por padrão, todos os contêineres podem ler e gravar no disco igualmente. Você pode alterar a prioridade do bloco IO do contêiner configurando o parâmetro -blkio-weight.
–Blkio-weight é semelhante a –cpu-shares. Ele define o valor de peso relativo e o padrão é 500.

No exemplo a seguir, a largura de banda do contêiner A para ler e gravar no disco é o dobro do contêiner 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

Insira a descrição da imagem aqui

8. Limitações de bps e iops

bps É byte por segundo, a quantidade de dados lidos e gravados por segundo.
iops É io por segundo, o número de E / S por segundo.

Os bps e iops do contêiner podem ser controlados pelos seguintes parâmetros:

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

O exemplo a seguir limita a taxa na qual o contêiner grava / 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

Insira a descrição da imagem aqui

Use o comando dd para testar a velocidade de gravação no disco do contêiner. Como o sistema de arquivos do contêiner está no host / dev / sda
, gravar arquivos no contêiner é equivalente a gravar no host / dev / sda. Além disso, oflag = direct especifica IO direto para gravar arquivos,
para que --device-write-bps possa ter efeito.

O resultado mostra que o limite de velocidade é de cerca de 5 MB / s. Como teste comparativo, se a velocidade não for limitada, os resultados são os seguintes.

[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

Insira a descrição da imagem aqui

Acho que você gosta

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