Docker kapsayıcısında birden fazla program çalıştırabilir miyim?


150

Masaüstünde kullanıcılar üzerinde çalışmayı amaçlayan bir uygulamayı dağıtma noktasından başımı Docker'a sarmaya çalışıyorum. Benim uygulama sadece bir şişesi web uygulaması ve mongo veritabanı. Normalde hem sanal makineye hem de ana bilgisayar bağlantı noktasını konuk web uygulamasına iletirim. Docker'ı denemek istiyorum ama birden fazla programı nasıl kullanacağımı bilmiyorum. Belgelerde sadece ENTRYPOINT olabileceği için Mongo ve şişe uygulamamı nasıl alabilirim. Yoksa ayrı kaplarda olmaları mı gerekiyor, bu durumda birbirleriyle nasıl konuşurlar ve bu uygulamayı dağıtmayı nasıl kolaylaştırır?


2
(? Tekli süreç ..): Spot on .. liman işçisi kadar popüler oldu bana neden meraklandırıyor - ama izin verdiği cevaplar .. bize ne bakınız
javadba

Yanıtlar:


120

Yalnızca bir ENTRYPOINT olabilir, ancak bu hedef genellikle gereken sayıda program başlatan bir komut dosyasıdır. Ayrıca tek bir kapsayıcı içinde birden fazla hizmet başlatmaya özen göstermek için örneğin Süpervizör veya benzerlerini kullanabilirsiniz. Bu, mysql, apache ve wordpress'i tek bir kapta çalıştıran bir liman işçisi konteynır örneğidir .

Diyelim ki, tek bir web uygulaması tarafından kullanılan bir veritabanınız var. Sonra her ikisini de tek bir kapta çalıştırmak daha kolaydır.

Birden fazla uygulama tarafından kullanılan paylaşılan bir veritabanınız varsa, veritabanını kendi kapsayıcısında ve uygulamaları kendi kapsayıcılarında çalıştırmak daha iyi olur.

Uygulamaların farklı kaplarda çalışırken birbirleriyle nasıl iletişim kurabileceği en az iki olasılık vardır:

  1. Açık IP portlarını kullanın ve bu portlardan bağlanın.
  2. Son docker sürümleri bağlanmayı destekler .

1
Docker'ın yeni sürümlerinin artık Docker konteyner ağlarını desteklediği anlaşılıyor .
jpierson

Docker şimdi vb sonra otomatik = true, stdout_logfile, stderr_logfile bir göz atın olarak her işlem için davranışını sepcify için izin Amiri çalıştırmak için destekler docs.docker.com/engine/admin/using_supervisord
Andreas Lundgren

5
Kesinlikle bu örnekte aynı kapta web uygulamasını ve mongodb çalıştırmayı denemenizi tavsiye etmem. Docker'da süpervizör veya benzer init benzeri süreçlerin iyi kullanım durumları vardır, ancak bu bunların bir parçası değildir. İki hizmeti ayrı kaplarda çalıştırmak için docker-compose kullanmak çok daha kolaydır.
nicolas-van

@ nicolas-van neden daha basit? Çünkü db ölürse, her şeyi yeniden başlatmak yerine db'nin kapsayıcısını yeniden başlatabilir miyim?
brillout

Aynı makinedeki uygulamalar aynı zamanda Unix etki alanı soketleri üzerinden de iletişim kurabilir . En yüksek performans garantisi.
Şüpheci Jule

21

Bir LAMP yığını, Mongo DB ve kendi hizmetlerimi çalıştırmak için benzer bir gereklilik vardı

Docker, OS tabanlı sanallaştırmadır, bu nedenle kapsayıcısını çalışan bir işlem etrafında izole eder, bu nedenle FOREGROUND'da çalışan en az bir işlem gerektirir.

Böylece, başlangıç ​​noktası olarak kendi başlangıç ​​komut dosyanızı sağlarsınız , böylece başlangıç ​​komut dosyanız genişletilmiş bir Docker görüntü komut dosyası haline gelir.

Bu yüzden Docker görüntü dosyamın sonunda iki satır var:

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

Senaryomda tüm MySQL, MongoDB, Tomcat vb. Çalıştırıyorum. Sonunda Apache'mi ön plan olarak çalıştırıyorum.

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

Bu, tüm hizmetlerimi başlatmamı ve son hizmet ön planda olmaya başlayarak kapsayıcıyı canlı tutmamı sağlıyor

Umarım yardımcı olur

GÜNCELLEME : Bu soruyu en son yanıtladığımdan beri, Docker compose gibi her şey kendi kapsayıcısında çalıştırmanıza yardımcı olabilir, ancak hepsini bu hizmetler arasında bağımlılıklar olarak birbirine bağlayabilir, docker-compose ve kullanın, ihtiyaçlarınız onunla uyuşmadıkça daha zarif bir yoldur.


6

Her iki hizmeti de aynı kapta çalıştırmayı öneren bazı önceki çözümlere kesinlikle katılmıyorum. Belgelerde tavsiye edilmediği açıkça belirtilmiştir :

Genel olarak, ilgilenilen alanları her kapta bir hizmet kullanarak ayırmanız önerilir. Bu hizmet birden çok işleme ayrılabilir (örneğin, Apache web sunucusu birden çok çalışan işlemi başlatır). Birden çok işleme sahip olmak sorun değil, ancak Docker'dan en iyi faydayı elde etmek için, bir kapsayıcısının genel uygulamanızın birden çok yönünden sorumlu olmasını önleyin. Kullanıcı tanımlı ağları ve paylaşılan birimleri kullanarak birden çok kapsayıcı bağlayabilirsiniz.

Süpervizör veya benzeri programlar için iyi kullanım durumları vardır, ancak bir web uygulaması + veritabanı çalıştırmak bunların bir parçası değildir.

Bunu yapmak için kesinlikle docker-compose kullanmalı ve farklı sorumluluklara sahip birden fazla kap düzenlemelisiniz.


2
Bu bir yorum, cevap değil. Lütfen bu konumu desteklemek için bir açıklama ve / veya bağlantılar eklemeyi düşünün. Aksi takdirde yardımcı olmaz.
Ivan Ivanov

1
Bu, böyle bir kullanım durumunda verebileceğim en iyi tavsiyenin docker-compose kullanmak olduğu yönündeki bir cevaptır. Her neyse, resmi önerilere daha fazla bağlantı verebileceğim konusunda haklısın. Bunu güncelleyeceğim.
nicolas-van

Soru, 2 işlemin bir kapta çalıştırılmasıyla ilgilidir, bu nedenle en iyi uygulamaları umursamaz. Size bir örnek vereceğim: PhotonOS tabanlı görüntü ve bir java işlemi içinde rabbitmq çalıştırmak zorunda kaldım ... Bu yüzden bir giriş komut dosyası kullandım ve ENTRYPOINT olarak kullandım :)
Vallerious

Orijinal soru, iki işlemi bir Docker kapsayıcısında çalıştırmanın teknik fizibilitesi hakkında genel bir soru değildir. MongoDB veritabanı ile birlikte bir Python uygulamasının konuşlandırılması olan özel bir kullanım durumunu belirtir. Ve bu kullanım durumunda, en iyi öneri, tek bir konteynerin kullanımını engellemek ve liman işçiliği-bestelemeyi önermektir.
nicolas-van

5

Ayrı kaplarda olabilirler ve gerçekten de uygulamanın daha büyük bir ortamda çalışması amaçlanıyorsa, muhtemelen olacaktır.

Çok konteynerli bir sistem, gerekli tüm bağımlılıkları getirebilmek için biraz daha düzenleme gerektirecektir, ancak Docker v0.6.5 + 'da, Docker'ın içine yerleştirilmiş olana yardımcı olacak yeni bir tesis var - Bağlama . Çok makineli bir çözümle, Docker ortamının dışından düzenlenmesi gereken bir şey.

İki farklı kapsayıcıyla, iki parça hala TCP / IP üzerinden iletişim kurar, ancak bağlantı noktaları özel olarak kilitlenmedikçe (birden fazla kopya çalıştıramayacağınız için önerilmez), yeni bağlantı noktasını geçmeniz gerekir veritabanının uygulamaya yönelik olarak açığa çıkarılması, böylece Mongo ile iletişim kurabilmesi. Bu yine, Linking'in yardımcı olabileceği bir şey.

Tüm bağımlılıkların aynı kapta gittiği daha basit, küçük bir kurulum için, başlangıçta ENTRYPOINT olarak adlandırılan program tarafından hem veritabanı hem de Python çalışma zamanının başlatılması da mümkündür. Bu bir kabuk betiği veya başka bir işlem denetleyicisi kadar basit olabilir - Süpervizör oldukça popülerdir ve halka açık Docker dosyalarında birkaç örnek vardır.


3

İki kap kullanmanın tercih edilebilir olduğuna dair diğer cevaplara katılıyorum, ancak kalbinizi birden fazla hizmeti tek bir kapta bir araya getirmeye ayarladıysanız, denetleyici gibi bir şey kullanabilirsiniz.

içinde Hipache örneğin dahil Dockerfile supervisord çalışır ve hipache ve Redis sunucu hem de dosya supervisord.conf belirtir çalıştırılacak.


2

Docker bunun nasıl yapılacağı ile ilgili birkaç örnek sunar . Hafif seçenek:

Tüm komutlarınızı, test ve hata ayıklama bilgileriyle birlikte bir sarıcı komut dosyasına koyun. Sarıcı komut dosyasını olarak çalıştırın CMD. Bu çok naif bir örnek. İlk olarak, sarıcı komut dosyası:

#!/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

Ardından 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

2

Tuşunu kullanarak 2 işlemi ön planda çalıştırabilirsiniz wait. Sadece aşağıdaki içeriğe sahip bir bash betiği oluşturun. Örn start.sh:

# runs 2 commands simultaneously:

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

Dockerfile dosyasında,

CMD bash start.sh

0

Adanmış bir komut dosyası çok fazla yük gibi görünüyorsa, açıkça ayrı işlemler oluşturabilirsiniz sh -c. Örneğin:

CMD sh -c 'mini_httpd -C /my/config -D &' \
 && ./content_computing_loop
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.