Cara Menjalankan Beberapa Layanan Dalam Satu Kontainer Docker
Diterbitkan: 2022-06-30Docker adalah teknologi untuk mengemas komponen tumpukan Anda sebagai wadah yang terisolasi. Ini adalah praktik umum untuk menjalankan setiap proses Anda dalam wadahnya sendiri, menciptakan pemisahan yang bersih antar komponen. Ini meningkatkan modularitas dan memungkinkan Anda mengakses manfaat skalabilitas containerisasi.
Masih ada situasi di mana Anda ingin menjalankan beberapa layanan dalam satu wadah. 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.
Mengidentifikasi Masalah
Kontainer Docker 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 secara otomatis berhenti ketika proses latar depan mereka keluar.
Anda dapat meluncurkan proses lain dari CMD
tetapi wadah hanya akan tetap berjalan saat proses latar depan asli masih hidup. Menjaga kontainer tetap beroperasi melalui masa pakai gabungan dari dua layanan independen tidak dapat dilakukan secara langsung menggunakan mekanisme ENTRYPOINT/CMD
.
Membungkus Beberapa Proses dalam Satu Titik Masuk
Skrip pembungkus adalah solusi paling sederhana untuk masalah ini. 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 penampung, menjaga penampung tetap berjalan hingga salah satu skrip yang dibungkus keluar.
#!/bin/bash /opt/proses pertama & /opt/proses kedua & tunggu -n keluar $?
Skrip ini memulai binari /opt/first-process
dan /opt/second-process
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 sudah jadi.
Model ini menghasilkan wadah yang menjalankan first-process
second-process
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 penampung:
ENTRYPOINT ["/bin/sh"] CMD ["./path/ke/script.sh"]
Opsi Kontainer --init
Salah satu tantangan dalam mengelola proses container adalah membersihkan secara efektif saat proses tersebut 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 wadah Anda.
Perintah docker run
memiliki flag --init
yang memodifikasi entrypoint untuk menggunakan tini
sebagai PID 1. Ini adalah implementasi proses init minimal yang menjalankan CMD
Anda, menangani penerusan sinyal, dan terus-menerus menuai zombie.
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 upstart
.
Menggunakan Manajer Proses Khusus
Pembuatan 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 pilihan yang tersedia ketika 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] perintah=/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 saat container dimulai.
DARI ubuntu: terbaru JALANKAN apt-get install -y apache2 mysql-server supervisor SALIN supervisord.conf /etc/supervisor/conf.d/supervisord.conf ENTRYPOINT ["/bin/sh"] CMD ["/usr/bin/pengawas"]
Karena supervisord
berjalan terus-menerus, container 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
:
# Tambahkan s6-overlay ke gambar Anda TAMBAHKAN https://github.com/just-containers/s6-overlay/releases/download/v3.1.0.0/s6-overlay-noarch.tar.xz /tmp JALANKAN tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz JALANKAN printf "#!/bin/shn/usr/sbin/Apache2 -DFOREGROUND"> /etc/services.d/first-service/run JALANKAN chmod +x /etc/services.d/first-service/run # Gunakan s6-overlay sebagai titik masuk gambar Anda ENTRYPOINT ["/init"]
Anda dapat menambahkan skrip finish
yang dapat dieksekusi di dalam direktori layanan Anda untuk menangani penghentian wadah dengan docker stop
. s6-overlay
akan secara otomatis menjalankan skrip ini ketika prosesnya menerima sinyal TERM
karena perintah stop
.
Skrip akhir menerima kode keluar dari layanan mereka sebagai argumen pertama mereka. 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 erat yang tidak dapat Anda pisahkan untuk dijalankan sebagai wadah 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 menampung jenis perangkat lunak ini.
Menjalankan beberapa proses dalam sebuah wadah tetap harus dihindari sedapat mungkin. Berpegang teguh 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 Anda.
Kesimpulan
Kontainer biasanya memiliki satu proses latar depan dan berjalan selama 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 wadah. 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.
Pengelola 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.