Como limitar o uso de CPU e RAM de um processo com cgroups no Ubuntu

No Ubuntu, a maneira mais segura de limitar a carga de trabalho com cgroups é deixar o systemd criar e gerenciar seu grupo de controle. Use ` systemd-run--limit` para um comando que você está iniciando agora ou configure um serviço do systemd quando o limite precisar persistir após reinicializações. Defina ` CPUQuota=--limit` para um limite máximo de tempo de CPU e escolha entre `--limit` MemoryHigh=para pressão e ` MemoryMax=--limit` para um limite máximo de memória. Esses limites se aplicam à unidade e seus processos filhos em conjunto.

Um cgroup (grupo de controle) é um mecanismo do kernel Linux que organiza processos para que o sistema possa contabilizar e controlar o uso de recursos. O systemd do Ubuntu já coloca os serviços em cgroups, portanto, a maioria dos usuários não precisa criar diretórios /sys/fs/cgroupmanualmente. Os exemplos abaixo usam a interface de controle de recursos do systemd e devem ser verificados em relação à versão do systemd instalada na sua distribuição Ubuntu.

Uma simulação de terminal no estilo Ubuntu que verifica a versão do systemd e o tipo de montagem cgroup2fs antes de definir os limites de recursos.
Exemplo ilustrativo de terminal para verificar o systemd e a montagem do cgroup v2. A versão e a saída exibidas são exemplos, não um resultado de teste.

Escolha o controle que corresponde ao problema.

MétodoO que ele controlaMelhor ajustePrincipal compensação
systemd-runescopo transitórioCotas de CPU e limites de memória para um comando recém-lançado e seus descendentes.Uma compilação, script, importação ou tarefa em lote única.O escopo é temporário e termina com a carga de trabalho; ele não se vincula a um processo arbitrário que já esteja em execução.
configurações do serviço systemdRecursos para o cgroup do serviço, incluindo processos filhos.Um daemon ou aplicativo que deve manter os mesmos limites após a reinicialização.Requer configuração de serviço e geralmente uma reinicialização para aplicar as novas configurações.
Arquivos cgroup v2 diretosControladores de nível de kernel, como cpu.maxememory.maxTempos de execução de contêineres, gerenciadores de cgroup delegados ou administração especializadaMais manual; o systemd controla grande parte da hierarquia do Ubuntu, e escrever em sua árvore gerenciada pode entrar em conflito com o systemd ou falhar devido a permissões e delegação.
niceouCPUWeight=Prioridade relativa da CPU quando grupos competemManter a prioridade do trabalho em segundo plano mais baixa, permitindo que ele utilize a CPU ociosa.Isso não representa um limite rígido de CPU e não limita a memória.

Para a maioria das máquinas Ubuntu interativas, um escopo transitório é a opção reversível mais rápida. Para um serviço de produção, use a unidade de serviço para que a política seja documentada e restaurada na inicialização. Use arquivos cgroup diretamente apenas quando estiver gerenciando deliberadamente uma hierarquia delegada ou criando um fluxo de trabalho de contêiner/runtime.

Verifique o sistema Ubuntu antes de definir limites.

Primeiro verifique se o systemd está disponível e se o sistema de arquivos cgroup é o Unified v2:

systemctl --version
stat -fc %T /sys/fs/cgroup

O resultado cgroup2fsdo segundo comando indica o sistema de arquivos cgroup v2 unificado. Versões do Ubuntu e sistemas personalizados podem diferir, portanto, não assuma que todas as máquinas tenham a mesma hierarquia ou recursos do systemd. Você também pode verificar a versão atual do systemd com o primeiro comando. Se a montagem do cgroup não for v2, algumas propriedades de recursos ou o comportamento do controlador podem ser diferentes; consulte a página do manual do Ubuntu para a versão instalada antes de copiar uma configuração.

Selecione os valores após medir a carga de trabalho. Deixe espaço para o restante do sistema e lembre-se de que os limites definidos em um serviço de usuário também são limitados por quaisquer limites em sua fatia pai. Um cgroup filho não pode receber mais recursos do que um ancestral permite.

Limitar um comando que você está prestes a iniciar

Para executar um comando na sua própria sessão de usuário, inicie-o em um escopo transitório com systemd-run --user --scope. Por exemplo:

Uma simulação de terminal no estilo Ubuntu, executando um processo Python com uma cota de CPU de 50% e limites de memória de 700 MB e 900 MB.
Exemplo ilustrativo de um terminal com um comando systemd-run único, contendo cota de CPU, limite de pressão de memória e teto rígido de memória.
systemd-run --user --scope --unit=worker-capped \
  -p CPUQuota=50% \
  -p MemoryHigh=700M \
  -p MemoryMax=900M \
  -- python3 /opt/worker.py

Substitua o comando Python pelo programa que você realmente precisa executar. Este exemplo define para o cgroup uma largura de banda máxima de CPU equivalente à metade de uma CPU, inicia o gerenciamento de pressão de memória em torno de 700 MiB e define um limite máximo de memória de 900 MiB. Os valores de memória usam unidades de base 1024 do systemd. Uma quota 100%representa o tempo equivalente a até uma CPU; 200%pode usar o equivalente a até duas CPUs quando disponíveis. Isso não significa uma porcentagem de todos os núcleos do computador.

O comando é executado em primeiro plano porque se trata de um escopo. Ao ser finalizado, a unidade transitória desaparece. Remova-a --usersomente se você pretende usar o gerenciador de sistema e possui os privilégios necessários; para uma unidade transitória em todo o sistema, execute o comando com sudoas opções apropriadas. As configurações de recursos podem ser rejeitadas se o gerenciador ou o controlador de cgroup não as suportarem.

Defina limites para um serviço systemd persistente.

Para um serviço como esse worker.service, crie um módulo de instalação em vez de editar o arquivo de unidade do fornecedor. Execute o comando sudo systemctl edit worker.servicee adicione:

Um modelo de configuração de serviço do systemd contendo as configurações CPUQuota, MemoryHigh e MemoryMax.
Exemplo de configuração de serviço systemd com controles persistentes de CPU e memória. Utilize o nome e os valores reais do serviço, adequados à sua carga de trabalho.
[Service]
CPUQuota=50%
MemoryHigh=700M
MemoryMax=900M

Salve o arquivo drop-in, recarregue as definições de unidade do systemd e reinicie o serviço para que o processo seja iniciado com a política revisada:

sudo systemctl daemon-reload
sudo systemctl restart worker.service

Use um limite de memória cauteloso. Se o serviço não conseguir recuperar memória suficiente abaixo de um determinado limite MemoryMax, o kernel poderá invocar o mecanismo de eliminação de processos por falta de memória dentro desse cgroup. Isso pode encerrar um ou mais processos no grupo de serviços e interromper o trabalho. Uma prática mais segura costuma ser definir o limite MemoryHighem um nível onde a recuperação e a limitação de memória sejam aceitáveis ​​e, em seguida, definir MemoryMaxum limite superior como limite final. Teste com cargas de pico realistas antes de implementar limites rígidos.

Verifique a unidade e observe seu comportamento.

Para o osciloscópio transiente, verifique o seu estado utilizando o nome da unidade que você forneceu:

Uma simulação de terminal mostrando o status do systemctl e o systemd-cgtop monitorando um escopo de carga de trabalho transitória.
Visualização ilustrativa do status e do monitor do cgroup. Os valores de CPU e memória mostrados aqui não são medições de uma execução real.
systemctl --user status worker-capped.scope
systemd-cgtop

Para um serviço do sistema, omita --usero comando de status. A visualização de status confirma que a unidade existe e está ativa; systemd-cgtopmostra o uso de recursos em tempo real por grupo de controle. Para inspecionar as propriedades configuradas, consulte a unidade diretamente, por exemplo:

systemctl --user show worker-capped.scope \
  -p CPUQuotaPerSecUSec -p MemoryHigh -p MemoryMax

A memória reportada para um cgroup não é necessariamente a mesma que a memória residente de um processo: ela contabiliza a memória alocada ao grupo e pode incluir os processos descendentes da carga de trabalho. Considere o monitoramento como evidência de como essa carga de trabalho se comporta ao longo do tempo, e não como um único número para otimização indiscriminada.

E se o processo já estiver em execução?

systemd-runInicia um novo comando dentro de uma nova unidade; não pega um PID existente arbitrário e o move para esse escopo. Se o processo pertencer a um serviço do systemd, aplique as configurações a esse serviço com um comando drop-in ou, para uma alteração temporária, use o comando `systemctl` sudo systemctl set-property --runtime worker.service CPUQuota=50% MemoryHigh=700M MemoryMax=900M. O --runtimeformato é temporário e não substitui uma configuração de serviço persistente.

Se o processo for um programa comum na sua sessão de desktop, o método mais seguro e simples geralmente é pará-lo e reiniciá-lo systemd-run. Aplicar uma propriedade a uma fatia mais ampla, como toda a sua fatia de usuário, pode afetar muitos aplicativos não relacionados. Mover um processo escrevendo seu PID em um arquivo cgroup requer controle da hierarquia delegada relevante e deve respeitar as regras de posicionamento de processos do cgroup v2; não escreva em diretórios gerenciados pelo systemd por tentativa e erro.

Como escolher uma política de CPU e memória

  • Precisa de um limite máximo rígido para o uso da CPU? Escolha CPUQuota=. Valores mais baixos reduzem o consumo máximo da CPU, mas podem tornar a conclusão mais lenta e aumentar o tempo de espera na fila.
  • Precisa apenas de prioridade mais baixa? Considere usar CPUWeight=uma alocação de CPU ponderada em vez de uma cota. A alocação ponderada distribui a CPU de forma relativa sob disputa; ela não reserva uma porcentagem fixa nem impede o uso de CPU ociosa.
  • Precisa de pressão na memória sem uma interrupção brusca imediata? Defina MemoryHigh=como o limite de pressão principal e observe a latência e o comportamento de recuperação.
  • Precisa de um limite de contenção final? Adicione MemoryMax=uma margem suficiente para picos normais. Esteja preparado para comportamentos de falta de memória (OOM) quando o limite não puder ser respeitado.
  • Já está usando um contêiner? Dê preferência aos parâmetros de CPU e memória suportados pelo gerenciador de contêineres, que configuram os cgroups para esse contêiner e se adequam ao seu ciclo de vida.

Não existe um limite ideal único para todas as cargas de trabalho. Um processo em lote em um computador pode tolerar uma cota baixa e um limite de memória moderado; um serviço sensível à latência pode precisar de mais espaço na CPU e um limite mais alto MemoryHighpara evitar pausas relacionadas à recuperação de memória. Comece com uma configuração conservadora, monitore o dispositivo durante um pico de uso representativo e ajuste uma configuração por vez.

Referências

Deixar um comentário

Baixe o FlightGear gratuitamente: Guia de Instalação Oficial

Baixe o FlightGear gratuitamente: Guia de Instalação Oficial

Baixe o FlightGear gratuitamente no site oficial. Compare os pacotes para Windows, macOS e Linux, instale os arquivos de dados e inicie seu primeiro voo.

Aplicativo Google Tasks para desktop: como usá-lo no computador

Aplicativo Google Tasks para desktop: como usá-lo no computador

Abra o Google Tasks em um navegador, adicione um atalho do Chrome ou inicie o aplicativo automaticamente e gerencie suas tarefas agendadas pelo Agenda e pelo Gmail.

OKSampler: Um sampler de música gratuito e simples para batidas de teclado.

OKSampler: Um sampler de música gratuito e simples para batidas de teclado.

O OKSampler mapeia trechos de MP3 para teclas do teclado e pode reproduzir áudio em loop. Saiba o que este software gratuito legado faz, onde terminam suas funcionalidades antigas e o que verificar antes de baixar.

Como instalar o Linux Mint Debian Edition 5 “Elsie” a partir de um pendrive USB

Como instalar o Linux Mint Debian Edition 5 “Elsie” a partir de um pendrive USB

Baixe e verifique a ISO arquivada do LMDE 5, crie um USB inicializável e escolha as configurações de instalação segura. O Elsie chegou ao fim de seu suporte; veja a versão atual do LMDE.

Como instalar o Wireshark no Linux: Ubuntu, Fedora, Arch e outras distribuições

Como instalar o Wireshark no Linux: Ubuntu, Fedora, Arch e outras distribuições

Instale o Wireshark no Ubuntu, Debian, Fedora, Arch ou openSUSE com os comandos de pacote atuais e, em seguida, configure a captura de pacotes em tempo real com segurança.

Como jogar Don't Starve Together no Linux

Como jogar Don't Starve Together no Linux

Instale a versão Linux de Don't Starve Together pelo Steam, crie um mundo ou junte-se a amigos seguindo estes passos de configuração e resolução de problemas.

Como jogar Squad no Linux com o Steam Proton

Como jogar Squad no Linux com o Steam Proton

Configure o Squad no Linux com o Steam Play e o Proton, instale o jogo, escolha uma ferramenta de compatibilidade e resolva problemas com o sistema anti-cheat.

Como criar uma unidade USB inicializável do Windows 11 no Linux

Como criar uma unidade USB inicializável do Windows 11 no Linux

Crie um pendrive de instalação do Windows 11 no Linux com o Ventoy: obtenha a ISO oficial, instale o Ventoy com segurança, copie a imagem e inicialize o computador de destino.

Como jogar DiRT Rally no Linux: Configuração do Steam e correções do Proton

Como jogar DiRT Rally no Linux: Configuração do Steam e correções do Proton

Aprenda a jogar DiRT Rally no Linux se você já o possui no Steam: instale a versão nativa, execute-o e use o Proton apenas como alternativa.

Como instalar o Devuan Linux a partir de um USB inicializável

Como instalar o Devuan Linux a partir de um USB inicializável

Instale o Devuan Excalibur a partir da ISO Live para desktop. Verifique o download, crie um USB inicializável, proteja as partições existentes e finalize a instalação com o Refracta Installer.