web-dev-qa-db-fra.com

Comment créer un utilisateur avec une utilisation limitée RAM?

J'ai donc 4 Go RAM + 4 Go de swap. Je veux créer un utilisateur avec un ram et un swap limités: 3 Go RAM et 1 Go de swap. Est-ce que Est-il possible de démarrer des applications avec RAM et swap disponibles sans créer un utilisateur séparé (et sans installer aucune application spéciale - ayant juste une configuration de serveur Debian/CentOS par défaut, et n'utilise pas Sudo)?

Mise à jour:

J'ai donc ouvert le terminall et l'ai tapé limit commande: ulimit -v 1000000 qui sera comme 976,6Mb limitation. Ensuite, j'ai appelé ulimit -a et j'ai vu que la limitation est "activée". Ensuite, j'ai commencé un script bash qui compile et démarre mon application dans Nohup, un long oneNohup ./cloud-updater-linux.sh >& /dev/null &... mais après un certain temps j'ai vu:

enter image description here

(ce qui serait correct si aucune limitation n'était appliquée - il a téléchargé une grande bibliothèque et a commencé à la compiler.)

Mais je pensais que j'appliquais des limitations au shell et à tous les processus lancés avec/depuis celui-ci avec ulimit -v 1000000? Qu'est-ce que je me suis trompé? Comment faire pour qu'un terminal et tous les sous-processus qu'il lance soient limités sur l'utilisation du ram?

48
myWallJSON

ulimit est fait pour cela. Vous pouvez configurer les valeurs par défaut pour ulimit par utilisateur ou par groupe dans

/etc/security/limits.conf

ulimit -v KBYTES définit la taille maximale de la mémoire virtuelle. Je ne pense pas que vous puissiez donner un maximum de swap. C'est juste une limite sur la quantité de mémoire virtuelle que l'utilisateur peut utiliser.

Alors vous limits.conf aurait la ligne (jusqu'à un maximum de 4G de mémoire)

luser  hard  as   4000000

MISE À JOUR - CGroupes

Les limites imposées par ulimit et limits.conf est par processus. Je n'étais définitivement pas clair sur ce point.

Si vous souhaitez limiter la quantité totale de mémoire utilisée par les utilisateurs (c'est ce que vous avez demandé). Vous souhaitez utiliser cgroups .

Dans /etc/cgconfig.conf:

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

Cela crée un cgroup qui a une limite de mémoire maximale de 4 Go.

Dans /etc/cgrules.conf:

luser   memory   memlimit/

Cela entraînera l'exécution de tous les processus exécutés par luser à l'intérieur des groupes de contrôle memlimit créés dans cgconfig.conf.

67
utopiabound

cgroups sont la bonne façon de procéder, comme l'ont souligné d'autres réponses. Malheureusement, il n'y a pas de solution parfaite au problème, comme nous le verrons ci-dessous. Il existe différentes façons de définir les limites d'utilisation de la mémoire de cgroup. La façon dont on fait pour que la session de connexion d'un utilisateur fasse automatiquement partie d'un groupe de contrôle varie d'un système à l'autre. Red Hat possède quelques outils, tout comme systemd .

memory.memsw.limit_in_bytes et memory.limit_in_bytes définir des limites, y compris et non compris le swap, respectivement. Le mauvais côté memory.limit_in_bytes est qu'il compte les fichiers mis en cache par le noyau pour le compte des processus du groupe de contrôle par rapport au quota du groupe. Moins de mise en cache signifie plus d'accès au disque, donc vous risquez de perdre certaines performances si le système avait autrement de la mémoire disponible.

D'autre part, memory.soft_limit_in_bytes permet au groupe de contrôle de dépasser le quota, mais si le tueur OOM du noyau est invoqué, les groupes de contrôle qui dépassent leurs quotas sont supprimés en premier, logiquement. L'inconvénient de cela, cependant, est qu'il y a des situations où de la mémoire est nécessaire immédiatement et qu'il n'y a pas de temps pour que le tueur OOM recherche les processus à tuer, auquel cas quelque chose pourrait échouer avant que les processus de l'utilisateur hors quota ne soient tué.

ulimit, cependant, n'est absolument pas le bon outil pour cela. ulimit limite l'utilisation de la mémoire virtuelle, ce qui n'est certainement pas ce que vous voulez. De nombreuses applications du monde réel utilisent beaucoup plus de mémoire virtuelle que de mémoire physique. La plupart des runtimes récupérés (Java, Go) fonctionnent de cette façon pour éviter la fragmentation. Un programme trivial "bonjour le monde" en C, s'il est compilé avec un désinfectant d'adresse, peut utiliser 20 To de mémoire virtuelle. Les allocateurs qui ne dépendent pas de sbrk, tels que jemalloc (qui est l'allocateur par défaut pour Rust) ou tcmalloc , auront également une utilisation de mémoire virtuelle substantiellement dans excès de leur utilisation physique. Pour plus d'efficacité, de nombreux outils mapperont les fichiers, ce qui augmente l'utilisation virtuelle mais pas nécessairement l'utilisation physique. Tous mes processus Chrome utilisent chacun 2 To de mémoire virtuelle. Je suis sur un ordinateur portable avec 8 Go de mémoire physique. De toute façon, on a essayé de configurer des quotas de mémoire virtuelle ici, soit casser Chrome, forcer Chrome pour désactiver certaines fonctions de sécurité qui reposent sur l'allocation (mais pas l'utilisation) de grandes quantités de mémoire virtuelle, ou être totalement inefficace pour empêcher un utilisateur d'abuser du système.

5
Adam Azarchs

Vous ne pouvez pas limiter l'utilisation de la mémoire au niveau de l'utilisateur, ulimit peut le faire mais pour un seul processus.

Même en utilisant les limites par utilisateur dans /etc/security/limits.conf, un utilisateur peut utiliser toute la mémoire en exécutant plusieurs processus.

Si vous voulez vraiment limiter les ressources, vous devez utiliser un outil de gestion des ressources, comme rcapd utilisé par les projets et les zones sous Solaris.

Il y a quelque chose qui semble fournir des fonctionnalités similaires sur Linux que vous pourriez étudier: cgroups .

4
jlliagre