Masalah Data

Sifat sistem berkas container yang sekali pakai dan mengapa basis data tidak boleh menyimpan data di dalamnya.

Daftar isi

Data yang ditulis di dalam container tidak dirancang untuk bertahan. Topik ini menjelaskan di mana perubahan itu disimpan, pola penempatan data mana yang paling berbahaya, dan mengapa siklus penggantian container menuntut data yang berada di luar container. Data yang harus tetap ada melewati umur container disebut data persisten. Sebuah simulasi tanpa Docker dipakai untuk memperlihatkan hilangnya data bersama tempat penyimpanannya. Setelah topik ini, keputusan menempatkan data di dalam maupun di luar container memiliki dasar yang jelas.

Lapisan tulis yang hidup bersama container#

Sistem berkas container tersusun atas layer image, lapisan penyusun image yang read-only, dan satu lapisan tulis tipis milik container yang sedang berjalan. Seluruh perubahan selama container hidup, mulai dari berkas log sampai baris baru pada basis data, ditulis pada lapisan tulis itu. Umur lapisan tulis terikat pada umur container yang memilikinya. Container yang dihentikan dengan docker stop masih menyimpan seluruh isinya dan dapat dijalankan kembali, tetapi container yang dihapus dengan docker rm membuang lapisan tulisnya seketika.

Perintah berikut menghapus container basis data aplikasi catatan. Lapisan tulis container itu, yang berisi seluruh berkas basis data yang ditulis selama layanan berjalan, ikut dibuang pada perintah yang sama. Tidak ada tahap pemulihan bawaan setelah perintah itu dijalankan.

bash
# tidak-dijalankan: daemon Docker tidak tersedia di sandbox
# menghapus container beserta seluruh isi lapisan tulisnya
docker rm catatan-db

Contoh lain yang sering terjadi adalah container yang dibangun ulang dari image yang sama. Container baru memperoleh lapisan tulis yang kosong, sehingga dimulai dari keadaan awal, bukan dari keadaan terakhir container sebelumnya. Keadaan yang benar-benar diinginkan hanya dapat dijamin bila data penting tidak pernah masuk ke lapisan tulis.

Simulasi hilangnya lapisan tulis#

Sandbox tempat topik ini ditulis tidak memiliki daemon Docker, yaitu proses latar yang menjalankan seluruh pekerjaan Docker, sehingga hilangnya lapisan tulis disimulasikan. Sebuah direktori sementara dibuat dengan mktemp -d untuk berperan sebagai container, subdirektori di dalamnya berperan sebagai lapisan tulis, dan satu berkas catatan ditulis di dalamnya. Langkah berikutnya menghapus subdirektori itu, lalu membaca berkasnya kembali sebagaimana aplikasi membaca datanya.

bash
# direktori sementara berperan sebagai container
cd "$(mktemp -d)"
# subdirektori berperan sebagai lapisan tulis, lalu satu berkas ditulis di dalamnya
mkdir lapisan-tulis
echo "catatan: rapat tim pukul sepuluh" > lapisan-tulis/catatan.txt
# container dihapus beserta lapisan tulisnya
rm -rf lapisan-tulis
# percobaan membaca berkas yang ditulis di lapisan tulis
cat lapisan-tulis/catatan.txt
text Keluaran
cat: lapisan-tulis/catatan.txt: No such file or directory

Pesan error di atas adalah keluaran asli dari simulasi, dan pola yang sama terjadi ketika docker rm menghapus container basis data. Berkas catatan.txt sempat ada, lalu hilang bersama direktorinya, dan tidak ada langkah pembatalan yang tersedia. Perintah cat diakhiri dengan status keluar bukan nol sebagai tanda kegagalan. Pada skala satu berkas kerugiannya terasa kecil, tetapi pada lapisan tulis container basis data, yang hilang adalah seluruh tabel beserta baris yang pernah ditulis.

Simulasi ini sengaja memakai alat dasar sistem operasi agar mekanismenya terlihat tanpa lapisan tambahan. Peran setiap bagian sudah jelas, yaitu direktori sementara sebagai container, subdirektori sebagai lapisan tulis, dan perintah penghapusan sebagai pengganti docker rm. Yang berbeda hanya alatnya, sedangkan akibat yang dialami data sama persis.

Pola penulisan yang berbahaya#

Bila seluruh tulisan di lapisan tulis hilang bersama container, pola kerja yang menaruh data penting di sana berarti menaruh data pada tempat yang sengaja dibuat sekali pakai. Tiga pola berikut muncul berulang kali pada aplikasi nyata dan menimbulkan kerugian yang tidak dapat dipulihkan.

  • Menyimpan basis data di dalam container. Berkas basis data ditulis terus-menerus selama layanan berjalan, dan penghapusan container menghapus seluruh tabel beserta isinya bersama lapisan tulis.
  • Menerima unggahan pengguna tanpa jalur keluar. Lampiran pada aplikasi catatan, misalnya gambar, tidak dapat dibuat ulang setelah hilang, sehingga lapisan tulis menjadi satu-satunya salinan yang ada.
  • Membangun cache yang mahal di dalam container. Cache adalah salinan kerja untuk mempercepat akses, dan kehilangannya tidak merusak data, tetapi seluruh biaya komputasi untuk membangunnya ulang muncul kembali dari nol.

Sebaliknya, data yang boleh hilang boleh saja tinggal di lapisan tulis. Log yang juga dikirim ke layanan lain, berkas sementara yang dibuat ulang otomatis, dan isi direktori kerja yang diambil dari image adalah contohnya. Pembedanya bukan ukuran berkas, melainkan biaya kehilangannya.

Siklus penggantian container menuntut data di luar container#

Prinsip immutability yang menjadi dasar kerja container menetapkan bahwa container tidak pernah diperbaiki dari dalam, melainkan diganti. Setiap perubahan aplikasi menghasilkan image baru, image baru dijalankan sebagai container baru, dan container lama dibuang. Dalam siklus itu, lapisan tulis container lama ikut dibuang setiap kali rilis terjadi. Bila data aplikasi catatan hanya hidup di lapisan tulis container basis data, pembaruan sekecil apa pun menghapus seluruh riwayat catatan pengguna.

Docker menyediakan dua mekanisme untuk menaruh data di luar lapisan tulis. Volume adalah penyimpanan yang dikelola Docker di host, sedangkan bind mount adalah pemetaan langsung ke direktori yang sudah ada di host. Host berarti mesin tempat Docker berjalan. Keduanya dipasang ke container pada jalur tertentu sehingga tulisan aplikasi tersimpan di luar container, dan container bebas dibuang tanpa menyentuh datanya. Volume menjadi jawaban standar untuk data basis data, sedangkan bind mount banyak dipakai untuk kode sumber saat pengembangan.

Ringkasan#

  • Lapisan tulis menyimpan seluruh perubahan selama container hidup, dan docker rm membuangnya bersama container tanpa tahap pemulihan.
  • Basis data, unggahan pengguna, dan cache yang mahal tidak boleh ditempatkan di lapisan tulis karena kerugiannya tidak dapat dipulihkan.
  • Siklus membangun ulang image dan mengganti container membuang lapisan tulis setiap rilis, sehingga data yang harus bertahan wajib berada di luar container.
  • Docker menyediakan volume dan bind mount sebagai tempat data di luar lapisan tulis.

Referensi#