Brief by evilfactorylabs

Brief by evilfactorylabs • Untuk obrolan makan siangmu seputar dunia pemrograman. Terbit sebelum jam 13.37 WIB setiap hari Senin & Selasa.

Apakah 'kita' membutuhkan Docker?

Menurut lo?

Docker adalah salah satu software yang paling populer untuk melakukan containerization terhadap sebuah aplikasi/layanan. Yang singkatnya, proses "distribusi" terhadap suatu aplikasi dibungkus menjadi sebuah artifak yang disebut "image" yang nantinya akan dijalankan diatas Docker engine menjadi sebuah proses yang bisa disebut dengan container instance.

Tidak jarang developers pun menggunakan Docker di lingkungan development, seperti untuk provisioning local database; Bootstrapping existing microservices, dll jika tidak menyediakan cara untuk melakukan tunneling ke remote server yang sudah ada.

Sebelum kita membahas lebih lanjut tentang Docker, mari kita bahas sedikit bagaimana biasanya kita melakukan "packaging" untuk software yang kita buat.

Software Packaging

Sebelumnya sudah dibahas sedikit disini, tapi mari kita fokus membahas khusus tentang software packaging di bagian ini.

Ada beragam cara untuk melakukan distribusi terhadap software yang developers buat. Zaman dulu, mungkin didistribusikannya via CD (are u remember?) yang berisi (offline) "installer", lalu sekarang (mengingat akses internet sudah lumayan cepat dan terjangkau) mungkin berada di masa installer online.

Ya, kita mendistribusikan software tersebut (agar bisa digunakan oleh pengguna akhir) dalam bentuk "paket".

Tapi itu untuk aplikasi di lingkungan desktop, sekarang rata-rata aplikasi dibuat untuk lingkungan web, alias aplikasi web. Aplikasi web tidak bisa (tidak perlu!) didistribusi seperti itu karena platform untuk menjalankan aplikasi tersebut adalah sebuah peramban. Karena, untuk bisa menggunakan aplikasi web, pengguna tinggal hanya mengakses alamat URL yang sudah didefinisikan oleh pengembang aplikasi.

Tanpa proses instalasi, it just works.

Sayangnya, aplikasi web tidak sesederhana yang dibayangkan. Sekarang mayoritas untuk menjalankan aplikasi, pengguna membutuhkan akses internet. Selain karena proses komputasi berada di server, juga karena aplikasi sekarang mayoritas adalah tentang sistem informasi. Yang berarti, data adalah hal yang paling inti dari aplikasi tersebut.

Dan data disimpan di basis data, dan basis data tersebut tidak mungkin berjalan disisi pengguna.

Aplikasi pada dasarnya adalah sebuah "hasil akhir" dari kumpulan instruksi yang didefinisikan berdasarkan bahasa program tertentu. Entah itu bahasa program HTML Python, Ruby, Go, JavaScript, dll. Untuk bisa menjalankan instruksi tersebut, perlu adanya runtime yang mengerti bagaimana "hasil akhir" tersebut dijalankan.

Membosankan? Sebentar, mari kita bahas masalahnya.

Ketika kita membuat software selain aplikasi web, bagian "runtime" ini menjadi tanggung jawab pengguna akhir secara langsung. Seperti, bila kita membuat software untuk target MacOS dan GNU/Linux, pengguna akhir harus memasang "target" yang sesuai dengan platform yang dia gunakan.

Sedangkan di aplikasi web, pengguna akhir hanya menerima dokumen HTML (ya, dan CSS beserta JS nya juga). Aplikasi web adalah sebuah kumpulan "layanan" yang saling berkomunikasi, dan layanan tersebut adalah sebuah "hasil akhir" yang sempat kita bahas tadi.

Kebanyakan (but not limited to) layanan tersebut ditulis menggunakan bahasa program yang dinamis, yang singkatnya, tidak ada proses kompilasi yang terjadi. Yang artinya, software didistrbusikan beserta dengan sumber kode berikut dengan dependensinya juga.

Sedangkan platform, tidak peduli dengan sumber kode yang ada.

Apakah platform Android memperdulikan aplikasi yang didibuat menggunakan Java atau Kotlin? Tentu tidak, yang mereka pedulikan hanyalah sebuah berkas ber-ekstensi apk. Dan berkas tersebut, adalah sebuah "hasil akhir". Software artifact.

Noisy Neighbor

Kita sedang tidak membahas Bare Metal vs Cloud, namun kita akan menggunakan istilah tersebut disini.

Siapa yang tidak nyaman dengan tetangga yang berisik? Begitupula di konteks ini. Lihat, bagaimana keselnya melihat tetangga memonopoli sumber daya yang ada? Bagaimana ribetnya ketika lingkungan dicemari oleh "dependensi" yang berbeda-beda?

2 masalah diatas terjadi ketika kita tidak melakukan "isolasi" terhadap kumpulan layanan yang ada. Layanan X yang memakan sedikit memori jadi tidak responsif karena layanan Y memonopoli proses CPU yang ada. Layanan Z jadi tidak berjalanan, karena layanan Z menggunakan dependensi yang berbeda versi dari yang digunakan oleh layanan lain.

Mungkin kita sudah sedikit memberikan spoiler, tapi pembahasan masih panjang ya.

pwn

Familiar dengan istilah itu? Dimana seseorang mendapatkan hak akses tinggi (uid 0) yang biasanya memanfaatkan celah di level kernel.

Yang bahaya nya, bisa meng-take over seluruh layanan, berkas-berkas & basis data yang ada di mesin yang diserang tersebut. Mungkin bisa saja penyerang memanfaatkan celah di salah satu aplikasi yang memiliki celah, menanam (web) shell di server tersebut, lalu mencoba untuk melakukan penyerangan privilege escalation sampai menjadi uid 0.

Satu aplikasi yang memiliki celah, namun seluruh server yang terkena dampak. Meskipun terlihat sedikit mustahil tapi who knows kan?

What if?

Bagaimana jika ada "sebuah solusi" dari proses pemaketan & pendistribusian software yang lebih "efektif", dan bisa berjalan secara efisien serta aman?

Ya, perkenalkan: Docker. Salah satu platform untuk melakukan containerization yang paling terkenal dari merek lain.

Konsep container di Docker, hampir sama dengan konsep container (atau "kontener", oke?) di dunia nyata:

Sumber

Begitulah kira-kira gambaran bagaimana aplikasi dipaketkan, didistribusi, dan dijalankan. Aplikasi berada di sebuah "penampung", segala dependensi; proses, sumber kode, dll berada di penampung-penampung tersebut yang tidak menganggu penampung lain yang ada.

Penampung mengarah ke "kotak" yang ada diatas kapal tersebut

Kapal tersebut adalah Docker Engine, yang berada diatas Host OS & hardware. Anggap Host OS adalah lautan yang biru itu, dan hardware adalah.. Bumi?

Seringkali terdapat miskonsepsi antara Virtual Machine (VM) dan Container. Singkatnya, VM melakukan "virtualisasi" di level hardware sedangkan Container di level OS.

Yang berarti, VM benar-benar berjalan diatas OS nya masing-masing sedangkan Container diatas OS yang "sama". Isolasi yang ada di VM menyangkut aplikasi, dependensi sampai Guest OS sedangkan di Container sebatas di proses saja. Ya, Container hanyalah sebuah layanan/proses yang berjalan langsung di server kita yang mana docker daemon lah yang membuat proses tersebut dapat berjalan secara terisolasi.

Packaging, easier

Sama seperti dulu (yang tentang CD), aplikasi kita dipaketkan menjadi sebuah "image" (masih ingat dengan iso?) lalu didistribusikan ke Container Registry. Registry ini bisa yang official dari Docker Hub, JFrog Artifactory, dsb.

Untuk melakukan pemaketan ini, developer harus membuat file bernama Dockerfile yang mana berisi instruksi-instruksi yang harus dilakukan oleh Docker Engine dari proses pemaketan sampai ke tahap eksekusi. Lalu hasil dari proses pemaketan tersebut akan diberi "label", dan siap untuk didistribusi & digunakan oleh developer.

Dibagian proses pemaketan ini berisi dari instalasi dependensi, proses build, dsb yang bukan bagian dari lingkungan runtime. Biasanya proses packaging dilakukan di CI server, sehingga production server hanya menyimpan "hasil akhir" nya saja yang berbentuk image, bukan "sebuah direktori" yang berisi beberapa berkas dan direktori.

Distribution, easier

Sama seperti semudah menggunakan apt di Ubuntu ataupun brew di Mac OS yang mana adalah sebuah package manager, tentunya lebih mudah & sederhana dibanding harus melakukan cloning repository, memasang dependensi yang dibutuhkan, lalu melakukan proses build secara manual.

Docker pun menyediakan utilitas itu (alias bisa bertindak sebagai package manager), yakni semudah docker pull lalu image akan diperbarui bila terdapat perubahan atau diunduh bila belum memiliki image yang dimaksud di repository lokal.

Ini membantu untuk aplikasi/layanan yang dibuat menggunakan bahasa program yang dinamis yang tidak memiliki proses kompilasi.

Running, easier

Layanan dirancang untuk bisa berjalan secara terus menerus, di background. Alias, bertindak sebagai daemon. Biasanya, untuk melakukannya kita membutuhkan "service manager" dari yang lower-level seperti systemd(1) , atau menggunakan process manager yang spesifik dengan bahasa program yang digunakan seperti PM2 untuk Node.js, Foreman untuk Ruby, Supervisor untuk Python, dsb.

Di Docker, Docker sendiri memiliki process manager sendiri yang bisa disebut docker daemon. Docker tau perintah apa yang harus dijalankan berdasarkan yang sudah didefinisikan di Dockerfile dan proses diatur oleh Docker itu sendiri dari monitoring, logging, dsb yang biasa dilakukan oleh process manager.

Dan ya, proses terisolasi. Dependensi dan penggunaan sumber daya berada di container masing-masing, tidak mencemari "proses lain" apalagi mengganggunya. Dan bila menggunakan lightweight linux dibawah proses yang ada, dan sekiranya pwnd, server bisa dijamin aman karena yang diserang adalah OS yang berada di proses tersebut saja.

Apakah kita membutuhkan Docker?

Ya dan Tidak.

Docker adalah aplikasi open source, gratis, dan lumayan ringan (bila dibandingkan dengan VM untuk penggunaan yg serupa).

Untuk beberapa kasus, Docker membantu dan beberapa tidak. Seperti, untuk aplikasi yang berjalan sebagai "satu kesatuan" (can we call it monolith?) yang tidak dipecah-pecah yg juga dirancang untuk scaling secara vertikal.

Dan yang mana proses distribusinya pun terlihat lebih sederhana, mungkin bisa hanya dengan menggunakan git workflow.

Docker tidak hanya tentang mempaketkan & mendistribusikan aplikasi kita, namun tentang menjalankannya juga.

Menjalankannya pun tidak sebatas hanya bergantung dengan "endpoint" yang sudah ditentukan di Dockerfile, namun juga tentang bagaimana aplikasi tersebut dijalankan seperti ketika aplikasi bergantung dengan proses/container lain (hello docker compose) ataupun yang berjalan dibanyak server yang terdistribusi yang mana perlu melakukan sebuah upacara yg disebut dengan orchestration.

Alternatif

Ada pilihan lain selain Docker untuk menggunakan teknologi "containerization" ini, adalah LXC; FreeBSD jail(8), CoreOS rkt, OpenVZ, dll. Layak untuk diingat bahwa "menentukan pilihan" adalah sebuah hal yang krusial, jadi pilihlah jangan hanya berdasarkan sisi engineering nya saja.

Penutup

Disini kita hanya membicarakan Docker di surface nya saja. Saya pribadi menggunakan Docker (including to serve this blog) untuk menjalankan aplikasi-aplikasi saya (11 aplikasi + 4 database), yang untuk incoming request diatur oleh Traefik.

Di development environment, penggunaan Docker hanya untuk hal-hal terkait database aja. Untuk aplikasinya, berjalan sebagai standalone server aja karena aplikasi yang dikembangkan gak banyak-banyak gede-gede banget.

Bagaimanapun, Docker mengubah cara kita mengembangkan, mendistribusikan, dan menjalankan aplikasi yang kita buat. Kembali ke pertanyaan "Apakah 'kita' membutuhkan Docker?" Jawabannya adalah: Tergatung.

Sorry to disappoint you, thank you.

Jika kamu memiliki jawaban sendiri, silahkan bisa komentar dibawah. Terima kasih!

Menikmati tulisan ini?

Blog ini tidak menampilkan iklan, yang berarti blog ini didanai oleh pembaca seperti kamu. Gabung bersama Loading... yang telah membantu blog ini agar terus bisa mencakup tulisan yang lebih berkualitas dan bermanfaat!

Pendukung

Dukung Mengapa saya harus mendukung?
You've successfully subscribed to Brief by evilfactorylabs
Great! Next, complete checkout for full access to Brief by evilfactorylabs
Welcome back! You've successfully signed in
Success! Your account is fully activated, you now have access to all content.