Kuasai cgroups dan namespaces, teknologi kernel yang mendukung Docker, Kubernetes, dan containerisasi modern. Penting untuk insinyur DevOps dan cloud.

Di Episode 1, kami mengeksplorasi fondasi Linux dan sejarahnya. Sekarang kami menyelam lebih dalam ke kernel—inti Linux yang membuat containerisasi modern mungkin.
Jika Anda pernah bertanya-tanya bagaimana container Docker dapat menjalankan proses terisolasi pada mesin yang sama, atau bagaimana Kubernetes mengelola ribuan container tanpa saling mengganggu, jawabannya terletak pada dua teknologi kernel yang kuat: namespaces dan cgroups.
Ini bukan hanya konsep akademis. Mereka adalah fondasi dari Docker, Kubernetes, infrastruktur cloud, arsitektur microservices, dan praktik DevOps modern.
Memahami namespaces dan cgroups sangat penting bagi siapa pun yang bekerja dengan container, platform cloud, atau infrastruktur. Dalam episode ini, kami akan mendemistifikasi teknologi ini dan menunjukkan cara kerjanya di balik layar.
Pada akhirnya, Anda akan memahami bagaimana kernel mengisolasi proses, membatasi sumber daya, dan memungkinkan dunia yang dikontainerisasi tempat kami tinggal hari ini.
Kernel Linux adalah perangkat lunak inti yang mengelola semua sumber daya perangkat keras dan memediasi akses antara aplikasi dan perangkat keras. Tanggung jawab utamanya meliputi:
Kernel berjalan dalam mode istimewa yang disebut "kernel space" dan melindungi dirinya dari aplikasi pengguna.
Linux membagi memori dan eksekusi menjadi dua ruang yang berbeda:
Kernel Space
User Space
Pemisahan ini sangat penting untuk stabilitas dan keamanan sistem. Aplikasi tidak dapat langsung mengakses perangkat keras; mereka harus meminta kernel untuk melakukannya.
Ketika aplikasi pengguna perlu melakukan sesuatu yang istimewa (seperti membaca file atau mengalokasikan memori), aplikasi membuat system call. Ini adalah antarmuka antara user space dan kernel space.
System calls umum meliputi:
open(): Buka fileread(): Baca dari file descriptorwrite(): Tulis ke file descriptorfork(): Buat proses baruexec(): Jalankan programexit(): Hentikan prosesmmap(): Peta memorisocket(): Buat socket jaringanKetika system call dibuat, CPU beralih dari mode pengguna ke mode kernel, kernel melakukan operasi, dan kemudian beralih kembali ke mode pengguna. Perubahan konteks ini memiliki biaya performa, itulah mengapa meminimalkan system calls penting untuk kode yang kritis terhadap performa.
Proses adalah instance yang sedang berjalan dari program. Setiap proses memiliki:
Proses terisolasi satu sama lain. Satu proses crash tidak mempengaruhi yang lain (dalam kebanyakan kasus).
Proses melalui beberapa status selama masa hidupnya:
Running → Waiting → Stopped → Zombie → TerminatedPenjadwal proses kernel memutuskan proses mana yang berjalan di CPU pada waktu tertentu. Pada sistem multi-core, beberapa proses dapat berjalan secara bersamaan (satu per core).
Penjadwal menggunakan:
Itulah mengapa sistem single-core dapat menjalankan ribuan proses—mereka dengan cepat beralih di antara mereka.
Proses membentuk hierarki pohon:
init (PID 1)
├── systemd-journal
├── systemd-logind
├── sshd
│ └── bash (user session)
│ └── vim
└── nginx
├── nginx (worker)
└── nginx (worker)Proses pertama adalah init (PID 1), yang merupakan induk dari semua proses lainnya. Sistem Linux modern menggunakan systemd sebagai sistem init, yang mengelola layanan, dependensi, dan startup sistem.
Ketika proses induk dihentikan, anak-anaknya menjadi yatim piatu dan diadopsi oleh init. Ini mencegah proses zombie dari terakumulasi.
Setiap proses memiliki ruang alamat virtual sendiri. Ini adalah fitur Linux kunci yang menyediakan:
Alamat virtual dipetakan ke memori fisik oleh Memory Management Unit (MMU). Proses berpikir memiliki akses ke ruang memori besar dan kontinu, tetapi kernel memetakannya ke memori fisik yang terfragmentasi.
Ketika proses membutuhkan memori:
Ini memungkinkan sistem menjalankan proses yang secara kolektif menggunakan lebih banyak memori daripada yang tersedia secara fisik.
Swap adalah ruang disk yang digunakan sebagai perpanjangan RAM. Ketika memori fisik penuh:
Namun, swap jauh lebih lambat daripada RAM (I/O disk ~1000x lebih lambat). Swapping berlebihan menyebabkan degradasi performa yang parah. Sistem modern mencoba meminimalkan swapping melalui manajemen memori yang lebih baik dan batas cgroup.
Namespaces adalah fitur kernel yang mempartisi sumber daya sistem sehingga proses dapat memiliki tampilan terisolasi dari sistem. Alih-alih semua proses melihat sumber daya sistem yang sama, setiap namespace menyediakan tampilan terpisah.
Pikirkan namespaces seperti dunia virtual. Beberapa proses dapat ada di namespace yang berbeda, masing-masing melihat versi sistem yang berbeda. Proses di satu namespace tidak dapat melihat atau berinteraksi dengan sumber daya di namespace lain.
Namespaces adalah fondasi isolasi container. Docker dan Kubernetes menggunakan namespaces untuk membuat lingkungan terisolasi untuk container.
Linux menyediakan beberapa jenis namespaces, masing-masing mengisolasi sumber daya sistem yang berbeda:
Mengisolasi ID proses. Setiap PID namespace memiliki pohon proses sendiri dengan PID 1 sendiri (proses init).
Kasus penggunaan: Container melihat pohon proses mereka sendiri, bukan proses host Contoh: Proses init container memiliki PID 1 di dalam container, tetapi mungkin PID 12345 di host
Mengisolasi sumber daya jaringan: antarmuka jaringan, alamat IP, tabel routing, aturan firewall.
Kasus penggunaan: Setiap container memiliki stack jaringan sendiri Contoh: Container dapat memiliki alamat IP sendiri, port, dan konfigurasi jaringan terpisah dari host
Mengisolasi sistem file. Setiap namespace dapat memiliki tampilan berbeda dari hierarki sistem file.
Kasus penggunaan: Container memiliki sistem file root sendiri
Contoh: / container menunjuk ke image container, bukan sistem file root host
Mengisolasi sumber daya Inter-Process Communication: antrian pesan, memori bersama, semaphore.
Kasus penggunaan: Proses di namespace IPC berbeda tidak dapat berkomunikasi via IPC Contoh: Dua container tidak dapat berbagi memori atau antrian pesan
Mengisolasi nama host dan nama domain.
Kasus penggunaan: Setiap container dapat memiliki nama host sendiri Contoh: Container dapat memiliki nama host "web-server" sementara host adalah "production-01"
Mengisolasi ID pengguna dan grup. Proses dapat menjadi root (UID 0) di dalam user namespace tetapi pengguna biasa di host.
Kasus penggunaan: Container dapat berjalan sebagai root di dalam tetapi tidak istimewa di host Contoh: Root container (UID 0 di namespace) dipetakan ke UID 1000 di host
Mengisolasi hierarki cgroup (kami akan membahas cgroups selanjutnya).
Kasus penggunaan: Proses melihat tampilan cgroup yang disederhanakan
Contoh: Container melihat cgroup-nya sebagai / alih-alih /docker/container-id
Namespaces bekerja dengan menyediakan tampilan terpisah dari sumber daya sistem. Ketika proses dibuat di namespace:
Inilah cara container Docker dapat:
Cgroups (control groups) adalah fitur kernel yang membatasi, memprioritaskan, dan mengisolasi penggunaan sumber daya dari kelompok proses. Sementara namespaces menyediakan isolasi (Anda tidak dapat melihat sumber daya lain), cgroups menyediakan batas sumber daya (Anda tidak dapat menggunakan lebih dari yang diizinkan).
Cgroups memungkinkan Anda untuk:
Tanpa cgroups, satu proses dapat mengkonsumsi semua CPU atau memori, membuat proses lain kelaparan. Cgroups mencegah ini.
Cgroups v1 (legacy)
Cgroups v2 (modern)
Sebagian besar sistem modern sedang bertransisi ke cgroups v2, tetapi v1 masih umum dalam produksi.
Kontrol berapa banyak waktu CPU yang dapat digunakan kelompok proses:
cpu.max = "50000 100000" # 50% dari satu core CPU
cpu.weight = 100 # Bobot penjadwalan CPU (1-10000)Kontrol berapa banyak memori yang dapat digunakan kelompok proses:
memory.max = "512M" # Batas keras: 512 MB
memory.high = "256M" # Batas lunak: memicu reclaim pada 256 MB
memory.swap.max = "0" # Nonaktifkan swap untuk cgroup iniKontrol bandwidth I/O disk:
io.max = "8:0 rbps=10485760 wbps=10485760" # 10 MB/s baca dan tulisKontrol perangkat mana yang dapat diakses proses:
devices.allow = "c 1:3 rw" # Izinkan /dev/null (perangkat karakter 1:3)
devices.deny = "b 8:* rwm" # Tolak semua perangkat blokCgroups membentuk hierarki pohon. Setiap cgroup dapat memiliki cgroup anak, dan batas sumber daya diwarisi dan ditegakkan di setiap level:
/
├── system.slice
│ ├── systemd-logind.service
│ └── sshd.service
├── user.slice
│ └── user-1000.slice
│ └── session-1.scope
└── docker
├── container-1
│ └── memory.max = 512M
└── container-2
└── memory.max = 1GBatas aktual proses ditentukan oleh semua cgroups di jalurnya dari root ke leaf.
Docker menggabungkan namespaces dan cgroups untuk membuat container terisolasi dan terbatas sumber daya:
Ketika Anda menjalankan docker run, Docker:
Proses container berpikir sedang berjalan di mesin sendiri, tetapi sebenarnya berbagi kernel host dengan container lain.
Mari lacak apa yang terjadi ketika Anda menjalankan container:
docker run --name web --cpus 1 --memory 512m nginx/ sebagai root image nginx, bukan root hostContainer sepenuhnya terisolasi dari container lain dan host, namun semuanya berbagi kernel yang sama.
Ketika Anda menentukan batas sumber daya di Docker atau Kubernetes, Anda menetapkan batas cgroup:
# Docker: Batasi ke 2 CPU dan 1 GB memori
docker run --cpus 2 --memory 1g myapp
# Kubernetes: Tetapkan permintaan dan batas sumber daya
resources:
requests:
cpu: "500m"
memory: "256Mi"
limits:
cpu: "1000m"
memory: "512Mi"Batas ini ditegakkan oleh cgroups. Jika container mencoba melampaui batas memorinya, kernel membunuh proses (OOMKill). Jika mencoba menggunakan lebih banyak CPU daripada yang dialokasikan, itu dibatasi.
Anda dapat memeriksa namespaces di sistem Anda:
# Daftar semua namespaces untuk proses
ls -la /proc/1/ns/
# Tampilkan ID namespace
readlink /proc/1/ns/*
# Bandingkan namespaces antara proses
diff <(readlink /proc/1/ns/*) <(readlink /proc/self/ns/*)
# Daftar semua proses dan namespace mereka
ps aux | head -5Anda dapat membuat proses di namespace baru menggunakan unshare:
# Buat PID namespace baru
sudo unshare --pid --fork /bin/bash
# Di dalam namespace baru, PID 1 adalah bash
ps aux
# Buat network namespace baru
sudo unshare --net /bin/bash
# Di dalam, Anda memiliki antarmuka jaringan terisolasi
ip link showAnda dapat menetapkan batas cgroup menggunakan systemd-run:
# Jalankan proses dengan batas CPU (50% dari satu core)
systemd-run --scope -p CPUQuota=50% stress-ng --cpu 1
# Jalankan proses dengan batas memori (256 MB)
systemd-run --scope -p MemoryLimit=256M myapp
# Jalankan dengan kedua batas
systemd-run --scope -p CPUQuota=50% -p MemoryLimit=512M myappPantau penggunaan sumber daya cgroups:
# Lihat penggunaan memori cgroup v2
cat /sys/fs/cgroup/memory.current
cat /sys/fs/cgroup/memory.max
# Lihat penggunaan CPU
cat /sys/fs/cgroup/cpu.stat
# Pantau secara real-time
watch -n 1 'cat /sys/fs/cgroup/memory.current'
# Untuk container Docker
docker statsTip
Jalur ke file cgroup berbeda antara cgroups v1 dan v2. Sebagian besar sistem modern menggunakan cgroups v2 di /sys/fs/cgroup/, sementara sistem yang lebih lama menggunakan v1 di /sys/fs/cgroup/<resource>/.
Kesalahan: Menetapkan batas memori terlalu rendah, menyebabkan OOMKill
# BURUK: 128 MB terlalu rendah untuk sebagian besar aplikasi
resources:
limits:
memory: "128Mi"Mengapa terjadi: Meremehkan kebutuhan memori aplikasi atau mencoba mengemas terlalu banyak container
Cara menghindarinya:
docker stats atau metrik Kubernetes untuk memahami penggunaanKesalahan: Menganggap proses di container dapat mengakses jaringan host
Mengapa terjadi: Salah memahami cara kerja network namespaces
Cara menghindarinya: Ingat bahwa container memiliki network namespaces terisolasi. Untuk mengakses jaringan host, gunakan --network host di Docker atau hostNetwork: true di Kubernetes.
Kesalahan: Tidak memperhitungkan tekanan memori dan penggunaan swap
Mengapa terjadi: Menganggap batas memori adalah pemberhentian keras (mereka tidak—swap dapat memperpanjangnya)
Cara menghindarinya:
memory.swap.max = 0)Kesalahan: Mengizinkan swap unlimited, menyebabkan degradasi performa
Mengapa terjadi: Konfigurasi sistem default memungkinkan swap
Cara menghindarinya:
Tetapkan permintaan dan batas sumber daya yang sesuai:
# Contoh Kubernetes
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"Permintaan adalah apa yang digunakan penjadwal untuk penempatan. Batas adalah batas keras yang ditegakkan oleh cgroups.
Nonaktifkan swap untuk performa yang dapat diprediksi:
# Di Docker
docker run --memory-swap 0 myapp
# Di Kubernetes
securityContext:
capabilities:
add:
- SYS_RESOURCEGunakan resource quotas di Kubernetes:
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
spec:
hard:
requests.cpu: "10"
requests.memory: "20Gi"
limits.cpu: "20"
limits.memory: "40Gi"Pantau metrik cgroup:
Gunakan alat seperti:
docker stats: Metrik container real-timekubectl top: Penggunaan sumber daya KubernetesAtur alert untuk:
Gunakan user namespaces: Petakan root container ke pengguna tidak istimewa di host
docker run --userns-remap=default myappBatasi akses perangkat: Hanya izinkan perangkat yang diperlukan
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALLGunakan filesystem read-only: Cegah container memodifikasi filesystem-nya
securityContext:
readOnlyRootFilesystem: trueJangan secara manual mengonfigurasi cgroups. Gunakan Docker atau Kubernetes sebagai gantinya:
# JANGAN lakukan ini secara manual
echo "512M" > /sys/fs/cgroup/memory/myapp/memory.limit_in_bytes
# LAKUKAN ini sebagai gantinya
docker run --memory 512m myappAlat orkestrasi container menangani konfigurasi cgroup untuk Anda, dengan abstraksi yang lebih baik dan penanganan kesalahan.
Di Kubernetes, Anda menentukan permintaan dan batas sumber daya, dan Kubernetes mengelola cgroups:
# Kubernetes menangani konfigurasi cgroup
resources:
requests:
memory: "256Mi"
limits:
memory: "512Mi"Anda tidak perlu tahu tentang cgroups untuk menggunakan Kubernetes secara efektif. Orchestrator mengabstraksi kompleksitasnya.
ls /proc/1/ns/ untuk melihat namespaces di sistem Andadocker stats untuk melihat penggunaan sumber daya/usr/share/doc/linux-doc/ atau kernel.orgMemahami namespaces dan cgroups adalah kunci untuk menguasai containerisasi. Konsep ini berlaku apakah Anda menggunakan Docker, Kubernetes, atau platform container lainnya.
Siap untuk episode berikutnya? Lanjutkan dengan Episode 3: Izin, Pengguna & Grup untuk menguasai manajemen izin file dan pengguna, yang sangat penting untuk keamanan container.