- Menjalankan
docker run ubuntu tetap berbagi kernel Linux host, dan Ubuntu hanya menyediakan alat user space
- Hasil
uname -r akan menampilkan versi kernel host, sedangkan hanya /etc/os-release yang menunjukkan info Ubuntu
- VM memiliki kernel unik masing-masing dan butuh beberapa menit untuk boot, sedangkan container mulai dalam hitungan milidetik dan berbagi kernel host lewat isolasi level OS tanpa virtualisasi hardware, sehingga overhead rendah
- Berkat stabilitas ABI system call Linux, container dari berbagai distro bisa berjalan di kernel yang sama
- Di lingkungan RAM 16GB, batas praktisnya sekitar 50-100 container ringan, 10-30 container menengah, dan 5-10 container besar
- Memahami arsitektur ini penting karena kerentanan kernel memengaruhi semua container, dan pemilihan base image berdampak langsung pada kompatibilitas dan keamanan
Arti dari “menjalankan Ubuntu”
- Saat menjalankan
docker run ubuntu:22.04, Anda mendapatkan prompt bash yang terlihat seperti Ubuntu, dan bisa menjalankan apt update serta memasang paket
- Namun, jika menjalankan
uname -r di dalam container, yang tampil adalah versi kernel host (misalnya 6.5.0-44-generic)
- File
/etc/os-release menunjukkan Ubuntu 22.04, tetapi kernel-nya milik mesin host, dan bagian "Ubuntu" hanyalah filesystem yang membentuk user space
Container vs virtual machine: perbandingan arsitektur
- VM memvirtualisasikan hardware, sedangkan container memvirtualisasikan sistem operasi
- Perbedaan utama:
- Kernel: VM punya kernel sendiri-sendiri, container berbagi kernel host
- Waktu boot: VM butuh beberapa menit, container milidetik
- Overhead memori: VM 512MB-4GB, container 1-10MB
- Penggunaan disk: VM 10-100GB, image container 10-500MB
- Tingkat isolasi: VM di level hardware, container di level proses
- Performa: VM punya overhead sekitar 5-10%, container mendekati performa native
Komponen sebenarnya dalam base image
- Isi tarball yang diunduh saat menarik
ubuntu:22.04:
-
1. Binary penting (/bin, /usr/bin)
/bin/bash (shell), /bin/ls (daftar file), /bin/cat (menampilkan file)
/usr/bin/apt (package manager), /usr/bin/dpkg (alat paket Debian)
-
2. Shared library (/lib, /usr/lib)
- glibc dan shared library lain yang di-link oleh program
/lib/x86_64-linux-gnu/libc.so.6 (library C - dasar semua program C)
- Library penting seperti
libpthread.so.0, libm.so.6
-
3. File konfigurasi (/etc)
/etc/apt/sources.list (repository paket)
/etc/passwd (database pengguna)
/etc/resolv.conf (konfigurasi DNS, biasanya di-mount dari host)
-
4. Database paket
/var/lib/dpkg/status (paket yang terpasang)
/var/lib/apt/lists/ (cache paket yang tersedia)
- Kernel, bootloader, dan driver tidak termasuk
Kernel tetap sama, semua yang lain berubah
- Fitur yang disediakan kernel Linux: penjadwalan proses, manajemen memori, operasi filesystem, network stack, driver perangkat, system call
- Saat proses dalam container memanggil
open(), read(), fork(), panggilan itu langsung diteruskan ke kernel host
- Kernel tidak tahu ataupun peduli apakah proses itu berasal dari "container Ubuntu" atau "container Alpine"
-
Stabilitas antarmuka system call
- ABI syscall Linux sangat stabil
- Mengapa binary yang dikompilasi dengan glibc 2.31 (Ubuntu 20.04) tetap berjalan di kernel Ubuntu 24.04:
- Kernel menjaga kompatibilitas ke belakang
- Nomor system call tidak berubah
- Fitur baru ditambahkan, tetapi fitur lama hampir tidak pernah dihapus
- Inilah alasan container Ubuntu 18.04 bisa berjalan di host yang memakai kernel 6.5
Coba sendiri: kernel sama, user space berbeda
- Jika menjalankan kueri kernel yang sama di beberapa base image, Anda bisa melihat bahwa semua image berbagi kernel host yang sama
- ubuntu:22.04, debian:12, alpine:3.19, fedora:39, archlinux:latest semuanya menunjukkan versi kernel yang sama (6.5.0-44-generic)
- Perbedaan tiap container ada pada susunan userland seperti binary
uname dan libc
Mengapa container sangat efisien
-
1. Tidak ada duplikasi kernel
- VM memuat seluruh kernel ke memori masing-masing (sekitar 100-500MB)
- 10 VM menghabiskan memori untuk 10 kernel, sedangkan 10 container hanya memakai satu kernel
-
2. Start instan
- Urutan boot VM: BIOS → bootloader → kernel → sistem init → layanan
- Container hanya perlu memanggil
fork() dan exec() sehingga proses muncul dalam milidetik
- Boot VM umum: 30-60 detik / start container: sekitar 0.347 detik
-
3. Layer image bersama
- Jika menjalankan 100 container dari
ubuntu:22.04, layer base image hanya ada satu kali di disk
- Tiap container hanya mendapat layer copy-on-write tipis untuk perubahan
-
4. Berbagi memori lewat kernel
- Page cache kernel dibagikan
- Jika 50 container membaca file yang sama, kernel hanya menyimpannya sekali di cache
- Jika memakai shared library yang sama, halaman memori bisa dibagi dengan copy-on-write
Menghitung batas jumlah container
-
Analisis memori (berdasarkan VM dengan RAM 16GB)
- Total RAM: 16,384 MB
- Overhead OS host: -1,024 MB
- Docker daemon: -256 MB
- Overhead runtime container: -512 MB
- Kapasitas untuk container: 14,592 MB
-
Penggunaan memori per jenis container
- Minimal (
sleep): sekitar 1MB
- Alpine + aplikasi kecil: sekitar 25MB
- Ubuntu + aplikasi Python: sekitar 120MB
- Ubuntu + aplikasi Java: sekitar 500MB
- Layanan Node.js: sekitar 200MB
-
Maksimum teoretis
- Container minimal (1MB): 14,592
- Alpine + aplikasi kecil (25MB): 583
- Ubuntu + Python (120MB): 121
- Java microservice (500MB): 29
-
Batas nyata
- Selain memori, ada faktor lain:
- Penjadwalan CPU: terlalu banyak container bersaing dapat memicu lonjakan latensi
- File descriptor: ulimit default 1024
- Port jaringan: port mapping hanya tersedia sampai 65,535
- PID: dibatasi oleh
/proc/sys/kernel/pid_max (default: 32,768)
- Disk I/O: ada overhead OverlayFS dan kebutuhan menelusuri banyak layer
- Pada VM 16GB yang menjalankan workload nyata, batas praktisnya:
- Container ringan (API, worker): 50-100
- Container menengah (DB, cache): 10-30
- Container besar (model ML, aplikasi JVM): 5-10
Kompatibilitas distribusi Linux
-
Janji ABI kernel
- Linux mempertahankan antarmuka syscall yang stabil
- Binary yang dikompilasi untuk kernel lama tetap bisa berjalan di kernel baru
- Binary Ubuntu 18.04 berjalan normal di kernel 6.5
-
Saat kompatibilitas rusak
- Kebutuhan fitur kernel: jika container memerlukan fitur yang tidak ada di kernel (misalnya io_uring memerlukan kernel 5.1+)
- Ketergantungan modul kernel: Wireguard memerlukan modul kernel wireguard, container NVIDIA memerlukan driver kernel nvidia
- Batasan seccomp/capability: jika host memblokir syscall yang dibutuhkan container (misalnya penggunaan ptrace memerlukan
--cap-add SYS_PTRACE)
Panduan memilih base image
| Base image |
Ukuran |
Package manager |
Kegunaan |
scratch |
0 MB |
Tidak ada |
Binary Go/Rust yang dikompilasi statis |
alpine |
7 MB |
apk |
Container minimal, musl libc |
distroless |
20 MB |
Tidak ada |
Fokus keamanan, tanpa shell dan package manager |
debian-slim |
80 MB |
apt |
Keseimbangan ukuran dan kompatibilitas |
ubuntu |
78 MB |
apt |
Ramah untuk pengembangan |
fedora |
180 MB |
dnf |
Paket terbaru, SELinux |
-
Kapan memakai tiap image
- scratch: untuk binary yang dikompilasi statis, hanya berisi binary tanpa OS sama sekali
- alpine: image minimal saat masih butuh akses shell; memakai musl libc alih-alih glibc sehingga bisa memunculkan masalah kompatibilitas tertentu
- distroless: image production berfokus keamanan; tidak punya shell dan package manager sehingga debugging lebih sulit, tetapi lebih aman
Batas antara user space dan kernel
-
Yang berasal dari base image (user space)
- Shell (
/bin/bash, /bin/sh)
- Library C (glibc, musl)
- Package manager (apt, apk, yum)
- Utilitas inti (ls, cat, grep)
- Konfigurasi sistem init (biasanya bukan systemd itu sendiri)
- Pengguna dan grup default (
/etc/passwd)
- Path library dan konfigurasi
-
Yang berasal dari host (kernel)
- Penjadwalan proses dan manajemen memori
- Network stack (TCP/IP, routing)
- Operasi filesystem (read, write, mount)
- Fitur keamanan (namespace, cgroups, seccomp)
- Driver perangkat (GPU, jaringan, storage)
- Manajemen waktu dan clock
- Kriptografi dan pembangkitan angka acak
-
Ilusi yang diciptakan namespace
- Kernel menyediakan namespace agar container terasa terisolasi
- Proses yang terlihat sebagai PID 1 di dalam container sebenarnya ada di host dengan PID yang lebih tinggi (misalnya 45678)
- Kernel menjaga pemetaan: PID container 1 → PID host 45678
- Inilah cara isolasi bekerja tanpa virtualisasi
Maknanya di lingkungan production
-
1. Kerentanan kernel berdampak ke semua container
- Jika kernel host punya celah, semua container ikut terekspos
- Menjaga patch host tetap mutakhir itu wajib
-
2. Kernel host membatasi fitur container
- Untuk memakai io_uring, host harus menggunakan kernel 5.1+
- Fitur eBPF memerlukan kernel 4.15+ dengan opsi tertentu aktif
-
3. Pentingnya glibc vs musl
- Alpine memakai musl libc
- Sebagian binary yang dikompilasi untuk glibc mungkin tidak berjalan
- Contoh: saat menjalankan binary glibc di Alpine, bisa muncul error karena file
/lib/x86_64-linux-gnu/libc.so.6 tidak ada
-
4. “OS” container murni konsep organisasi
- Dari sudut pandang kernel, tidak ada perbedaan antara "container Ubuntu" dan "container Debian"
- Keduanya hanyalah proses yang membuat syscall
Kesalahpahaman yang umum
- ❌ "Container adalah VM ringan": container adalah proses dengan isolasi tingkat lanjut, sedangkan VM memvirtualisasikan hardware dan menjalankan kernel terpisah
- ❌ "Setiap container punya kernel sendiri": semua container berbagi kernel host, dan "OS" dalam container hanyalah file user space
- ❌ "Menjalankan container Ubuntu = menjalankan Ubuntu": yang dijalankan adalah kernel host dan tool Ubuntu; jika host-nya Debian, berarti sebenarnya memakai kernel Debian
- ❌ "Base image berisi sistem operasi lengkap": base image hanya memuat alat user space minimum, tanpa kernel, bootloader, atau driver
- ❌ "Semakin banyak container = semakin banyak memori": berkat layer bersama dan page cache kernel, container sering bisa berbagi memori secara efisien
Ringkasan inti
- Base image Docker adalah snapshot filesystem dari komponen user space sebuah distribusi Linux
- Binary, library, dan konfigurasi yang membuat Ubuntu terasa seperti Ubuntu
- Sistem operasi yang sebenarnya, yaitu kernel, dibagi dengan host
- Arsitektur ini memungkinkan:
- Waktu start dalam milidetik (tanpa boot kernel)
- Overhead memori minimal (satu kernel, halaman bersama)
- Kepadatan skala besar (ratusan container per host)
- Performa mendekati native (syscall langsung ke kernel)
- Trade-off-nya adalah isolasi yang lebih lemah dibanding VM — karena container berbagi kernel, eksploit kernel memengaruhi semua container
- Untuk sebagian besar workload, trade-off ini layak
9 komentar
Kernel + alat = distribusi
Kalau begitu, bukankah ini juga tetap Ubuntu..
Jadi, ada juga tutorial yang membuat Docker langsung di Linux dengan mengisolasi direktori lalu mengatur pengguna dan grup, dan sebagainya.
Bermanfaat.
리눅스 네임스페이스, cgroups, 및 chroot를 사용하여 자체 Docker를 구축하세요.
Jadi, kalau boleh dibilang agak berlebihan,
chroot + cgroup = dockerjuga cukup masuk akal untuk memahaminya.Sebenarnya, itu sedikit lebih dekat ke
systemd-nspawn☝️🤓Sebenarnya
Sarkasme / Merendahkan diri sendiri
Sangat menarik.
Sepertinya isi artikelnya menjelaskan berdasarkan LINUX,
tetapi kalau dijalankan di Windows, berarti kernel virtual yang dibuat dengan WSL2 juga akan dibagikan seperti yang dijelaskan di tulisan itu, ya?
Kalau misalnya ada kerentanan di Docker sehingga kernel bisa disentuh, saya juga penasaran apakah Windows yang menambahkan satu lapis virtualisasi dibanding Linux justru bisa dianggap lebih kuat dari sisi keamanan.
Saya agak terkejut melihat reaksi di komentar atas.
Saya kira tentu saja orang sudah tahu ini saat memakainya.
Kernel Linux berasal dari host, sedangkan sisanya berupa alat-alat yang digunakan di distribusi Linux.
Setahu saya, WSL2 berjalan dengan virtualisasi di atas Hyper-V.
Windows - Linux di dalam mesin virtual - lalu di dalamnya lagi Container...
Pada dasarnya, karena
rootdi dalam Container bukanrootyang sesungguhnya untuk seluruh sistem, secara default ia tidak bisa memanipulasi kernel sembarangan.Namun, kalau muncul kerentanan, akibatnya bisa besar.
Dari sisi performa, Windows cenderung lebih lambat karena harus melewati satu lapisan virtualisasi tambahan.