UPDATE: Observe que a resposta abaixo se aplica ao RHEL 6. No RHEL 7, a maioria dos cgroups é gerenciada pelo systemd e o libcgroup está obsoleto.
Desde a publicação desta pergunta, estudei o guia inteiro ao qual vinculei acima, bem como a maioria da documentação cgroups.txt e cpusets.txt . Agora eu sei mais do que eu esperava aprender sobre cgroups, então vou responder minha própria pergunta aqui.
Existem várias abordagens que você pode adotar. O contato de nossa empresa na Red Hat (arquiteto técnico) recomendou uma restrição geral de todos os processos, de preferência a uma abordagem mais declarativa - restringindo apenas os processos que queríamos especificamente restritos. A razão para isso, de acordo com suas declarações sobre o assunto, é que é possível que as chamadas do sistema dependam do código do espaço do usuário (como processos LVM) que, se restringido, poderia diminuir a velocidade do sistema - o oposto do efeito pretendido. Então acabei restringindo vários processos nomeados especificamente e deixando tudo o resto.
Além disso, quero mencionar alguns dados básicos do cgroup que estavam faltando quando postei minha pergunta.
Os Cgroups não dependem da libcgroup
instalação. No entanto, esse é um conjunto de ferramentas para lidar automaticamente com a configuração do cgroup e as atribuições de processo ao cgroups e pode ser muito útil.
Eu descobri que as ferramentas libcgroup também podem ser enganosas, porque o pacote libcgroup é construído em seu próprio conjunto de abstrações e suposições sobre o uso do cgroups, que são ligeiramente diferentes da implementação real do cgroups no nível do kernel. (Eu posso colocar exemplos, mas isso levaria algum trabalho; comente se você estiver interessado.)
Portanto, antes de usar ferramentas libcgroup (tais como /etc/cgconfig.conf
, /etc/cgrules.conf
, cgexec
, cgcreate
, cgclassify
, etc.) I altamente recomendável ficar muito familiarizado com o /cgroup
próprio sistema de arquivos virtual, e criando manualmente cgroups, hierarquias cgroup (incluindo hierarquias com vários subsistemas anexados, que libcgroup sneakily e resumos leakily ), reatribuindo processos a diferentes cgroups executando echo $the_pid > /cgroup/some_cgroup_hierarchy/a_cgroup_within_that_hierarchy/tasks
, e outras tarefas aparentemente mágicas que são libcgroup
executadas sob o capô.
Outro conceito básico que eu estava perdendo era que, se o /cgroup
sistema de arquivos virtual estiver montado no seu sistema (ou mais precisamente, se algum dos subsistemas cgroup, conhecido como "controladores", estiver montado)), todos os processos do sistema inteiro estarão em um cgroup. Não existe algo como "alguns processos estão em um cgroup e outros não".
Existe o que é chamado de cgroup raiz para uma determinada hierarquia, que possui todos os recursos do sistema para os subsistemas conectados. Por exemplo, uma hierarquia cgroup que possui os subsistemas cpuset e blkio conectados, teria um cgroup raiz que possuiria todos os cpus no sistema e todo o blkio no sistema e poderia compartilhar alguns desses recursos com os cgroups filhos . Você não pode restringir o cgroup raiz porque ele possui todos os recursos do seu sistema, portanto, restringi-lo nem faria sentido.
Alguns outros dados simples que estavam faltando sobre o libcgroup:
Se você usar /etc/cgconfig.conf
, verifique se o chkconfig --list cgconfig
programa cgconfig
está configurado para ser executado na inicialização do sistema.
Se você alterar /etc/cgconfig.conf
, precisará executar service cgconfig restart
para carregar as alterações. (E problemas com a interrupção do serviço ou a execução cgclear
são muito comuns quando se faz testes. Para depuração, recomendo, por exemplo lsof /cgroup/cpuset
, se cpuset
é o nome da hierarquia do cgroup que você está usando.)
Se você deseja usar /etc/cgrules.conf
, é necessário garantir que o "daemon do mecanismo de regras do cgroup" ( cgrulesengd
) esteja em execução: service cgred start
e chkconfig cgred on
. (E você deve estar ciente de uma condição de corrida possível, mas improvável, referente a este serviço, conforme descrito no Guia de Gerenciamento de Recursos Red Hat na seção 2.8.1 na parte inferior da página.)
Se você quiser brincar manualmente e configurar seus cgroups usando o sistema de arquivos virtual (que eu recomendo para o primeiro uso), você pode fazer isso e criar um cgconfig.conf
arquivo para espelhar sua configuração usando cgsnapshot
as várias opções.
E, finalmente, a principal informação que eu estava perdendo quando escrevi o seguinte:
No entanto, a advertência sobre isso parece ser ... que os filhos de myprocessname serão transferidos para o cgroup restrito de cpu0only.
Eu estava correto, mas há uma opção que eu desconhecia.
cgexec
é o comando para iniciar um processo / executar um comando e atribuí-lo a um cgroup.
cgclassify
é o comando para atribuir um processo já em execução a um cgroup.
Ambos também impedirão cgred
( cgrulesengd
) de reatribuir o processo especificado para um cgroup diferente com base em /etc/cgrules.conf
.
Ambos cgexec
e cgclassify
apoiar a --sticky
bandeira, que além disso impede cgred
de reatribuição criança processos com base em /etc/cgrules.conf
.
Portanto, a resposta para a pergunta que eu escrevi (embora não seja a configuração que acabei implementando, devido aos conselhos do nosso Red Hat Technical Architect mencionado acima) é:
Faça o cpu0only
e anycpu
cgroup conforme descrito na minha pergunta. (Verifique se cgconfig
está definido para ser executado na inicialização.)
Faça a * cpuset cpu0only
regra como descrito na minha pergunta. (E verifique se cgred
está configurado para ser executado na inicialização.)
Iniciar qualquer processo que eu quero sem restrições com: cgexec -g cpuset:anycpu --sticky myprocessname
.
Esses processos serão irrestritos e todos os seus processos filhos também serão irrestritos. Todo o resto do sistema será restrito à CPU 0 (uma vez que você reinicia, pois cgred
não aplica o cgrules a processos já em execução, a menos que eles alterem seu EUID). Isso não é totalmente aconselhável, mas foi o que solicitei inicialmente e isso pode ser feito com os cgroups.