15%

Hemat 15% di Semua Layanan Hosting

Uji kemampuanmu dan dapatkan Diskon pada paket hosting apa saja

Gunakan kode:

Skills
Memulai
09.10.2024

Mengelola Sumber Daya Sistem dengan Perintah `ulimit` di Linux

Perintah `ulimit` adalah utilitas shell bawaan pada sistem Unix dan Linux yang memberlakukan batas sumber daya per-proses dan per-pengguna, mencegah satu proses atau pengguna menghabiskan sumber daya sistem seperti waktu CPU, memori, deskriptor file terbuka, dan jumlah proses. Perintah ini beroperasi di tingkat kernel melalui system call `setrlimit()`, menjadikannya salah satu mekanisme paling langsung dan berbiaya rendah yang tersedia bagi administrator sistem untuk tata kelola sumber daya.

Untuk server mana pun yang menjalankan beban kerja produksi — baik aplikasi web dengan lalu lintas tinggi, mesin database, maupun tumpukan layanan mikro yang dikontainerisasi — pengaturan `ulimit` yang salah konfigurasi atau tidak ada adalah penyebab utama kegagalan berantai, proses yang tidak terkendali, dan pemadaman sistem penuh. Mengatur batas ini dengan benar bukan pilihan; ini adalah kebersihan infrastruktur yang mendasar.

Cara Kerja `ulimit` di Balik Layar

Ketika proses shell memanggil `ulimit`, ia memanggil system call `getrlimit()` dan `setrlimit()` yang didefinisikan dalam standar POSIX. Setiap batas direpresentasikan sebagai sepasang nilai: soft limit dan hard limit. Nilai-nilai ini disimpan per-proses dalam deskriptor proses kernel dan diwarisi oleh proses anak pada saat `fork()`.

Model pewarisan ini sangat penting untuk dipahami. Jika Anda menetapkan nilai `ulimit` dalam sesi shell, setiap proses yang dihasilkan dari shell tersebut — termasuk daemon yang diluncurkan melalui skrip init — mewarisi batas tersebut. Sebaliknya, batas yang ditetapkan di `/etc/security/limits.conf` berlaku pada waktu login PAM, bukan pada saat runtime, yang berarti batas tersebut hanya berlaku untuk sesi login baru, bukan untuk layanan yang sudah berjalan.

Soft Limit vs. Hard Limit

PropertiSoft LimitHard Limit
Siapa yang dapat menaikkannyaPengguna tanpa hak istimewa mana pun (hingga hard limit)Hanya root (`CAP_SYS_RESOURCE`)
Siapa yang dapat menurunkannyaPengguna mana punPengguna mana pun (tidak dapat dibalikkan tanpa root)
PenegakanDitegakkan oleh kernelBertindak sebagai batas atas untuk soft limit
Kasus penggunaan umumBatas operasional sehari-hariMaksimum absolut untuk kebijakan keamanan
Flag dalam `ulimit``-S``-H`

Kesalahan operasional yang umum adalah menetapkan hard limit sama dengan soft limit. Ini menghilangkan semua fleksibilitas bagi proses untuk sementara menaikkan batasnya sendiri, yang dilakukan secara sah oleh beberapa aplikasi (seperti implementasi JVM tertentu dan mesin database) selama startup.

Referensi Lengkap: Flag Sumber Daya `ulimit`

FlagSumber DayaSatuanNilai Produksi Umum
`-t`Waktu CPUDetik`unlimited` untuk daemon
`-f`Ukuran file maksimumBlok 512-byte`unlimited` atau batas tertentu
`-d`Ukuran segmen data (heap)KB`unlimited` untuk aplikasi Java
`-s`Ukuran stackKB`8192` (default)
`-c`Ukuran file core dumpBlok 512-byte`0` (dinonaktifkan di produksi)
`-m`Ukuran resident set maksimumKBJarang ditegakkan (gunakan cgroups)
`-v`Memori virtual (ruang alamat)KB`unlimited` untuk sebagian besar layanan
`-n`Deskriptor file terbukaJumlah`65536` atau lebih tinggi untuk server sibuk
`-u`Proses pengguna maksimumJumlah`4096`–`65536` tergantung peran
`-l`Memori terkunci (mlock)KBTinggi untuk Redis, Elasticsearch
`-i`Sinyal tertundaJumlahDefault sistem biasanya cukup
`-q`Byte antrian pesan POSIXByteDefault sistem
`-r`Prioritas penjadwalan real-timePrioritas`0` kecuali beban kerja RT
`-e`Prioritas penjadwalan maksimum (nice)Nilai niceDefault sistem

Penggunaan `ulimit` Praktis dengan Konteks Dunia Nyata

Melihat Batas Saat Ini

“`bash

ulimit -a # All soft limits for the current shell

ulimit -aH # All hard limits for the current shell

“`

Untuk memeriksa batas proses yang sedang berjalan (PID) secara spesifik, baca langsung dari filesystem proc — ini adalah sumber otoritatif dan melewati pelaporan tingkat shell:

“`bash

cat /proc/<PID>/limits

“`

Ini sangat berharga saat memecahkan masalah layanan yang dimulai oleh systemd atau skrip init, di mana `ulimit -a` tingkat shell tidak akan mencerminkan batas aktual proses.

Menetapkan Soft dan Hard Limit

“`bash

Set soft limit for open file descriptors

ulimit -Sn 65536

Set hard limit for open file descriptors

ulimit -Hn 131072

Set both simultaneously (soft = hard = value)

ulimit -n 65536

“`

Menonaktifkan Core Dump di Produksi

“`bash

ulimit -c 0

“`

Core dump dapat menghabiskan gigabyte ruang disk dalam hitungan detik ketika proses bermeori tinggi mengalami crash. Menonaktifkannya di produksi adalah praktik standar kecuali Anda sedang aktif melakukan debugging. Untuk lingkungan pengembangan, tetapkan jalur khusus menggunakan `sysctl kernel.core_pattern` bersama dengan batas core yang bukan nol.

Membatasi Waktu CPU untuk Proses yang Tidak Dipercaya

“`bash

ulimit -t 30

“`

Ini mengirimkan `SIGXCPU` ke proses ketika mencapai soft limit waktu CPU, dan `SIGKILL` pada hard limit. Ini sangat berguna di lingkungan shared hosting atau saat menjalankan skrip yang dikirimkan pengguna.

Menaikkan Batas Deskriptor File Terbuka untuk Layanan dengan Konkurensi Tinggi

Nginx, HAProxy, PostgreSQL, dan Redis semuanya memerlukan jumlah deskriptor file terbuka yang tinggi di bawah beban. Default sistem sebesar 1024 sangat rendah dan berbahaya untuk produksi:

“`bash

ulimit -n 65536

“`

Namun, ini hanya memengaruhi sesi shell saat ini. Untuk konfigurasi persisten, gunakan metode yang dijelaskan di bagian berikutnya.

Membuat Pengaturan `ulimit` Menjadi Persisten

Metode 1: `/etc/security/limits.conf`

Ini adalah pendekatan berbasis PAM standar untuk batas persisten tingkat pengguna:

“`

/etc/security/limits.conf

<domain> <type> <item> <value>

  • soft nofile 65536
  • hard nofile 131072

nginx soft nproc 4096

nginx hard nproc 8192

postgres soft nofile 65536

postgres hard nofile 65536

postgres soft memlock unlimited

postgres hard memlock unlimited

“`

Wildcard `*` berlaku untuk semua pengguna tetapi tidak berlaku untuk root. Root memerlukan entri eksplisit:

“`

root soft nofile 65536

root hard nofile 131072

“`

Pastikan modul PAM dimuat. Verifikasi `/etc/pam.d/common-session` (Debian/Ubuntu) atau `/etc/pam.d/system-auth` (RHEL/CentOS) mengandung:

“`

session required pam_limits.so

“`

Metode 2: File Drop-in `/etc/security/limits.d/`

Untuk manajemen yang lebih bersih, terutama dalam sistem manajemen konfigurasi seperti Ansible atau Puppet, tempatkan file batas khusus layanan di direktori drop-in:

“`bash

/etc/security/limits.d/99-nginx.conf

nginx soft nofile 65536

nginx hard nofile 131072

“`

File dalam direktori ini diproses setelah `limits.conf` dan menimpanya, menjadikannya ideal untuk penyesuaian khusus aplikasi tanpa memodifikasi konfigurasi dasar.

Metode 3: Unit Layanan systemd (Standar Modern)

Untuk layanan yang dikelola oleh systemd — yang merupakan mayoritas distribusi Linux modern — `limits.conf` tidak diterapkan secara default. systemd mengelola batas sumber dayanya sendiri per unit layanan:

“`ini

/etc/systemd/system/nginx.service.d/limits.conf

[Service]

LimitNOFILE=65536

LimitNPROC=4096

LimitCORE=0

LimitMEMLOCK=infinity

“`

Setelah mengedit, muat ulang dan mulai ulang:

“`bash

systemctl daemon-reload

systemctl restart nginx

“`

Verifikasi batas yang diterapkan:

“`bash

cat /proc/$(systemctl show -p MainPID nginx | cut -d= -f2)/limits

“`

Ini adalah metode paling andal untuk layanan produksi dan harus menjadi pendekatan default pada sistem mana pun yang menjalankan systemd (Ubuntu 16.04+, CentOS 7+, Debian 8+).

Metode 4: File Profil Shell

Untuk batas sesi pengguna yang berlaku secara interaktif, tambahkan perintah `ulimit` ke `/etc/profile` (seluruh sistem) atau `~/.bashrc` / `~/.profile` (per-pengguna). Pendekatan ini sesuai untuk workstation pengembang tetapi tidak cocok untuk proses daemon.

Profil Konfigurasi `ulimit` Berbasis Peran

Peran server yang berbeda memerlukan profil batas sumber daya yang pada dasarnya berbeda. Menerapkan default generik di semua jenis server adalah sumber umum kegagalan yang halus dan sulit didiagnosis.

Web Server (Nginx / Apache)

“`

nofile: 65536–131072 # High concurrency requires many open sockets + files

nproc: 4096 # Worker processes + threads

core: 0 # Disable core dumps in production

“`

Database Relasional (PostgreSQL / MySQL)

“`

nofile: 65536 # Many concurrent connections = many file descriptors

memlock: unlimited # Required for shared memory and huge pages

nproc: 4096

stack: 8192 KB

core: 0

“`

Server Aplikasi Java (Tomcat / Spring Boot)

“`

nofile: 65536

nproc: 65536 # JVM thread-per-connection models spawn many threads

data: unlimited # JVM heap is allocated from the data segment

stack: 512 KB # Reduce stack size to fit more threads in memory

“`

Redis / Penyimpanan Data In-Memory

“`

nofile: 65536

memlock: unlimited # Prevents swapping of memory-mapped data

“`

Jebakan Kritis dan Kasus Tepi

Batas `nproc` menghitung thread, bukan hanya proses. Di Linux, thread diimplementasikan sebagai proses ringan (`clone()` dengan memori bersama). Aplikasi Java dengan 500 thread dihitung sebagai 500 terhadap batas `nproc`. Ini mengejutkan banyak administrator yang menetapkan nilai `nproc` yang konservatif dan kemudian bertanya-tanya mengapa JVM mereka crash dengan `OutOfMemoryError: unable to create new native thread`.

`ulimit -v` membatasi ruang alamat virtual, bukan RAM fisik. Banyak administrator menetapkan `-v` dengan berpikir mereka membatasi penggunaan memori. Pada kenyataannya, mereka membatasi ruang alamat virtual, yang mencakup file yang dipetakan ke memori, pustaka bersama, dan metaspace JVM. Menetapkan ini terlalu rendah akan menyebabkan kegagalan `mmap()` dan kesalahan aplikasi yang tidak jelas.

`ulimit` tidak berlaku secara retroaktif. Mengubah batas di `limits.conf` atau file unit systemd tidak memengaruhi proses yang sudah berjalan. Anda harus memulai ulang layanan agar batas baru berlaku.

Lingkungan container melewati `ulimit` dengan cara yang tidak terduga. Di Docker, default `ulimit` ditetapkan di tingkat daemon (`/etc/docker/daemon.json`) dan dapat ditimpa per container dengan `–ulimit`. Namun, batas container dibatasi oleh batas kernel host. Menetapkan `nofile=1048576` dalam container sementara host memiliki `nofile=65536` akan secara diam-diam kembali ke batas host.

Batas sistem `nofile` terpisah dari batas per-proses. Parameter kernel `fs.file-max` (ditetapkan melalui `sysctl`) mengontrol jumlah total deskriptor file di seluruh sistem. Bahkan jika `nofile` per-proses ditetapkan tinggi, mencapai `fs.file-max` akan menyebabkan kesalahan `ENFILE` di seluruh sistem. Periksa dan sesuaikan keduanya:

“`bash

sysctl fs.file-max

sysctl -w fs.file-max=2097152

“`

`ulimit` vs. cgroups: Memilih Alat yang Tepat

Kemampuan`ulimit` / `setrlimit`cgroups v2
CakupanPer-proses (diwarisi oleh anak)Per-kelompok proses
Pembatasan memoriRuang alamat virtual saja (`-v`)Penegakan RSS + swap aktual
Pembatasan CPUAnggaran waktu CPU (`-t`)Pengontrol bandwidth CPU (% yang tepat)
Pembatasan I/OTidak didukungBobot dan batas kecepatan block I/O
Pembatasan jaringanTidak didukungMemerlukan integrasi tc + cgroup
PersistensiMelalui PAM atau systemdMelalui slice systemd atau cgroupfs
Kompatibilitas containerTerbatasNative (Docker, Kubernetes menggunakan cgroups)
GranularitasKasarTerperinci

`ulimit` tetap menjadi alat yang tepat untuk batas per-sesi yang cepat, batas deskriptor file, dan kontrol core dump. Untuk isolasi sumber daya yang komprehensif — terutama di lingkungan multi-tenant atau beban kerja yang dikontainerisasi — cgroups v2 adalah mekanisme yang lebih unggul. Pada lingkungan VPS Hosting atau Dedicated Server yang dikonfigurasi dengan baik, kedua mekanisme biasanya digunakan secara kombinasi: `ulimit` untuk penjaga per-proses dan cgroups untuk anggaran sumber daya agregat.

Pemantauan dan Validasi Batas Sumber Daya

Pemantauan proaktif mencegah kegagalan terkait batas menjadi insiden produksi.

Periksa penggunaan deskriptor file saat ini di seluruh sistem:

“`bash

cat /proc/sys/fs/file-nr

Output: <allocated> <unused> <max>

“`

Temukan proses yang mendekati batas `nofile` mereka:

“`bash

for pid in /proc/[0-9]*; do

pid_num=${pid##*/}

limit=$(awk '/Max open files/{print $4}' /proc/$pid_num/limits 2>/dev/null)

current=$(ls /proc/$pid_num/fd 2>/dev/null | wc -l)

[ -n "$limit" ] && [ "$limit" != "unlimited" ] &&

awk -v c=$current -v l=$limit -v p=$pid_num

'BEGIN{if(c/l>0.8) printf "PID %s: %d/%d (%.0f%%)n",p,c,l,c/l*100}'

done

“`

Alat untuk pemantauan berkelanjutan:

  • `lsof -u <username>` — daftar semua file terbuka untuk pengguna
  • `ss -s` — statistik socket (berkorelasi dengan tekanan `nofile`)
  • `htop` dengan tampilan pohon proses — visualisasikan jumlah proses per pengguna
  • `sar -v` — penggunaan deskriptor file dan inode historis melalui sysstat
  • Prometheus `node_exporter` — mengekspos metrik `node_filefd_allocated` dan `node_filefd_maximum` untuk peringatan

Untuk lingkungan yang menjalankan VPS dengan cPanel atau panel kontrol lainnya, banyak dari batas ini telah dikonfigurasi sebelumnya oleh penginstal panel, tetapi sering kali perlu disesuaikan ke atas seiring pertumbuhan lalu lintas. Selalu verifikasi batas aktual terhadap `/proc/<PID>/limits` daripada mempercayai dokumentasi panel.

Implikasi Keamanan dari `ulimit`

Batas sumber daya juga merupakan kontrol keamanan. Tanpa batas tersebut, proses yang dikompromikan atau bermasalah dapat mengeksekusi fork bomb (`:(){ :|:& };:`), menghabiskan semua slot proses yang tersedia dan membuat sistem tidak responsif. Batas `nproc` yang konservatif per pengguna adalah mitigasi utama:

“`

  • hard nproc 4096

“`

Demikian pula, menonaktifkan core dump (`-c 0`) mencegah konten memori yang sensitif — termasuk kunci enkripsi, kata sandi, dan token sesi — ditulis ke disk dalam file yang dapat dibaca semua orang.

Untuk lingkungan shared hosting atau server mana pun di mana beberapa pengguna memiliki akses shell, `ulimit` adalah lapisan keamanan yang wajib. Pada infrastruktur Shared Web Hosting, batas ini biasanya ditegakkan di tingkat platform, tetapi administrator yang menjalankan VPS multi-pengguna mereka sendiri harus mengonfigurasinya secara eksplisit.

Jika server Anda menangani terminasi SSL atau manajemen sertifikat, pastikan proses yang menangani TLS (misalnya, Nginx, HAProxy) memiliki batas `nofile` yang cukup, karena setiap koneksi TLS memerlukan beberapa deskriptor file. Padukan ini dengan SSL Certificates yang dikonfigurasi dengan benar untuk menghindari kegagalan koneksi terkait sertifikat yang memperparah masalah sumber daya.

Untuk penerapan server email, Postfix dan Dovecot sangat sensitif terhadap batas `nofile`, karena setiap koneksi email bersamaan dan akses kotak surat menghabiskan deskriptor file. Jika Anda menjalankan infrastruktur email sendiri daripada menggunakan Email Hosting yang dikelola, menyetel `nofile` ke setidaknya 65536 untuk pengguna email adalah hal yang tidak dapat ditawar pada server dengan beban sedang mana pun.

Matriks Keputusan: Apa yang Dikonfigurasi dan Di Mana

SkenarioMetode yang DirekomendasikanParameter Utama
Sesi pengguna interaktif`/etc/security/limits.conf``nofile`, `nproc`, `core`
Layanan yang dikelola systemdBagian `[Service]` unit systemd`LimitNOFILE`, `LimitNPROC`, `LimitCORE`
Container DockerFlag `–ulimit` atau `daemon.json``nofile`, `nproc`
Pengujian shell satu kaliPerintah `ulimit` langsungFlag apa pun
Server bersama multi-tenant`limits.conf` + penegakan PAM`nproc`, `nofile`, `fsize`, `cpu`
Pod KubernetesKonteks keamanan pod + cgroupsDikelola oleh kubelet
Penyesuaian khusus aplikasiFile drop-in `limits.d/`Parameter khusus layanan

Daftar Periksa Poin Penting Teknis

  • Selalu verifikasi batas yang diterapkan melalui `/proc/<PID>/limits`, bukan `ulimit -a` tingkat shell, untuk layanan yang berjalan.
  • Untuk layanan systemd, konfigurasikan batas dalam file unit menggunakan direktif `Limit*` — `limits.conf` tidak dibaca oleh systemd secara default.
  • Tetapkan `nofile` minimal `65536` untuk layanan mana pun yang menangani koneksi jaringan; `131072` atau lebih tinggi untuk beban kerja dengan konkurensi tinggi.
  • Jangan pernah menetapkan hard limit sama dengan soft limit kecuali Anda memiliki persyaratan keamanan tertentu — aplikasi memerlukan ruang untuk menyesuaikan diri sendiri.
  • Nonaktifkan core dump (`LimitCORE=0`) di produksi; aktifkan dengan jalur yang terkontrol di staging.
  • Batas `nproc` menghitung thread di Linux — pertimbangkan hal ini saat mengonfigurasi aplikasi JVM atau runtime Go.
  • Sesuaikan `fs.file-max` melalui `sysctl` bersama dengan batas `nofile` per-proses untuk menghindari kelelahan `ENFILE` di seluruh sistem.
  • Di lingkungan yang dikontainerisasi, batas kernel host adalah batas atas yang keras — pengaturan `ulimit` tingkat container tidak dapat melampauinya.
  • Gunakan cgroups v2 untuk penegakan memori dan I/O; gunakan `ulimit` untuk batas deskriptor file, jumlah proses, dan kontrol core dump.
  • Setelah perubahan batas apa pun di `limits.conf` atau file unit systemd, mulai ulang layanan yang terpengaruh dan verifikasi dengan `/proc/<PID>/limits`.

FAQ

Apakah `ulimit` berlaku untuk proses root?

Wildcard `*` di `/etc/security/limits.conf` secara eksplisit mengecualikan root. Proses root juga melewati penegakan hard limit untuk sebagian besar jenis sumber daya — root dapat menaikkan hard limit-nya sendiri. Untuk menerapkan batas pada root, tambahkan entri `root` eksplisit di `limits.conf`, meskipun banyak layanan sistem yang berjalan sebagai root akan mengabaikan batas yang diterapkan PAM jika dimulai di luar sesi login.

Mengapa perubahan `limits.conf` saya tidak berpengaruh pada layanan yang berjalan?

`limits.conf` diterapkan oleh PAM pada waktu login. Layanan yang dimulai oleh systemd, SysVinit, atau Upstart tidak melalui PAM dan oleh karena itu tidak mewarisi pengaturan `limits.conf`. Konfigurasikan batas langsung dalam file unit systemd menggunakan `LimitNOFILE` dan direktif terkait, kemudian jalankan `systemctl daemon-reload && systemctl restart <service>`.

Berapa nilai maksimum yang dapat saya tetapkan untuk `nofile`?

Maksimum per-proses dibatasi oleh parameter kernel `fs.nr_open` (default: 1.048.576 pada sebagian besar kernel). Total seluruh sistem dibatasi oleh `fs.file-max`. Anda dapat menaikkan `fs.nr_open` melalui `sysctl`, tetapi nilai di atas 1.048.576 memerlukan kompilasi ulang kernel pada kernel yang lebih lama. Secara praktis, 524.288 atau 1.048.576 mencakup hampir semua kasus penggunaan produksi.

Bagaimana cara memeriksa apakah suatu proses telah mencapai batas `ulimit`-nya?

Periksa log kernel dengan `dmesg | grep -i "ulimit|RLIMIT|too many open|cannot allocate"`. Log aplikasi biasanya akan menampilkan `EMFILE` (terlalu banyak file terbuka), `ENOMEM` (kegagalan alokasi memori), atau `EAGAIN` (sumber daya sementara tidak tersedia). Silang referensikan dengan `/proc/<PID>/limits` dan jumlah deskriptor saat ini melalui `ls /proc/<PID>/fd | wc -l`.

Apakah `ulimit` cukup untuk isolasi sumber daya di lingkungan multi-tenant?

Tidak. `ulimit` menyediakan penjaga per-proses dan per-pengguna tetapi tidak memberlakukan batas bandwidth memori, disk I/O, atau throughput jaringan. Untuk isolasi multi-tenant yang sesungguhnya, kombinasikan `ulimit` dengan pengontrol sumber daya cgroups v2, dan pertimbangkan isolasi namespace (namespace pengguna, namespace PID) untuk batas keamanan yang lebih kuat. Pada infrastruktur yang dikelola, kontrol ini biasanya berlapis di tingkat hypervisor dan runtime container.

15%

Hemat 15% di Semua Layanan Hosting

Uji kemampuanmu dan dapatkan Diskon pada paket hosting apa saja

Gunakan kode:

Skills
Memulai