Bagaimana cara membuat pengguna dengan penggunaan RAM terbatas?

44

Jadi saya punya 4 GB RAM + 4GB swap. Saya ingin membuat pengguna dengan ram dan swap terbatas: RAM 3 GB dan swap 1 GB. Mungkinkah itu terjadi? Apakah mungkin untuk memulai aplikasi dengan RAM dan swap terbatas yang tersedia untuk mereka tanpa membuat pengguna yang terpisah (dan tidak menginstal aplikasi khusus - hanya memiliki konfigurasi server Debian / CentOS standar, dan tidak menggunakan sudo)?

Memperbarui:

Jadi saya membuka terminal dan mengetiknya perintah ulimit : ulimit -v 1000000yang akan menjadi seperti 976,6Mbbatasan. Selanjutnya saya menelepon ulimit -adan melihat keterbatasan itu "aktif". Lalu saya mulai beberapa skrip bash yang mengkompilasi dan memulai aplikasi saya nohup, yang panjang nohup ./cloud-updater-linux.sh >& /dev/null & ... tapi setelah beberapa waktu saya melihat:

masukkan deskripsi gambar di sini

(yang akan baik-baik saja jika tidak ada batasan yang diterapkan - itu mengunduh beberapa lib besar, dan mulai mengkompilasinya.)

Tapi saya pikir saya menerapkan batasan pada shell dan semua proses diluncurkan dengan / darinya ulimit -v 1000000? Apa yang salah? Bagaimana cara membuat terminal dan semua sub proses yang diluncurkan terbatas pada penggunaan ram?

myWallJSON
sumber
1
Anda tidak dapat menempatkan batasan memori pada pengguna secara keseluruhan, hanya pada setiap proses. Dan Anda tidak dapat membedakan antara penggunaan RAM dan swap. Jika Anda ingin kontrol yang lebih baik, jalankan proses pengguna di mesin virtual.
Gilles 'SANGAT berhenti menjadi jahat'
@Gilles cukup yakin bahwa mesin virtual hanya menggunakan cgroups dan namespaces, atau turunan dari
RapidWebs
@RapidWebs tidak, mereka tidak. Mereka hanya meniru jumlah RAM yang telah ditentukan, dan OS tamu kemudian memutuskan bagaimana mengalokasikannya ke proses.
Ruslan
Kontainer (bukan mesin virtual) menggunakan cgroup, untuk membatasi penggunaan memori. Membatasi memori virtual bukanlah ide yang baik; Suatu proses dapat menggunakan banyak memori virtual, tetapi hanya dapat menggunakan sedikit RAM. Sebagai contoh, sistem saya memiliki 34359738367 kB memori virtual yang dialokasikan, tetapi lebih sedikit ram.
ctrl-alt-delor

Jawaban:

64

ulimitdibuat untuk ini. Anda dapat mengatur default untuk ulimitper pengguna atau per grup di

/etc/security/limits.conf

ulimit -v KBYTESmenetapkan ukuran memori virtual maks. Saya tidak berpikir Anda bisa memberikan jumlah maksimum swap. Ini hanya batas pada jumlah memori virtual yang dapat digunakan pengguna.

Jadi, Anda limits.confakan memiliki garis (ke 4Gmemori maksimum )

luser  hard  as   4000000

PEMBARUAN - CGroups

Batas yang diberlakukan oleh ulimitdan limits.confper proses. Saya jelas tidak jelas tentang hal itu.

Jika Anda ingin membatasi jumlah total memori yang digunakan pengguna (yang Anda tanyakan). Anda ingin menggunakan cgroup .

Dalam /etc/cgconfig.conf:

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

Ini menciptakan cgroupyang memiliki batas memori maksimum 4Gb.

Dalam /etc/cgrules.conf:

luser   memory   memlimit/

Ini akan menyebabkan semua proses dijalankan oleh luserdijalankan di dalam memlimitcgroup yang dibuat di cgconfig.conf.

utopiabound
sumber
apakah hal seperti itu bisa diselesaikan useradd?
myWallJSON
4
@myWallJSON Tidak secara langsung, tetapi Anda dapat langsung menambahkannya ke membatasi.conf, atau Anda dapat mengatur grup dengan batas tertentu dalam batas.conf dan menambahkan pengguna ke grup itu.
utopiabound
1
Itu luar biasa! Saya tidak tahu Anda bisa melakukan ini! Jawaban bagus +1
Yanick Girouard
1
@utopiabound: Memperbarui Q saya dengan beberapa data yang saya coba gunakan ulimit.
myWallJSON
1
@ f.ardelian Tingkatkan kernel. Inilah artikel tentang bagaimana melakukan hal itu!
Daniel C. Sobral
4

Anda tidak dapat membatasi penggunaan memori di tingkat pengguna, ulimit dapat melakukan itu kecuali untuk satu proses.

Bahkan dengan menggunakan per batas pengguna di /etc/security/limits.conf, pengguna dapat menggunakan semua memori dengan menjalankan beberapa proses.

Jika Anda benar-benar ingin membatasi sumber daya, Anda perlu menggunakan alat manajemen sumber daya, seperti rcapd yang digunakan oleh proyek dan zona di bawah Solaris.

Ada sesuatu yang tampaknya menyediakan fitur serupa di Linux yang mungkin Anda selidiki: cgroups .

Jlliagre
sumber
Yah, saya kira menetapkan batas pada shell login pengguna atau sesuatu seperti itu dapat diartikan sebagai "menetapkan batas untuk pengguna", karena semua proses akan mewarisi dari shell itu?
amn
1
@ amn Tidak akan. Seorang pengguna mungkin hanya membuka shell login baru untuk mengatasinya.
jlliagre
Benar, itu menggugurkan asumsi saya baik-baik saja.
amn
3

cgroupsadalah cara yang tepat untuk melakukan ini, seperti yang ditunjukkan oleh jawaban lain. Sayangnya tidak ada solusi yang sempurna untuk masalah ini, seperti yang akan kita bahas di bawah. Ada banyak cara berbeda untuk menetapkan batas penggunaan memori cgroup. Bagaimana seseorang membuat sesi login pengguna secara otomatis menjadi bagian dari cgroup bervariasi dari satu sistem ke sistem lainnya. Red Hat memiliki beberapa alat, dan begitu pula systemd .

memory.memsw.limit_in_bytesdan memory.limit_in_bytesmenetapkan batas termasuk dan tidak termasuk swap, masing-masing. Kelemahannya memory.limit_in_bytesadalah ia menghitung file yang di-cache oleh kernel atas nama proses dalam cgroup terhadap kuota grup. Lebih sedikit caching berarti lebih banyak akses disk, jadi Anda berpotensi memberikan kinerja jika sistem memiliki memori yang tersedia.

Di sisi lain, memory.soft_limit_in_bytesmemungkinkan cgroup untuk melampaui kuota, tetapi jika pembunuh OOM kernel dipanggil maka cgroup yang melebihi kuota mereka terbunuh terlebih dahulu, secara logis. Kelemahan dari itu, bagaimanapun, adalah bahwa ada situasi di mana beberapa memori diperlukan segera dan tidak ada waktu untuk pembunuh OOM untuk mencari-cari proses untuk membunuh, dalam hal ini sesuatu mungkin gagal sebelum proses pengguna kuota berlebihan adalah terbunuh.

ulimit, bagaimanapun, benar-benar alat yang salah untuk ini. ulimit membatasi penggunaan memori virtual, yang hampir pasti bukan yang Anda inginkan. Banyak aplikasi dunia nyata menggunakan lebih banyak memori virtual daripada memori fisik. Sebagian besar runtime yang dikumpulkan oleh sampah (Java, Go) bekerja dengan cara ini untuk menghindari fragmentasi. Program "hello world" sepele di C, jika dikompilasi dengan pembersih alamat, dapat menggunakan memori virtual 20TB. Alokator yang tidak bergantung sbrk, seperti jemalloc (yang merupakan pengalokasi default untuk Rust) atau tcmalloc, juga akan memiliki penggunaan memori virtual yang jauh melebihi penggunaan fisiknya. Untuk efisiensi, banyak alat akan mmap file, yang meningkatkan penggunaan virtual tetapi tidak harus penggunaan fisik. Semua proses Chrome saya masing-masing menggunakan memori virtual 2TB. Saya menggunakan laptop dengan memori fisik 8GB. Dengan cara apa pun seseorang mencoba mengatur kuota memori virtual di sini akan memecah Chrome, memaksa Chrome untuk menonaktifkan beberapa fitur keamanan yang bergantung pada mengalokasikan (tetapi tidak menggunakan) memori virtual dalam jumlah besar, atau sama sekali tidak efektif mencegah pengguna menyalahgunakan sistem. .

Adam Azarchs
sumber