Memulai Docker: Menyederhanakan DevOps
Diterbitkan: 2022-03-11Jika Anda menyukai ikan paus, atau hanya tertarik pada pengiriman berkelanjutan yang cepat dan tanpa rasa sakit dari perangkat lunak Anda ke produksi, maka saya mengundang Anda untuk membaca Tutorial pengantar Docker ini. Segalanya tampaknya menunjukkan bahwa wadah perangkat lunak adalah masa depan TI, jadi mari kita berenang cepat dengan wadah ikan paus Moby Dock dan Molly.
Docker, diwakili oleh logo dengan paus yang tampak ramah, adalah proyek sumber terbuka yang memfasilitasi penyebaran aplikasi di dalam wadah perangkat lunak. Fungsionalitas dasarnya diaktifkan oleh fitur isolasi sumber daya dari kernel Linux, tetapi menyediakan API yang mudah digunakan di atasnya. Versi pertama dirilis pada tahun 2013, dan sejak itu menjadi sangat populer dan banyak digunakan oleh banyak pemain besar seperti eBay, Spotify, Baidu, dan banyak lagi. Pada putaran pendanaan terakhir, Docker telah mendapatkan $95 juta yang sangat besar, dan berada di jalur yang tepat untuk menjadi layanan utama DevOps.
Analogi Pengangkutan Barang
Filosofi di balik Docker dapat diilustrasikan dengan analogi sederhana berikut. Dalam industri transportasi internasional, barang harus diangkut dengan berbagai cara seperti forklift, truk, kereta api, crane, dan kapal. Barang-barang ini datang dalam berbagai bentuk dan ukuran dan memiliki persyaratan penyimpanan yang berbeda: karung gula, kaleng susu, tanaman dll. Secara historis, itu adalah proses yang menyakitkan tergantung pada intervensi manual di setiap titik transit untuk bongkar muat.
Semuanya berubah dengan penggunaan kontainer antar moda. Karena tersedia dalam ukuran standar dan diproduksi dengan mempertimbangkan transportasi, semua mesin yang relevan dapat dirancang untuk menanganinya dengan intervensi manusia yang minimal. Manfaat tambahan dari wadah tertutup adalah mereka dapat melestarikan lingkungan internal seperti suhu dan kelembaban untuk barang-barang sensitif. Akibatnya, industri transportasi dapat berhenti mengkhawatirkan barang itu sendiri dan fokus membawanya dari A ke B.
Dan di sinilah Docker masuk dan membawa manfaat serupa ke industri perangkat lunak.
Apa Bedanya dengan Mesin Virtual?
Sekilas, mesin virtual dan wadah Docker mungkin tampak sama. Namun, perbedaan utama mereka akan menjadi jelas ketika Anda melihat diagram berikut:
Aplikasi yang berjalan di mesin virtual, selain hypervisor, memerlukan contoh lengkap dari sistem operasi dan semua pustaka pendukung. Wadah, di sisi lain, berbagi sistem operasi dengan tuan rumah. Hypervisor sebanding dengan mesin kontainer (diwakili sebagai Docker pada gambar) dalam arti bahwa ia mengelola siklus hidup kontainer. Perbedaan penting adalah bahwa proses yang berjalan di dalam container sama seperti proses asli pada host, dan tidak menimbulkan overhead apa pun yang terkait dengan eksekusi hypervisor. Selain itu, aplikasi dapat menggunakan kembali pustaka dan berbagi data antar wadah.
Karena kedua teknologi memiliki kekuatan yang berbeda, biasanya ditemukan sistem yang menggabungkan mesin virtual dan wadah. Contoh sempurna adalah alat bernama Boot2Docker yang dijelaskan di bagian instalasi Docker.
Arsitektur Docker
Di bagian atas diagram arsitektur ada pendaftar. Secara default, registri utama adalah Docker Hub yang menampung gambar publik dan resmi. Organisasi juga dapat meng-host registri pribadi mereka jika diinginkan.
Di sisi kanan kami memiliki gambar dan wadah. Gambar dapat diunduh dari pendaftar secara eksplisit ( docker pull imageName
) atau secara implisit saat memulai sebuah wadah. Setelah gambar diunduh, itu di-cache secara lokal.
Wadah adalah contoh gambar - mereka adalah makhluk hidup. Mungkin ada beberapa kontainer yang berjalan berdasarkan gambar yang sama.
Di tengah, ada daemon Docker yang bertanggung jawab untuk membuat, menjalankan, dan memantau container. Ini juga menangani pembuatan dan penyimpanan gambar. Terakhir, di sisi kiri ada klien Docker. Ini berbicara dengan daemon melalui HTTP. Soket Unix digunakan saat berada di mesin yang sama, tetapi manajemen jarak jauh dimungkinkan melalui API berbasis HTTP.
Menginstal Docker
Untuk instruksi terbaru, Anda harus selalu merujuk ke dokumentasi resmi.
Docker berjalan secara native di Linux, jadi tergantung pada distribusi targetnya, ini bisa semudah sudo apt-get install docker.io
. Lihat dokumentasi untuk detailnya. Biasanya di Linux, Anda menambahkan perintah Docker dengan sudo
, tetapi kami akan melewatkannya di artikel ini untuk kejelasan.
Karena daemon Docker menggunakan fitur kernel khusus Linux, tidak mungkin menjalankan Docker secara native di Mac OS atau Windows. Sebagai gantinya, Anda harus menginstal aplikasi bernama Boot2Docker. Aplikasi ini terdiri dari VirtualBox Virtual Machine, Docker itu sendiri, dan utilitas manajemen Boot2Docker. Anda dapat mengikuti petunjuk instalasi resmi untuk MacOS dan Windows untuk menginstal Docker pada platform ini.
Menggunakan Docker
Mari kita mulai bagian ini dengan contoh singkat:
docker run phusion/baseimage echo "Hello Moby Dock. Hello Molly."
Kita harus melihat output ini:
Hello Moby Dock. Hello Molly.
Namun, lebih banyak yang terjadi di balik layar daripada yang mungkin Anda pikirkan:
- Gambar 'phusion/baseimage' diunduh dari Docker Hub (jika belum ada di cache lokal)
- Sebuah wadah berdasarkan gambar ini dimulai
- Perintah echo dieksekusi di dalam wadah
- Wadah dihentikan ketika perintah keluar
Saat pertama kali dijalankan, Anda mungkin melihat penundaan sebelum teks dicetak di layar. Jika gambar telah di-cache secara lokal, semuanya akan memakan waktu sepersekian detik. Detail tentang wadah terakhir dapat diambil dengan menjalankan docker ps -l
:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES af14bec37930 phusion/baseimage:latest "echo 'Hello Moby Do 2 minutes ago Exited (0) 3 seconds ago stoic_bardeen
Melakukan Penyelaman Berikutnya
Seperti yang Anda tahu, menjalankan perintah sederhana di dalam Docker semudah menjalankannya langsung di terminal standar. Untuk mengilustrasikan kasus penggunaan yang lebih praktis, sepanjang sisa artikel ini, kita akan melihat bagaimana kita dapat menggunakan Docker untuk menyebarkan aplikasi server web sederhana. Untuk mempermudah, kami akan menulis program Java yang menangani permintaan HTTP GET ke '/ ping' dan merespons dengan string 'pong\n'.
import java.io.IOException; import java.io.OutputStream; import java.net.InetSocketAddress; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; public class PingPong { public static void main(String[] args) throws Exception { HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0); server.createContext("/ping", new MyHandler()); server.setExecutor(null); server.start(); } static class MyHandler implements HttpHandler { @Override public void handle(HttpExchange t) throws IOException { String response = "pong\n"; t.sendResponseHeaders(200, response.length()); OutputStream os = t.getResponseBody(); os.write(response.getBytes()); os.close(); } } }
file docker
Sebelum masuk dan membangun image Docker Anda sendiri, sebaiknya periksa terlebih dahulu apakah ada yang sudah ada di Docker Hub atau registry pribadi apa pun yang dapat Anda akses. Misalnya, alih-alih menginstal Java sendiri, kami akan menggunakan gambar resmi: java:8
.
Untuk membangun sebuah gambar, pertama-tama kita perlu memutuskan gambar dasar yang akan kita gunakan. Hal ini dilambangkan dengan instruksi FROM . Di sini, ini adalah gambar resmi untuk Java 8 dari Docker Hub. Kami akan menyalinnya ke file Java kami dengan mengeluarkan instruksi COPY . Selanjutnya, kita akan mengompilasinya dengan RUN . Instruksi EXPOSE menunjukkan bahwa gambar akan memberikan layanan pada port tertentu. ENTRYPOINT adalah instruksi yang ingin kita jalankan ketika sebuah wadah berdasarkan gambar ini dimulai dan CMD menunjukkan parameter default yang akan kita berikan padanya.

FROM java:8 COPY PingPong.java / RUN javac PingPong.java EXPOSE 8080 ENTRYPOINT ["java"] CMD ["PingPong"]
Setelah menyimpan instruksi ini dalam file bernama “Dockerfile”, kita dapat membuat image Docker yang sesuai dengan menjalankan:
docker build -t toptal/pingpong .
Dokumentasi resmi untuk Docker memiliki bagian yang didedikasikan untuk praktik terbaik terkait penulisan Dockerfile.
Menjalankan Kontainer
Ketika image sudah terbangun, kita bisa menghidupkannya sebagai wadah. Ada beberapa cara untuk menjalankan container, tetapi mari kita mulai dengan yang sederhana:
docker run -d -p 8080:8080 toptal/pingpong
di mana -p [port-on-the-host]:[port-in-the-container] menunjukkan pemetaan port pada host dan container masing-masing. Selanjutnya, kami memberi tahu Docker untuk menjalankan wadah sebagai proses daemon di latar belakang dengan menentukan -d . Anda dapat menguji apakah aplikasi server web berjalan dengan mencoba mengakses 'http://localhost:8080/ping'. Perhatikan bahwa pada platform tempat Boot2docker digunakan, Anda harus mengganti 'localhost' dengan alamat IP mesin virtual tempat Docker dijalankan.
Di Linux:
curl http://localhost:8080/ping
Pada platform yang membutuhkan Boot2Docker:
curl $(boot2docker ip):8080/ping
Jika semuanya berjalan dengan baik, Anda akan melihat responsnya:
pong
Hore, wadah Docker kustom pertama kami masih hidup dan berenang! Kami juga dapat memulai wadah dalam mode interaktif -i -t . Dalam kasus kami, kami akan menimpa perintah entrypoint sehingga kami disajikan dengan terminal bash. Sekarang kita dapat menjalankan perintah apa pun yang kita inginkan, tetapi keluar dari wadah akan menghentikannya:
docker run -i -t --entrypoint="bash" toptal/pingpong
Ada lebih banyak pilihan yang tersedia untuk digunakan untuk memulai kontainer. Mari kita bahas beberapa lagi. Misalnya, jika kita ingin menyimpan data di luar container, kita dapat berbagi filesystem host dengan container dengan menggunakan -v . Secara default, mode akses adalah baca-tulis, tetapi dapat diubah ke mode hanya-baca dengan menambahkan :ro
ke jalur volume intra-kontainer. Volume sangat penting ketika kita perlu menggunakan informasi keamanan apa pun seperti kredensial dan kunci pribadi di dalam wadah, yang tidak boleh disimpan pada gambar. Selain itu, ini juga dapat mencegah duplikasi data, misalnya dengan memetakan repositori Maven lokal Anda ke wadah untuk menyelamatkan Anda dari mengunduh Internet dua kali.
Docker juga memiliki kemampuan untuk menghubungkan container bersama-sama. Kontainer yang terhubung dapat berbicara satu sama lain meskipun tidak ada port yang terbuka. Itu dapat dicapai dengan –link other-container-name . Di bawah ini adalah contoh menggabungkan parameter yang disebutkan di atas:
docker run -p 9999:8080 --link otherContainerA --link otherContainerB -v /Users/$USER/.m2/repository:/home/user/.m2/repository toptal/pingpong
Operasi Penampung dan Gambar Lainnya
Tidak mengherankan, daftar operasi yang dapat diterapkan pada wadah dan gambar agak panjang. Untuk singkatnya, mari kita lihat beberapa di antaranya:
- stop - Menghentikan container yang sedang berjalan.
- start - Memulai container yang dihentikan.
- commit - Membuat image baru dari perubahan container.
- rm - Menghapus satu atau lebih wadah.
- rmi - Menghapus satu atau lebih gambar.
- ps - Mencantumkan container.
- gambar - Daftar gambar.
- exec - Menjalankan perintah dalam wadah yang sedang berjalan.
Perintah terakhir bisa sangat berguna untuk tujuan debugging, karena memungkinkan Anda untuk terhubung ke terminal wadah yang sedang berjalan:
docker exec -i -t <container-id> bash
Penulisan Docker untuk Dunia Layanan Mikro
Jika Anda memiliki lebih dari sekadar beberapa wadah yang saling berhubungan, masuk akal untuk menggunakan alat seperti docker-compose. Dalam file konfigurasi, Anda menjelaskan cara memulai container dan bagaimana container harus ditautkan satu sama lain. Terlepas dari jumlah container yang terlibat dan ketergantungannya, Anda dapat menjalankan semuanya dengan satu perintah: docker-compose up
.
buruh pelabuhan di alam liar
Mari kita lihat tiga tahap siklus hidup proyek dan lihat bagaimana paus ramah kita dapat membantu.
Perkembangan
Docker membantu Anda menjaga lingkungan pengembangan lokal Anda tetap bersih. Alih-alih menginstal beberapa versi layanan berbeda seperti Java, Kafka, Spark, Cassandra, dll., Anda dapat memulai dan menghentikan wadah yang diperlukan saat diperlukan. Anda dapat mengambil langkah lebih jauh dan menjalankan beberapa tumpukan perangkat lunak secara berdampingan menghindari campur aduk versi ketergantungan.
Dengan Docker, Anda dapat menghemat waktu, tenaga, dan uang. Jika proyek Anda sangat rumit untuk disiapkan, lakukan "dockerise". Lewati kesulitan membuat gambar Docker sekali, dan dari titik ini semua orang dapat memulai wadah dalam sekejap.
Anda juga dapat menjalankan "lingkungan integrasi" secara lokal (atau pada CI) dan mengganti stub dengan layanan nyata yang berjalan di container Docker.
Pengujian / Integrasi Berkelanjutan
Dengan Dockerfile, mudah untuk mencapai build yang dapat direproduksi. Jenkins atau solusi CI lainnya dapat dikonfigurasi untuk membuat image Docker untuk setiap build. Anda dapat menyimpan beberapa atau semua gambar dalam registri Docker pribadi untuk referensi di masa mendatang.
Dengan Docker, Anda hanya menguji apa yang perlu diuji dan mengeluarkan lingkungan dari persamaan. Melakukan pengujian pada container yang sedang berjalan dapat membantu menjaga hal-hal lebih mudah diprediksi.
Fitur menarik lainnya dari memiliki wadah perangkat lunak adalah mudah untuk memutar mesin budak dengan pengaturan pengembangan yang identik. Ini bisa sangat berguna untuk pengujian beban penyebaran berkerumun.
Produksi
Docker dapat menjadi antarmuka umum antara pengembang dan personel operasi yang menghilangkan sumber gesekan. Ini juga mendorong gambar/binari yang sama untuk digunakan di setiap langkah pipa. Selain itu, kemampuan untuk men-deploy container yang telah diuji sepenuhnya tanpa perbedaan lingkungan membantu memastikan bahwa tidak ada kesalahan yang terjadi dalam proses build.
Anda dapat dengan mulus memigrasikan aplikasi ke dalam produksi. Sesuatu yang dulunya merupakan proses yang membosankan dan terkelupas sekarang dapat menjadi sesederhana:
docker stop container-id; docker run new-image
Dan jika terjadi kesalahan saat men-deploy versi baru, Anda selalu dapat dengan cepat melakukan roll-back atau mengubah ke container lain:
docker stop container-id; docker start other-container-id
… dijamin tidak akan meninggalkan kekacauan atau meninggalkan barang dalam keadaan tidak konsisten.
Ringkasan
Ringkasan bagus tentang apa yang dilakukan Docker termasuk dalam motonya sendiri: Bangun, Kirim, Jalankan.
- Build - Docker memungkinkan Anda membuat aplikasi dari layanan mikro, tanpa mengkhawatirkan inkonsistensi antara lingkungan pengembangan dan produksi, dan tanpa mengunci platform atau bahasa apa pun.
- Ship - Docker memungkinkan Anda merancang seluruh siklus pengembangan, pengujian, dan distribusi aplikasi, serta mengelolanya dengan antarmuka pengguna yang konsisten.
- Run - Docker menawarkan Anda kemampuan untuk menerapkan layanan yang dapat diskalakan secara aman dan andal di berbagai platform.
Bersenang-senang berenang dengan paus!
Bagian dari pekerjaan ini terinspirasi oleh buku yang sangat bagus Using Docker oleh Adrian Mouat.