Saya telah membangun gambar dasar dari Dockerfile bernama centos + ssh. Di Dockerfile centos + ssh, saya menggunakan CMD untuk menjalankan layanan ssh.
Kemudian saya ingin membangun image menjalankan layanan lain bernama rabbitmq, Dockerfile:
FROM centos+ssh
EXPOSE 22
EXPOSE 4149
CMD /opt/mq/sbin/rabbitmq-server start
Untuk memulai wadah kelinci , jalankan :
docker run -d -p 222:22 -p 4149:4149 rabbitmq
tetapi layanan ssh tidak berfungsi, ini merasakan Dockerfile CMD dari Rabbitmq menggantikan CMD centos.
- Bagaimana CMD bekerja di dalam image buruh pelabuhan?
- Jika saya ingin menjalankan banyak layanan, bagaimana caranya? Menggunakan supervisor?
Anda benar, Dockerfile kedua akan menimpa
CMD
perintah yang pertama. Docker akan selalu menjalankan satu perintah, tidak lebih. Jadi di akhir Dockerfile Anda, Anda dapat menentukan satu perintah untuk dijalankan. Tidak lebih.Tetapi Anda dapat menjalankan kedua perintah dalam satu baris:
Apa yang juga dapat Anda lakukan untuk membuat Dockerfile Anda sedikit lebih bersih, Anda dapat meletakkan perintah CMD Anda ke file tambahan:
Dan file seperti ini:
sumber
&&
teknik hanya akan bekerja dengan layanan non-interaktif (yang dapat dimulai di latar belakang) jika tidak, hanya layanan pertama yang akan berjalan.Sementara saya menghormati jawaban dari qkrijger yang menjelaskan bagaimana Anda dapat mengatasi masalah ini, saya pikir masih banyak lagi yang dapat kita pelajari tentang apa yang terjadi di sini ...
Untuk benar-benar menjawab pertanyaan Anda tentang " mengapa " ... Saya pikir akan sangat membantu bagi Anda untuk memahami cara kerja
docker stop
perintah dan bahwa semua proses harus dimatikan dengan bersih untuk mencegah masalah ketika Anda mencoba untuk memulai ulang (file korupsi dll).Masalah: Bagaimana jika buruh pelabuhan benar-benar memulai SSH dari perintahnya dan memulai RabbitMQ dari file Docker Anda? " Perintah docker stop mencoba menghentikan container yang sedang berjalan terlebih dahulu dengan mengirimkan sinyal SIGTERM ke proses root (PID 1) di container. " Proses manakah yang merupakan pelacakan buruh pelabuhan sebagai PID 1 yang akan mendapatkan SIGTERM? Apakah itu SSH atau Rabbit ?? "Menurut model proses Unix, proses init - PID 1 - mewarisi semua proses anak yatim piatu dan harus menuai semuanya. Sebagian besar container Docker tidak memiliki proses init yang melakukan ini dengan benar, dan akibatnya container mereka terisi dengan proses zombie dari waktu ke waktu. "
Jawaban: Docker hanya mengambil bahwa CMD lalu sebagai salah satu yang akan mendapatkan diluncurkan sebagai proses akar dengan PID 1 dan mendapatkan SIGTERM dari
docker stop
.Solusi yang disarankan: Anda harus menggunakan (atau membuat) gambar dasar yang khusus dibuat untuk menjalankan lebih dari satu layanan, seperti phusion / baseimage
Penting untuk dicatat bahwa tini ada persis karena alasan ini, dan pada Docker 1.13 dan yang lebih baru, tini secara resmi merupakan bagian dari Docker, yang memberi tahu kita bahwa menjalankan lebih dari satu proses di Docker IS VALID .. bahkan jika seseorang mengklaim menjadi lebih terampil tentang Docker, dan bersikeras bahwa Anda tidak masuk akal karena berpikir untuk melakukan ini, ketahuilah bahwa Anda tidak. Ada situasi yang benar-benar valid untuk melakukannya.
Senang mendengarnya:
sumber
Jawaban buruh pelabuhan resmi untuk Menjalankan beberapa layanan dalam satu wadah .
Ini menjelaskan bagaimana Anda dapat melakukannya dengan sistem init (systemd, sysvinit, pemula), script (
CMD ./my_wrapper_script.sh
) atau supervisor sejenisnyasupervisord
.The
&&
solusi dapat bekerja hanya untuk layanan yang dimulai di latar belakang (daemon) atau yang akan mengeksekusi cepat tanpa interaksi dan melepaskan prompt. Melakukan ini dengan layanan interaktif (yang membuat prompt) dan hanya layanan pertama yang akan dimulai.sumber
Untuk mengatasi mengapa CMD dirancang untuk menjalankan hanya satu layanan per kontainer, mari kita sadari apa yang akan terjadi jika server sekunder yang dijalankan dalam kontainer yang sama bukanlah hal sepele / tambahan tetapi "utama" (misalnya penyimpanan yang dibundel dengan aplikasi frontend). Sebagai permulaan, ini akan memecah beberapa fitur penampungisasi penting seperti penskalaan horizontal (otomatis) dan penjadwalan ulang antar node, keduanya mengasumsikan hanya ada satu aplikasi (sumber beban CPU) per penampung. Lalu ada masalah kerentanan - lebih banyak server yang terekspos dalam satu wadah berarti lebih sering menambal CVE ...
Jadi mari kita akui bahwa ini adalah 'dorongan' dari perancang Docker (dan Kubernetes / Openhift) menuju praktik yang baik dan kami tidak boleh menemukan kembali solusi (SSH tidak diperlukan - kami telah
docker exec / kubectl exec / oc rsh
merancang untuk menggantinya)./devops/447/why-it-is-recommended-to-run-only-one-process-in-a-container
sumber