Observação:
- Este tutorial está disponível em um ambiente de laboratório gratuito fornecido pela Oracle.
- Ele usa valores de exemplo para credenciais, tenancy e compartimentos do Oracle Cloud Infrastructure. Ao concluir seu laboratório, substitua esses valores por valores específicos do seu ambiente de nuvem.
Executar Grupos de Controle Versão 2 no Oracle Linux
Introdução
Control Groups (cgroups) é um recurso do kernel Linux para limitar, priorizar e alocar recursos como tempo de CPU, memória e largura de banda de rede para executar processos.
Este tutorial o orienta durante a limitação do tempo de CPU para processos do usuário usando cgroups v2.
Objetivos
Neste laboratório, você aprenderá a:
- Ativar cgroups v2
- Definir um limite de CPU flexível para um processo do usuário
- Definir um limite de CPU rígido para um processo do usuário
Pré-requisitos
- Um sistema com o Oracle Linux 8 instalado com a seguinte configuração:
- um usuário não raiz com permissões
sudo
- um usuário não raiz com permissões
Configurar Ambiente de Laboratório
Observação: Ao usar o ambiente de laboratório gratuito, consulte Informações Básicas sobre o Oracle Linux Lab para obter instruções de conexão e outras instruções de uso.
Antes de começar a trabalhar com o laboratório, precisamos completar alguns itens de governança. Os itens criados são usados para demonstrar as capacidades de limitação de cgroups.
Criar script de geração de carregamento
-
Se ainda não estiver conectado, abra um terminal e conecte via ssh ao sistema ol8-server.
ssh oracle@<ip_address_of_ol8-server> -
Crie o script
foo.exe.echo '#!/bin/bash /usr/bin/sha1sum /dev/zero' > foo.exe -
Copie o script
foo.exepara um local em$PATHe defina as permissões adequadas.sudo mv foo.exe /usr/local/bin/foo.exe sudo chown root:root /usr/local/bin/foo.exe sudo chmod 755 /usr/local/bin/foo.exeObservação: (Opcional) Se estiver executando com o SELinux
enforcing:sudo sestatusCorrija os labels do SELinux após copiar e alterar permissões executando o seguinte comando:
sudo /sbin/restorecon -v /usr/local/bin/foo.exe
Criar serviço que gera carga
-
Crie o arquivo
foo.service.echo '[Unit] Description=the foo service After=network.target [Service] ExecStart=/usr/local/bin/foo.exe [Install] WantedBy=multi-user.target' > foo.service -
Copie o script
foo.servicepara onde os scripts systemd estão localizados e defina as permissões adequadas.sudo mv foo.service /etc/systemd/system/foo.service sudo chown root:root /etc/systemd/system/foo.service sudo chmod 644 /etc/systemd/system/foo.serviceObservação: (Opcional) Se estiver executando com o SELinux
enforcing, corrija os labels do SELinux após copiar e alterar permissões executando o seguinte comando:sudo /sbin/restorecon -v /etc/systemd/system/foo.service -
Recarregue o daemon; portanto, systemd reconhece o novo serviço.
sudo systemctl daemon-reload -
Inicie
foo.servicee verifique seu status.sudo systemctl start foo.service sudo systemctl status foo.service
Criar usuários
Usuários adicionais permitirão a execução do script de geração de carga nessas diferentes contas e pesos diferentes da CPU.
-
Crie usuários e defina senhas.
sudo useradd -u 8000 ralph sudo useradd -u 8001 alice echo "ralph:oracle" | sudo chpasswd echo "alice:oracle" | sudo chpasswd -
Permitir conexões SSH.
Copie a chave SSH da conta de usuário
oracle.sudo mkdir /home/ralph/.ssh sudo cp /home/oracle/.ssh/authorized_keys /home/ralph/.ssh/authorized_keys sudo chown -R ralph:ralph /home/ralph/.ssh sudo chmod 700 /home/ralph/.ssh sudo chmod 600 /home/ralph/.ssh/authorized_keys -
Repita para o usuário
alice.sudo mkdir /home/alice/.ssh sudo cp /home/oracle/.ssh/authorized_keys /home/alice/.ssh/authorized_keys sudo chown -R alice:alice /home/alice/.ssh sudo chmod 700 /home/alice/.ssh sudo chmod 600 /home/alice/.ssh/authorized_keys -
Abra um novo terminal e verifique se as duas conexões SSH funcionam.
ssh ralph@<ip_address_of_ol8-server>Em seguida,
exita sessão e repita para o usuário a seguir.ssh alice@<ip_address_of_ol8-server>Saia da sessão e feche a janela do terminal.
Montar cgroups v2
O Oracle Linux monta os cgroups v1 por padrão no momento da inicialização. Para utilizar cgroups v2, é necessário configurar manualmente os parâmetros do kernel de inicialização.
-
Retorne ao terminal no qual você está conectado como
oracle. -
Adicione o parâmetro kernel systemd v2 cgroups.
sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=1"Em vez disso, é possível especificar somente a entrada de inicialização atual executando
sudo grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="systemd.unified_cgroup_hierarchy=1". -
Reinicialize.
sudo rebootA reinicialização levará alguns minutos.
Observação: Você não poderá ssh para o sistema até que a reinicialização seja concluída e o daemon sshd esteja em execução.
-
Conecte-se novamente via ssh ao sistema ol8-server.
ssh oracle@<ip_address_of_ol8-server> -
Verifique se o cgroups v2 foi montado.
sudo mount -l | grep cgroupExemplo de saída:
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,seclabel,nsdelegate) -
Inspecione o conteúdo do diretório montado de cgroups.
ll /sys/fs/cgroupExemplo de saída:
total 0 -r--r--r--. 1 root root 0 Mar 13 21:20 cgroup.controllers -rw-r--r--. 1 root root 0 Mar 13 21:20 cgroup.max.depth -rw-r--r--. 1 root root 0 Mar 13 21:20 cgroup.max.descendants -rw-r--r--. 1 root root 0 Mar 13 21:20 cgroup.procs -r--r--r--. 1 root root 0 Mar 13 21:20 cgroup.stat -rw-r--r--. 1 root root 0 Mar 13 21:20 cgroup.subtree_control -rw-r--r--. 1 root root 0 Mar 13 21:20 cgroup.threads -rw-r--r--. 1 root root 0 Mar 13 21:20 cpu.pressure -r--r--r--. 1 root root 0 Mar 13 21:20 cpuset.cpus.effective -r--r--r--. 1 root root 0 Mar 13 21:20 cpuset.mems.effective drwxr-xr-x. 2 root root 0 Mar 13 21:20 init.scope -rw-r--r--. 1 root root 0 Mar 13 21:20 io.pressure -rw-r--r--. 1 root root 0 Mar 13 21:20 memory.pressure drwxr-xr-x. 87 root root 0 Mar 13 21:20 system.slice drwxr-xr-x. 4 root root 0 Mar 13 21:24 user.sliceA saída mostra o grupo de controle de raiz em seu local padrão. O diretório contém arquivos de interface prefixados com cgroup e diretórios relacionados a
systemdque terminam em.scopee.slice.
Trabalhar com o Virtual File System
Antes de começarmos, precisamos saber um pouco sobre o sistema de arquivos virtual cgroups montado em /sys/fs/cgroup.
-
Mostre quais CPUs participam do cpuset para todos.
cat /sys/fs/cgroup/cpuset.cpus.effectiveExemplo de saída:
[oracle@ol8-server ~]$ cat /sys/fs/cgroup/cpuset.cpus.effective 0-1Nossa caixa de teste era uma instância do Oracle Linux 8 implantada em uma forma VM.Standard2.1, que é um sistema dual-core.
-
Mostrar quais controladores estão ativos.
cat /sys/fs/cgroup/cgroup.controllersExemplo de saída:
[oracle@ol8-server ~]$ cat /sys/fs/cgroup/cgroup.controllers cpuset cpu io memory pids rdmaÉ bom ver o controlador do cpuset presente, pois o usaremos posteriormente neste laboratório.
-
Mostrar processos gerados por
oracle.Primeiro, precisamos determinar o ID de usuário (UID) do
oracle.who idExemplo de saída:
[oracle@ol8-server ~]$ who oracle pts/0 2022-03-13 21:23 (10.39.209.157) [oracle@ol8-server ~]$ id uid=1001(oracle) gid=1001(oracle) groups=1001(oracle),10(wheel) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023Usando o UID, podemos encontrar a fatia de usuários
oracle.cd /sys/fs/cgroup/user.slice lsExemplo de saída:
[oracle@ol8-server ~]$ cd /sys/fs/cgroup/user.slice [oracle@ol8-server user.slice]$ ls cgroup.controllers cgroup.subtree_control memory.events memory.pressure pids.max cgroup.events cgroup.threads memory.events.local memory.stat user-0.slice cgroup.freeze cgroup.type memory.high memory.swap.current user-1001.slice cgroup.max.depth cpu.pressure memory.low memory.swap.events user-989.slice cgroup.max.descendants cpu.stat memory.max memory.swap.max cgroup.procs io.pressure memory.min pids.current cgroup.stat memory.current memory.oom.group pids.eventsSystemd atribui a cada usuário uma fatia chamada
user-<UID>.slice. O que há nesse diretório?cd user-1001.slice lsExemplo de saída:
[oracle@ol8-server user.slice]$ cd user-1001.slice/ [oracle@ol8-server user-1001.slice]$ ls cgroup.controllers cgroup.max.descendants cgroup.threads io.pressure user-runtime-dir@1001.service cgroup.events cgroup.procs cgroup.type memory.pressure cgroup.freeze cgroup.stat cpu.pressure session-3.scope cgroup.max.depth cgroup.subtree_control cpu.stat user@1001.serviceEsses são os cgroups de nível superior para o usuário
oracle. No entanto, não há processos listados emcgroup.procs. Então, onde está a lista de processos do usuário?cat cgroup.procsExemplo de saída:
[oracle@ol8-server user-1001.slice]$ cat cgroup.procs [oracle@ol8-server user-1001.slice]$Quando
oracleabriu a sessão SSH no início deste laboratório, a sessão de usuário criou uma subunidade de escopo. Sob esse escopo, podemos verificarcgroup.procspara obter uma lista de processos gerados nessa sessão.Observação: O usuário pode ter várias sessões com base no número de conexões com o sistema; portanto, substitua o 3 na amostra abaixo conforme necessário.
cd session-3.scope ls cat cgroup.procsExemplo de saída:
[oracle@ol8-server user-1001.slice]$ cd session-3.scope/ [oracle@ol8-server session-3.scope]$ ls cgroup.controllers cgroup.max.depth cgroup.stat cgroup.type io.pressure cgroup.events cgroup.max.descendants cgroup.subtree_control cpu.pressure memory.pressure cgroup.freeze cgroup.procs cgroup.threads cpu.stat [oracle@ol8-server session-3.scope]$ cat cgroup.procs 3189 3200 3201 54217Agora que encontramos os processos da maneira difícil, podemos usar
systemd-cglspara mostrar as mesmas informações em uma exibição em árvore.Observação: Quando executado de dentro do sistema de arquivos virtual,
systemd-cglslimita a saída cgroup ao diretório de trabalho atual.cd /sys/fs/cgroup/user.slice/user-1001.slice systemd-cglsExemplo de saída:
[oracle@ol8-server user-1001.slice]$ systemd-cgls Working directory /sys/fs/cgroup/user.slice/user-1001.slice: ├─session-3.scope │ ├─ 3189 sshd: oracle [priv] │ ├─ 3200 sshd: oracle@pts/0 │ ├─ 3201 -bash │ ├─55486 systemd-cgls │ └─55487 less └─user@1001.service └─init.scope ├─3193 /usr/lib/systemd/systemd --user └─3195 (sd-pam)
Limitar os Núcleos de CPU Usados
Com os cgroups v2, systemd tem controle total do controlador de cpuset. Esse nível de controle permite que um administrador programe trabalhos apenas em um núcleo de CPU específico.
-
Verifique as CPUs para
user.slice.cd /sys/fs/cgroup/user.slice ls cat ../cpuset.cpus.effectiveExemplo de saída:
[oracle@ol8-server cgroup]$ cd /sys/fs/cgroup/user.slice/ [oracle@ol8-server user.slice]$ ls cgroup.controllers cgroup.subtree_control memory.events memory.pressure pids.max cgroup.events cgroup.threads memory.events.local memory.stat user-0.slice cgroup.freeze cgroup.type memory.high memory.swap.current user-1001.slice cgroup.max.depth cpu.pressure memory.low memory.swap.events user-989.slice cgroup.max.descendants cpu.stat memory.max memory.swap.max cgroup.procs io.pressure memory.min pids.current cgroup.stat memory.current memory.oom.group pids.events [oracle@ol8-server user.slice]$ cat ../cpuset.cpus.effective 0-1O
cpuset.cpus.effectivemostra os núcleos reais usados pelo user.slice. Se o parâmetro não existir no diretório cgroup específico, ou não o definimos, o valor será herdado do pai, que acontece ser o diretório raiz cgroup de nível superior para esse caso. -
Restrinja as fatias
systeme usuário 0, 1001 e 989 ao núcleo de CPU 0.cat /sys/fs/cgroup/system.slice/cpuset.cpus.effective sudo systemctl set-property system.slice AllowedCPUs=0 cat /sys/fs/cgroup/system.slice/cpuset.cpus.effectiveExemplo de saída:
[oracle@ol8-server user.slice]$ cat /sys/fs/cgroup/system.slice/cpuset.cpus.effective cat: /sys/fs/cgroup/system.slice/cpuset.cpus.effective: No such file or directory [oracle@ol8-server user.slice]$ sudo systemctl set-property system.slice AllowedCPUs=0 [oracle@ol8-server user.slice]$ cat /sys/fs/cgroup/system.slice/cpuset.cpus.effective 0Observação: O
No such file or directoryindica que, por padrão, a fatiasystemherda seu valorcpuset.cpus.effectivedo pai.sudo systemctl set-property user-0.slice AllowedCPUs=0 sudo systemctl set-property user-1001.slice AllowedCPUs=0 sudo systemctl set-property user-989.slice AllowedCPUs=0 -
Restrinja o usuário
ralphao núcleo de CPU 1.sudo systemctl set-property user-8000.slice AllowedCPUs=1 cat /sys/fs/cgroup/user.slice/user-8000.slice/cpuset.cpus.effectiveExemplo de saída:
[oracle@ol8-server ~]$ sudo systemctl set-property user-8000.slice AllowedCPUs=1 [oracle@ol8-server ~]$ cat /sys/fs/cgroup/user.slice/user-8000.slice/cpuset.cpus.effective 1 -
Abra um novo terminal e conecte via ssh como
ralphao sistema ol8-server.ssh ralph@<ip_address_of_ol8-server> -
Teste usando o script
foo.exe.foo.exe &Verifique os resultados.
topUma vez que
topesteja em execução, pressione1 keypara mostrar as CPUs individualmente.Exemplo de saída:
top - 18:23:55 up 21:03, 2 users, load average: 1.03, 1.07, 1.02 Tasks: 155 total, 2 running, 153 sleeping, 0 stopped, 0 zombie %Cpu0 : 6.6 us, 7.0 sy, 0.0 ni, 84.8 id, 0.0 wa, 0.3 hi, 0.3 si, 1.0 st %Cpu1 : 93.0 us, 6.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.7 hi, 0.3 si, 0.0 st MiB Mem : 14707.8 total, 13649.1 free, 412.1 used, 646.6 buff/cache MiB Swap: 4096.0 total, 4096.0 free, 0.0 used. 13993.0 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 226888 ralph 20 0 228492 1808 1520 R 99.7 0.0 199:34.27 sha1sum 269233 root 20 0 223724 6388 1952 S 1.3 0.0 0:00.04 pidstat 1407 root 20 0 439016 41116 39196 S 0.3 0.3 0:17.81 sssd_nss 1935 root 20 0 236032 3656 3156 S 0.3 0.0 0:34.34 OSWatcher 2544 root 20 0 401900 40292 9736 S 0.3 0.3 0:10.62 ruby 1 root 20 0 388548 14716 9508 S 0.0 0.1 0:21.21 systemd ...Digite
qpara sair do topo. -
Forma alternativa de verificar o processador que está executando um processo.
ps -eo pid,psr,user,cmd | grep ralphExemplo de saída:
[ralph@ol8-server ~]$ ps -eo pid,psr,user,cmd | grep ralph 226715 1 root sshd: ralph [priv] 226719 1 ralph /usr/lib/systemd/systemd --user 226722 1 ralph (sd-pam) 226727 1 ralph sshd: ralph@pts/2 226728 1 ralph -bash 226887 1 ralph /bin/bash /usr/local/bin/foo.exe 226888 1 ralph /usr/bin/sha1sum /dev/zero 269732 1 ralph ps -eo pid,psr,user,cmd 269733 1 ralph grep --color=auto ralphA coluna
psré o número da CPU docmdou o processo real. -
Saia e feche a janela do terminal usada para fazer log-in como
ralph. -
Elimine o job
foo.exe.Alterne de volta para o terminal no qual você está conectado como
oraclee execute o comando a seguir.sudo pkill sha1sum
Ajustar o peso da CPU para usuários
Hora de associar alice à diversão. Ela tem algum trabalho crítico a ser concluído, e portanto, daremos a ela duas vezes a prioridade normal na CPU.
-
Designe
aliceà mesma CPU queralph.sudo systemctl set-property user-8001.slice AllowedCPUs=1 cat /sys/fs/cgroup/user.slice/user-8001.slice/cpuset.cpus.effective -
Defina
CPUWeight.sudo systemctl set-property user-8001.slice CPUWeight=200 cat /sys/fs/cgroup/user.slice/user-8001.slice/cpu.weightO peso padrão é 100, portanto, 200 é o dobro desse número.
-
Abra um novo terminal e conecte via ssh como
ralphao sistema ol8-server.ssh ralph@<ip_address_of_ol8-server> -
Execute
foo.execomoralph.foo.exe & -
Abra outro novo terminal e conecte via ssh como
aliceao sistema ol8-server.ssh alice@<ip_address_of_ol8-server> -
Execute
foo.execomoalice.foo.exe & -
Verifique, por meio de
top, sealiceestá obtendo a prioridade mais alta.topUma vez executado o topo, pressione
1 keypara mostrar as CPUs individualmente.Exemplo de saída:
top - 20:10:55 up 25 min, 3 users, load average: 1.29, 0.46, 0.20 Tasks: 164 total, 3 running, 161 sleeping, 0 stopped, 0 zombie %Cpu0 : 0.0 us, 0.0 sy, 0.0 ni, 96.5 id, 0.0 wa, 0.0 hi, 3.2 si, 0.3 st %Cpu1 : 92.4 us, 7.6 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st MiB Mem : 15715.8 total, 14744.6 free, 438.5 used, 532.7 buff/cache MiB Swap: 4096.0 total, 4096.0 free, 0.0 used. 15001.1 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 7934 alice 20 0 15800 1768 1476 R 67.0 0.0 0:36.15 sha1sum 7814 ralph 20 0 15800 1880 1592 R 33.3 0.0 0:34.60 sha1sum 1 root 20 0 388476 14440 9296 S 0.0 0.1 0:02.22 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd ... -
Retorne ao terminal conectado como o usuário
oracle. -
Carregue o
system.sliceusando ofoo.service.sudo systemctl start foo.serviceVeja agora a saída superior ainda em execução na janela do terminal
alice. Veja quefoo.serviceestá consumindo a CPU 0, enquanto os usuários dividem a CPU 1 com base em seus pesos.Exemplo de saída:
top - 19:18:15 up 21:57, 3 users, load average: 2.15, 2.32, 2.25 Tasks: 159 total, 4 running, 155 sleeping, 0 stopped, 0 zombie %Cpu0 : 89.1 us, 7.3 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.7 hi, 0.3 si, 2.6 st %Cpu1 : 93.7 us, 5.3 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.7 hi, 0.3 si, 0.0 st MiB Mem : 14707.8 total, 13640.1 free, 420.5 used, 647.2 buff/cache MiB Swap: 4096.0 total, 4096.0 free, 0.0 used. 13984.3 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 280921 root 20 0 228492 1776 1488 R 93.4 0.0 0:07.74 sha1sum 279185 alice 20 0 228492 1816 1524 R 65.6 0.0 7:35.18 sha1sum 279291 ralph 20 0 228492 1840 1552 R 32.8 0.0 7:00.30 sha1sum 2026 oracle-+ 20 0 935920 29280 15008 S 0.3 0.2 1:03.31 gomon 1 root 20 0 388548 14716 9508 S 0.0 0.1 0:22.30 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.10 kthreadd ...
Designar uma Cota de CPU
Por fim, limitaremos o tempo de CPU para ralph.
-
Retorne ao terminal conectado como o usuário
oracle. -
Defina a cota como 5%
sudo systemctl set-property user-8000.slice CPUQuota=5%A alteração entra em vigor imediatamente, conforme visto na saída superior ainda em execução no terminal do usuário
alice.Exemplo de saída:
top - 19:24:53 up 22:04, 3 users, load average: 2.21, 2.61, 2.45 Tasks: 162 total, 4 running, 158 sleeping, 0 stopped, 0 zombie %Cpu0 : 93.0 us, 4.7 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.7 hi, 0.0 si, 1.7 st %Cpu1 : 91.7 us, 5.6 sy, 0.0 ni, 0.0 id, 0.0 wa, 1.0 hi, 1.0 si, 0.7 st MiB Mem : 14707.8 total, 13639.4 free, 420.0 used, 648.4 buff/cache MiB Swap: 4096.0 total, 4096.0 free, 0.0 used. 13984.7 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 280921 root 20 0 228492 1776 1488 R 97.4 0.0 6:26.75 sha1sum 279185 alice 20 0 228492 1816 1524 R 92.1 0.0 12:21.12 sha1sum 279291 ralph 20 0 228492 1840 1552 R 5.3 0.0 8:44.84 sha1sum 1 root 20 0 388548 14716 9508 S 0.0 0.1 0:22.48 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.10 kthreadd ... -
Reverta o limite no usuário
ralphusando a janela de terminaloracle.
echo "max 100000" | sudo tee -a user-8000.slice/cpu.max
A cota é gravada no arquivo cpu.max e os padrões são max 100000.
Exemplo de saída:
[oracle@ol8-server user.slice]$ echo "max 100000" | sudo tee -a user-8000.slice/cpu.max max 100000
Você pode ativar cgroups v2, limitar os usuários a uma CPU específica quando o sistema estiver sob carga e bloqueá-los para usar apenas um percentual dessa CPU. Confira outros recursos para saber mais sobre o Oracle Linux.
Para Obter Mais Informações
Consulte outros recursos relacionados:
Mais Recursos de Aprendizagem
Explore outros laboratórios em docs.oracle.com/learn ou acesse mais conteúdo de aprendizado gratuito no canal YouTube do Oracle Learning. Além disso, visite education.oracle.com/learning-explorer para se tornar um Oracle Learning Explorer.
Para obter a documentação do produto, visite o Oracle Help Center.
Run Control Groups Version 2 on Oracle Linux
F54929-01
March 2022
Copyright © 2022, Oracle and/or its affiliates.