Como criar um usuário com uso limitado de RAM?

Como criar um usuário com uso limitado de RAM?

Portanto, tenho 4 GB de RAM + 4 GB de troca. Quero criar um usuário com memória RAM e swap limitados: 3 GB de RAM e 1 GB de swap. Isso é possível? É possível iniciar aplicativos com RAM limitada e trocar disponíveis para eles sem criar um usuário separado (e sem instalar nenhum aplicativo especial - tendo apenas uma configuração de servidor Debian/CentOS padrão e sem usar o sudo)?

Atualizar:

Então eu abri o terminal e digitei nelelimitecomando: ulimit -v 1000000que será como 976,6Mblimitação. Em seguida liguei ulimit -ae vi que a limitação está "ativada". Então comecei um script bash que compila e inicia meu aplicativo em nohupumlongo nohup ./cloud-updater-linux.sh >& /dev/null &... mas depois de algum tempo eu vi:

insira a descrição da imagem aqui

(o que seria bom se nenhuma limitação fosse aplicada - ele baixou uma biblioteca grande e começou a compilá-la.)

Mas pensei ter aplicado limitações ao shell e a todos os processos iniciados com/a partir dele com ulimit -v 1000000? O que eu errei? Como fazer com que um terminal e todos os subprocessos que ele inicia sejam limitados no uso de memória RAM?

Responder1

ulimité feito para isso. Você pode configurar padrões ulimitpor usuário ou por grupo em

/etc/security/limits.conf

ulimit -v KBYTESdefine o tamanho máximo da memória virtual. Não acho que você possa dar um valor máximo de troca. É apenas um limite na quantidade de memória virtual que o usuário pode usar.

Então você limits.confteria a linha (no máximo de 4Gmemória)

luser  hard  as   4000000

ATUALIZAÇÃO - Grupos CG

Os limites impostos por ulimite limits.confsão por processo. Eu definitivamente não estava claro nesse ponto.

Se você deseja limitar a quantidade total de memória que um usuário usa (que foi o que você pediu). Você quer usargrupos.

Em /etc/cgconfig.conf:

group memlimit {
    memory {
        memory.limit_in_bytes = 4294967296;
    }
}

Isso cria um cgroupque tem um limite máximo de memória de 4GiB.

Em /etc/cgrules.conf:

luser   memory   memlimit/

Isso fará com que todos os processos executados lusersejam executados dentro dos memlimitcgroups criados em cgconfig.conf.

Responder2

cgroupssão a maneira certa de fazer isso, como outras respostas apontaram. Infelizmente não existe uma solução perfeita para o problema, como veremos a seguir. Existem várias maneiras diferentes de definir limites de uso de memória do cgroup. A forma de tornar a sessão de login de um usuário automaticamente parte de um cgroup varia de sistema para sistema. chapéu vermelhotem algumas ferramentas, e tambémsistema.

memory.memsw.limit_in_bytese memory.limit_in_bytesestabelecer limites incluindo e não incluindo swap, respectivamente. A desvantagem memory.limit_in_bytesé que ele conta os arquivos armazenados em cache pelo kernel em nome dos processos no cgroup em relação à cota do grupo. Menos cache significa mais acesso ao disco, então você está potencialmente desistindo de algum desempenho se o sistema tiver alguma memória disponível.

Por outro lado, memory.soft_limit_in_bytespermite que o cgroup ultrapasse a cota, mas se o assassino OOM do kernel for invocado, então os cgroups que ultrapassarem suas cotas serão eliminados primeiro, logicamente. A desvantagem disso, entretanto, é que há situações em que alguma memória é necessária imediatamente e não há tempo para o assassino OOM procurar processos para matar, caso em que algo pode falhar antes que os processos do usuário acima da cota sejam eliminados. morto.

ulimit, no entanto, é absolutamente a ferramenta errada para isso. ulimit impõe limites ao uso da memória virtual, o que quase certamente não é o que você deseja. Muitos aplicativos do mundo real usam muito mais memória virtual do que memória física. A maioria dos tempos de execução com coleta de lixo (Java, Go) funciona dessa maneira para evitar fragmentação. Um programa trivial "olá mundo" em C, se compilado com o desinfetante de endereço, pode usar 20 TB de memória virtual. Alocadores que não dependem de sbrk, comojemalloc(que é o alocador padrão para Rust) outcmalloc, também terão um uso de memória virtual substancialmente superior ao uso físico. Para maior eficiência, muitas ferramentas mapeiam arquivos, o que aumenta o uso virtual, mas não necessariamente o uso físico. Todos os meus processos do Chrome usam 2 TB de memória virtual cada. Estou em um laptop com 8 GB de memória física. Qualquer maneira que alguém tentasse configurar cotas de memória virtual aqui quebraria o Chrome, forçaria o Chrome a desabilitar alguns recursos de segurança que dependem da alocação (mas não do uso) de grandes quantidades de memória virtual ou seria completamente ineficaz na prevenção de um usuário abusar do sistema .

Responder3

Você não pode limitar o uso de memória no nível do usuário; o ulimit pode fazer isso, mas para um único processo.

Mesmo usando limites por usuário /etc/security/limits.conf, um usuário pode usar toda a memória executando vários processos.

Se você realmente deseja limitar os recursos, você precisa usar uma ferramenta de gerenciamento de recursos, comorcapdusado por projetos e zonas no Solaris.

Há algo que parece fornecer recursos semelhantes no Linux que você pode investigar:grupos.

Responder4

No sistema com systemd (por exemplo, Ubuntu 22.04 que estou usando), a maneira mais simples de restringir CPU/memória é usar arquivos de configuração systemd cgroups, por exemplo, para restringir 4 GB de RAM e 2 threads:

nano /etc/systemd/system/user-.slice.d/50-memory.conf

E escreva nesse arquivo:

[Slice]
MemoryMax=4G
CPUQuota=200%

(corre então systemctl daemon-reloadpara aplicar)

Isso se aplica a todos os usuários, mas você pode substituir usuários individuais em/etc/systemd/system/user-[uid].slice.d/50-memory.conf

(Acho que o nome do arquivo conf não importa, mas não tenho certeza)

informação relacionada