Docker adalah teknologi untuk mengemas komponen tumpukan Anda sebagai wadah terisolasi. Sudah menjadi praktik umum untuk menjalankan setiap proses Anda dalam wadahnya sendiri, menciptakan pemisahan yang bersih antar komponen. Hal ini meningkatkan modularitas dan memungkinkan Anda mengakses manfaat skalabilitas containerization.
Masih ada situasi di mana Anda ingin menjalankan beberapa layanan dalam satu container. Meskipun ini tidak muncul secara alami di ekosistem Docker, kami akan menunjukkan beberapa pendekatan berbeda yang dapat Anda gunakan untuk membuat container dengan lebih dari satu proses yang berumur panjang.
Identifikasi Masalah
Container container menjalankan satu proses latar depan. Ini ditentukan oleh instruksi ENTRYPOINT dan CMD gambar. ENTRYPOINT diatur dalam Dockerfile gambar sementara CMD dapat diganti saat membuat wadah. Kontainer berhenti secara otomatis ketika proses latar depan mereka keluar.
Anda dapat meluncurkan proses lain dari CMD tetapi penampung hanya akan tetap berjalan saat proses latar depan asli masih hidup. Menjaga container tetap beroperasi selama masa pakai gabungan dari dua layanan independen tidak dapat dilakukan secara langsung menggunakan mekanisme ENTRYPOINT/CMD.
Membungkus Banyak Proses dalam Satu Entrypoint
Wrapper skrip adalah solusi paling sederhana untuk masalah tersebut. Anda dapat menulis skrip yang memulai semua proses Anda dan menunggu hingga selesai. Menyetel skrip sebagai ENTRYPOINT Docker Anda akan menjalankannya sebagai proses latar depan container, menjaga container tetap berjalan hingga salah satu skrip yang dibungkus keluar.
#!/bin/bash
/opt/first-process &
/opt/second-process &
wait -n
exit $?
Skrip ini memulai binari /opt/proses pertama dan /opt/proses kedua di dalam wadah. Penggunaan & memungkinkan skrip untuk melanjutkan tanpa menunggu setiap proses keluar. wait digunakan untuk menangguhkan skrip sampai salah satu proses berhenti. Skrip kemudian keluar dengan kode status yang dikeluarkan oleh skrip yang telah selesai.
Model ini menghasilkan wadah yang menjalankan proses pertama dan proses kedua hingga salah satunya keluar. Pada saat itu, wadah akan berhenti, meskipun proses lain mungkin masih berjalan.
Untuk menggunakan skrip ini, ubah ENTRYPOINT dan CMD gambar Docker Anda untuk menjadikannya proses latar depan wadah:
ENTRYPOINT ["/bin/sh"]
CMD ["./path/to/script.sh"]
Dengan opsi --init
Dengan mengelola proses container secara efektif dibersihkan saat keluar. Docker menjalankan CMD Anda sebagai ID proses 1, membuatnya bertanggung jawab untuk menangani sinyal dan menghilangkan zombie. Jika skrip Anda tidak memiliki kemampuan ini, Anda bisa berakhir dengan proses anak yatim piatu yang bertahan di dalam container Anda.
Perintah run docker memiliki flag --init yang memodifikasi entrypoint untuk menggunakan tini sebagai PID 1. Ini adalah proses init minimal implementasi yang menjalankan CMD Anda, menangani penerusan sinyal, dan terus-menerus menuai zombies.
Sebaiknya gunakan --init jika Anda berharap akan menghasilkan banyak proses dan tidak ingin menangani pembersihan secara manual. Tini adalah rasa init ringan yang dirancang untuk wadah. Ini jauh lebih kecil daripada alternatif yang lengkap seperti systemd dan pemula.
Menggunakan Pengelola Proses Khusus
Skrip manual dengan cepat menjadi kurang optimal ketika Anda memiliki banyak proses untuk dikelola. Mengadopsi manajer proses adalah cara lain untuk menjalankan beberapa layanan di dalam wadah Docker Anda. Manajer proses menjadi ENTRYPOINT Anda dan bertanggung jawab untuk memulai, memelihara, dan membersihkan setelah proses pekerja Anda.
Ada beberapa opsi yang tersedia saat menerapkan pendekatan ini. supervisord adalah pilihan populer yang mudah dikonfigurasi melalui file /etc/supervisor/conf.d/supervisord.conf:
[program:apache2]
command=/usr/sbin/apache2 -DFOREGROUND
[program:mysqld]
command=/usr/sbin/mysqld_safe
File konfigurasi ini mengonfigurasi supervisord untuk memulai Apache dan MySQL. Untuk menggunakannya dalam wadah Docker, tambahkan semua paket yang diperlukan ke gambar Anda, lalu salin file konfigurasi supervisord Anda ke lokasi yang benar. Tetapkan supervisord sebagai CMD gambar untuk menjalankannya secara otomatis ketika container start.
FROM ubuntu:latest
RUN apt-get install -y apache2 mysql-server supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
ENTRYPOINT ["/bin/sh"]
CMD ["/usr/bin/supervisord"]
Karena supervisord berjalan terus-menerus, penampung tidak dapat dihentikan saat salah satu proses yang dipantau keluar. Opsi alternatif adalah s6-overlay yang memang memiliki kemampuan ini. Ini menggunakan model layanan deklaratif di mana Anda menempatkan skrip layanan langsung ke /etc/services.d:
# Add s6-overlay to your image
ADD https://github.com/just-containers/s6-overlay/releases/download/v3.1.0.0/s6-overlay-noarch.tar.xz /tmp
RUN tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz
RUN printf "#!/bin/shn/usr/sbin/apache2 -DFOREGROUND" > /etc/services.d/first-service/run
RUN chmod +x /etc/services.d/first-service/run
# Use s6-overlay as your image's entrypoint
ENTRYPOINT ["/init"]
Anda dapat menambahkan skrip penyelesaian yang dapat dieksekusi di dalam direktori layanan Anda untuk menangani penghentian wadah dengan pemberhentian buruh pelabuhan. s6-overlay akan secara otomatis menjalankan skrip ini ketika prosesnya menerima sinyal TERM karena perintah stop. Skrip
Finish menerima kode keluar dari layanan mereka sebagai argumen pertama. Kode diatur ke 256 ketika layanan dimatikan karena sinyal yang tidak tertangkap. Script perlu menulis kode keluar terakhir ke /run/s6-linux-init-container-results/exitcode; s6-overlay membaca file ini dan keluar dengan nilai di dalamnya, menyebabkan kode tersebut digunakan sebagai kode stop container Anda.
#!/bin/sh
echo "$1" > /run/s6-linux-init-container-results/exitcode
Kapan Anda Harus Menjalankan Beberapa Proses Dalam Kontainer?
Teknik ini paling baik digunakan dengan proses yang digabungkan secara erat yang tidak dapat Anda pisahkan untuk dijalankan sebagai kontainer independen. Anda mungkin memiliki program yang bergantung pada utilitas pembantu latar belakang atau aplikasi monolitik yang melakukan manajemen proses individualnya sendiri. Teknik yang ditunjukkan di atas dapat membantu Anda menyimpan jenis perangkat lunak ini.
Menjalankan banyak proses dalam wadah tetap harus dihindari sedapat mungkin. Berpegang pada satu proses latar depan memaksimalkan isolasi, mencegah komponen saling mengganggu, dan meningkatkan kemampuan Anda untuk men-debug dan menguji bagian tertentu. Anda dapat menskalakan komponen satu per satu menggunakan orkestra penampung, yang memberi Anda fleksibilitas untuk menjalankan lebih banyak instans dari proses paling intensif sumber daya.
Kesimpulan
Containers biasanya memiliki satu proses latar depan dan berjalan selama proses tersebut masih hidup. Model ini selaras dengan praktik terbaik containerisasi dan memungkinkan Anda memperoleh manfaat maksimal dari teknologi.
Dalam beberapa situasi, Anda mungkin memerlukan beberapa proses untuk dijalankan dalam sebuah container. Karena semua gambar pada akhirnya memiliki satu titik masuk, Anda harus menulis skrip pembungkus atau menambahkan manajer proses yang bertanggung jawab untuk memulai binari target Anda.
Manajer proses memberi Anda semua yang Anda butuhkan tetapi mengasapi gambar Anda dengan paket dan konfigurasi tambahan. Skrip pembungkus lebih sederhana tetapi mungkin perlu dipasangkan dengan flag --init Docker untuk mencegah proliferasi proses zombie.
Itulah berita seputar
Cara Menjalankan Beberapa Layanan Dalam Satu Kontainer Docker, semoga bermanfaat.
Disadur dari HowToGeek.com.