Bisakah saya menjalankan banyak program dalam wadah Docker?

150

Saya mencoba untuk membungkus kepala saya di sekitar Docker dari titik menyebarkan aplikasi yang dimaksudkan untuk dijalankan pada pengguna di desktop. Aplikasi saya hanyalah sebuah aplikasi web flask dan database mongo. Biasanya saya akan menginstal keduanya dalam VM dan, meneruskan port host ke aplikasi web tamu. Saya ingin mencoba Docker tetapi saya tidak yakin bagaimana saya seharusnya menggunakan lebih dari satu program. Dokumentasi mengatakan hanya ada ENTRYPOINT jadi bagaimana saya bisa memiliki Mongo dan aplikasi labu saya. Atau apakah mereka perlu berada di wadah yang terpisah, dalam hal bagaimana mereka berbicara satu sama lain dan bagaimana hal ini membuat pendistribusian aplikasi menjadi mudah?

nickponline
sumber
2
Spot on: membuat saya bertanya-tanya mengapa buruh pelabuhan sangat populer .. (proses tunggal ..?) - tapi mari kita lihat apa yang dikatakan jawabannya ..
javadba

Jawaban:

120

Mungkin hanya ada satu ENTRYPOINT, tetapi target itu biasanya adalah skrip yang meluncurkan sebanyak mungkin program yang diperlukan. Anda juga dapat menggunakan misalnya Supervisord atau yang serupa untuk mengurus peluncuran beberapa layanan di dalam satu wadah. Ini adalah contoh dari wadah buruh pelabuhan menjalankan mysql, apache dan wordpress dalam satu wadah .

Katakanlah, Anda memiliki satu database yang digunakan oleh satu aplikasi web. Maka mungkin lebih mudah untuk menjalankan keduanya dalam satu wadah.

Jika Anda memiliki database bersama yang digunakan oleh lebih dari satu aplikasi, maka akan lebih baik untuk menjalankan database dalam wadahnya masing-masing dan aplikasi masing-masing dalam wadah mereka sendiri.

Setidaknya ada dua kemungkinan bagaimana aplikasi dapat berkomunikasi satu sama lain ketika mereka berjalan dalam wadah yang berbeda:

  1. Gunakan port IP terbuka dan hubungkan melalui mereka.
  2. Versi buruh pelabuhan terbaru mendukung penautan .
Vesako
sumber
1
Sepertinya versi baru Docker sekarang mendukung jaringan kontainer Docker .
jpierson
Docker sekarang mendukung untuk menjalankan Supervisor, memungkinkan Anda untuk memisahkan perilaku untuk setiap proses seperti autorestart = true, stdout_logfile, stderr_logfile dll. Lihatlah docs.docker.com/engine/admin/using_supervisord
Andreas Lundgren
4
Saya pasti tidak akan merekomendasikan untuk mencoba menjalankan aplikasi web dan mongodb dalam wadah yang sama dalam contoh ini. Ada beberapa kasus penggunaan yang baik dari supervisord atau proses mirip-init serupa di Docker tetapi ini bukan bagian dari mereka. Lebih mudah menggunakan komposisi buruh pelabuhan untuk menjalankan kedua layanan dalam wadah terpisah.
nicolas-van
@ nicolas-van kenapa lebih sederhana? Apakah karena jika db mati saya kemudian dapat memulai ulang wadah db daripada harus me-restart semuanya?
brillout
Aplikasi pada mesin yang sama juga dapat berkomunikasi melalui soket domain Unix . Dijamin kinerja tertinggi.
Skeptical Jule
21

Saya memiliki persyaratan yang sama untuk menjalankan tumpukan LAMP, Mongo DB, dan layanan saya sendiri

Docker adalah virtualisasi berbasis OS, itulah sebabnya ia mengisolasi wadahnya di sekitar proses yang sedang berjalan, oleh karena itu membutuhkan setidaknya satu proses yang berjalan di FOREGROUND.

Jadi, Anda memberikan skrip startup Anda sendiri sebagai titik masuk, sehingga skrip startup Anda menjadi skrip gambar Docker yang diperluas, di mana Anda dapat menumpuk sejumlah layanan sejauh SETIDAKNYA SATU LAYANAN TERLALU MULAI YANG DIMULAI, YANG TERLALU MENUJU AKHIR

Jadi file gambar Docker saya memiliki dua baris di bawah ini pada akhirnya:

COPY myStartupScript.sh /usr/local/myscripts/myStartupScript.sh
CMD ["/bin/bash", "/usr/local/myscripts/myStartupScript.sh"]

Dalam skrip saya, saya menjalankan semua MySQL, MongoDB, Tomcat dll. Pada akhirnya saya menjalankan Apache saya sebagai utas foreground.

source /etc/apache2/envvars
/usr/sbin/apache2 -DFOREGROUND

Ini memungkinkan saya untuk memulai semua layanan saya dan menjaga wadah tetap hidup dengan layanan terakhir mulai di latar depan

Semoga ini bisa membantu

UPDATE : Sejak saya terakhir menjawab pertanyaan ini, hal-hal baru telah muncul seperti penulisan Docker , yang dapat membantu Anda menjalankan setiap layanan pada wadahnya sendiri, namun mengikat semuanya bersama-sama sebagai dependensi di antara layanan-layanan tersebut, cobalah mengetahui lebih lanjut tentang komposisi docker dan gunakan, itu cara yang lebih elegan kecuali jika kebutuhan Anda tidak cocok dengannya.

Basav
sumber
6

Saya sangat tidak setuju dengan beberapa solusi sebelumnya yang merekomendasikan untuk menjalankan kedua layanan dalam wadah yang sama. Itu jelas dinyatakan dalam dokumentasi bahwa itu tidak direkomendasikan :

Umumnya disarankan agar Anda memisahkan area yang menjadi perhatian dengan menggunakan satu layanan per kontainer. Layanan itu dapat bercabang menjadi beberapa proses (misalnya, server web Apache memulai beberapa proses pekerja). Tidak masalah memiliki banyak proses, tetapi untuk mendapatkan manfaat maksimal dari Docker, hindari satu wadah yang bertanggung jawab atas banyak aspek dari keseluruhan aplikasi Anda. Anda dapat menghubungkan beberapa wadah menggunakan jaringan yang ditentukan pengguna dan volume bersama.

Ada beberapa kasus penggunaan yang baik untuk pengawas atau program serupa tetapi menjalankan aplikasi web + database bukan bagian dari mereka.

Anda harus menggunakan komposisi buruh pelabuhan untuk melakukan itu dan mengatur banyak wadah dengan tanggung jawab berbeda.

nicolas-van
sumber
2
Ini adalah komentar, bukan jawaban. Silakan pertimbangkan untuk menambahkan penjelasan dan / atau tautan untuk mendukung posisi ini. Kalau tidak, itu tidak membantu.
Ivan Ivanov
1
Ini adalah jawaban dalam arti bahwa rekomendasi terbaik yang dapat saya berikan dalam use case adalah menggunakan komposisi buruh pelabuhan. Bagaimanapun, Anda benar bahwa saya bisa memberikan lebih banyak tautan ke rekomendasi resmi. Saya akan memperbarui itu.
nicolas-van
Pertanyaannya adalah menjalankan 2 proses dalam satu wadah, sehingga tidak peduli dengan praktik terbaik. Saya akan memberi Anda sebuah contoh: Saya harus menjalankan rabbitmq di dalam gambar berbasis PhotonOS dan juga proses java ... Jadi saya menggunakan skrip entri dan digunakan sebagai ENTRYPOINT :)
Vallerious
Pertanyaan asli bukanlah pertanyaan umum tentang kelayakan teknis menjalankan dua proses dalam wadah Docker. Ini menyatakan kasus penggunaan khusus yang merupakan penyebaran aplikasi Python bersama dengan database MongoDB. Dan, untuk kasus penggunaan itu, rekomendasi terbaik adalah untuk mencegah penggunaan wadah tunggal dan merekomendasikan penggunaan komposisi buruh pelabuhan.
nicolas-van
5

Mereka bisa berada di wadah yang terpisah, dan memang, jika aplikasi itu juga dimaksudkan untuk berjalan di lingkungan yang lebih besar, mereka mungkin akan melakukannya.

Sistem multi-kontainer akan membutuhkan lebih banyak orkestrasi untuk dapat memunculkan semua dependensi yang diperlukan, meskipun dalam Docker v0.6.5 +, ada fasilitas baru untuk membantu dengan yang dibangun ke dalam Docker itu sendiri - Menghubungkan . Dengan solusi multi-mesin, masih ada sesuatu yang harus diatur dari luar lingkungan Docker.

Dengan dua wadah yang berbeda, kedua bagian masih berkomunikasi melalui TCP / IP, tetapi kecuali jika port telah dikunci secara khusus (tidak disarankan, karena Anda tidak dapat menjalankan lebih dari satu salinan), Anda harus melewati port baru bahwa database telah terpapar ke aplikasi, sehingga dapat berkomunikasi dengan Mongo. Ini lagi, sesuatu yang bisa dibantu oleh Linking.

Untuk instalasi yang lebih sederhana dan kecil, di mana semua dependensi berada dalam wadah yang sama, memiliki kedua database dan runtime Python dimulai oleh program yang awalnya disebut sebagai ENTRYPOINT juga dimungkinkan. Ini bisa sesederhana skrip shell, atau pengontrol proses lainnya - Supervisord cukup populer, dan sejumlah contoh ada di Dockerfiles publik.

Alister Bulman
sumber
3

Saya setuju dengan jawaban lain bahwa menggunakan dua wadah lebih disukai, tetapi jika Anda memiliki hati untuk menggabungkan beberapa layanan dalam satu wadah Anda dapat menggunakan sesuatu seperti pengawas.

di Hipache misalnya, termasuk Dockerfile berjalan supervisord, dan menspesifikasikan berkas supervisord.conf untuk kedua hipache dan Redis-server yang akan dijalankan.

ben schwartz
sumber
2

Docker memberikan beberapa contoh tentang cara melakukannya. Pilihan ringan adalah:

Masukkan semua perintah Anda dalam skrip wrapper, lengkap dengan informasi pengujian dan debugging. Jalankan skrip pembungkus sebagai milik Anda CMD. Ini adalah contoh yang sangat naif. Pertama, skrip wrapper:

#!/bin/bash

# Start the first process
./my_first_process -D
status=$?
if [ $status -ne 0 ]; then
  echo "Failed to start my_first_process: $status"
  exit $status
fi

# Start the second process
./my_second_process -D
status=$?
if [ $status -ne 0 ]; then
  echo "Failed to start my_second_process: $status"
  exit $status
fi

# Naive check runs checks once a minute to see if either of the processes exited.
# This illustrates part of the heavy lifting you need to do if you want to run
# more than one service in a container. The container will exit with an error
# if it detects that either of the processes has exited.
# Otherwise it will loop forever, waking up every 60 seconds

while /bin/true; do
  ps aux |grep my_first_process |grep -q -v grep
  PROCESS_1_STATUS=$?
  ps aux |grep my_second_process |grep -q -v grep
  PROCESS_2_STATUS=$?
  # If the greps above find anything, they will exit with 0 status
  # If they are not both 0, then something is wrong
  if [ $PROCESS_1_STATUS -ne 0 -o $PROCESS_2_STATUS -ne 0 ]; then
    echo "One of the processes has already exited."
    exit -1
  fi
  sleep 60
done

Berikutnya, Dockerfile:

FROM ubuntu:latest
COPY my_first_process my_first_process
COPY my_second_process my_second_process
COPY my_wrapper_script.sh my_wrapper_script.sh
CMD ./my_wrapper_script.sh
OzNetNerd
sumber
2

Anda dapat menjalankan 2 proses di latar depan dengan menggunakan wait. Buat skrip bash dengan konten berikut. Misalnya start.sh:

# runs 2 commands simultaneously:

mongod & # your first application
P1=$!
python script.py & # your second application
P2=$!
wait $P1 $P2

Di Dockerfile Anda, mulai dengan

CMD bash start.sh
Sam
sumber
0

Jika skrip khusus sepertinya terlalu banyak overhead, Anda dapat menelurkan proses terpisah secara eksplisit sh -c. Sebagai contoh:

CMD sh -c 'mini_httpd -C /my/config -D &' \
 && ./content_computing_loop
Raphael
sumber