Docker konteyneri neden hemen çıkıyor


239

Kullanarak arka planda bir kap çalıştırın

 docker run -d --name hadoop h_Service

çabuk çıkar. Ama eğer ön planda koşarsam iyi çalışır. Kullanarak günlükleri kontrol ettim

docker logs hadoop

hata yoktu. Herhangi bir fikir?

DOCKERFILE

 FROM java_ubuntu_new
 RUN wget http://archive.cloudera.com/cdh4/one-click-install/precise/amd64/cdh4-repository_1.0_all.deb
 RUN dpkg -i cdh4-repository_1.0_all.deb
 RUN curl -s http://archive.cloudera.com/cdh4/ubuntu/precise/amd64/cdh/archive.key | apt-key add -
 RUN  apt-get update
 RUN apt-get install -y hadoop-0.20-conf-pseudo
 RUN dpkg -L hadoop-0.20-conf-pseudo
 USER hdfs
 RUN hdfs namenode -format
 USER root
 RUN apt-get install -y sudo
 ADD . /usr/local/
 RUN chmod 777 /usr/local/start-all.sh
 CMD ["/usr/local/start-all.sh"]

start-all.sh

 #!/usr/bin/env bash
 /etc/init.d/hadoop-hdfs-namenode start
 /etc/init.d/hadoop-hdfs-datanode start
 /etc/init.d/hadoop-hdfs-secondarynamenode start
 /etc/init.d/hadoop-0.20-mapreduce-tasktracker start
 sudo -u hdfs hadoop fs -chmod 777 /
 /etc/init.d/hadoop-0.20-mapreduce-jobtracker start
 /bin/bash

1
Altın kural, limanlaştırılmış sunucularınızın arka plana geçmesini önlemenizdir. Sunucu paketlerinin çoğu, arka planın normal durumda olması nedeniyle bunları ön planda zorlama seçeneklerine sahiptir.
Arnaud Meuret

Yapmayı umduğunuz her chmod 777şey güvensiz ve yanlıştır. Aklı başında izinlere geri dönmelisiniz (bu durumda muhtemelen 755).
üçlü

Yanıtlar:


125

Docker konteyneri, ana işlemi bittiğinde çıkar.

Bu durumda start-all.shkomut dosyanız sona erdiğinde çıkacaktır . Bu durumda size nasıl yapılacağını anlatacak hadoop hakkında yeterli bilgim yok, ancak ya ön planda çalışan bir şey bırakmanız ya da işlemleri çalıştırmak için runit ya da supervisord gibi bir işlem yöneticisi kullanmanız gerekiyor.

Bence eğer bunu belirtmezseniz -d, çalışma konusunda yanılmış olmalısınız ; tamamen aynı etkiye sahip olmalıdır. Biraz farklı bir komutla veya -itbazı şeyleri değiştirecek şekilde kullanarak başlattığınızdan şüpheleniyorum .

Basit bir çözüm aşağıdaki gibi bir şey eklemek olabilir:

while true; do sleep 1000; done

betiğin sonuna kadar. Ancak bunu sevmiyorum, çünkü senaryo gerçekten başladığı süreçleri izliyor olmalı.

(Bu kodu https://github.com/sequenceiq/hadoop-docker/blob/master/bootstrap.sh adresinden çaldığımı söylemeliyim )


218

Bu benim için hile yaptı:

docker run -dit ubuntu

Bundan sonra, aşağıdakileri kullanarak çalışan işlemleri kontrol ettim:

docker ps -a

Kabı tekrar takmak için

docker attach CONTAINER_NAME

İPUCU: Konteyner tipini durdurmadan çıkmak için: ^P^Q


15
@Tommy, docs.docker.com/engine/reference/commandline/run -d adresinden --detach Ayrılmış mod: arka planda komut çalıştır, -i, - etkileşimli STDIN'i takılı olmasa bile açık tutun, -t, - -tty Bir sözde TTY tahsis etmek -ditsadece steno olduğunu

3
@ am17torres doğru, üzgünüm kafa karıştırıcı sorumu açıklığa kavuşturayım; d ayrılmıştır ve i etkileşimlidir, bu yüzden d ve i kombinasyonu bana kafa karıştırıcıdır. Ben d bir arka plan (etkileşimli olmayan) süreç olarak başlatmak olduğunu düşündüm.
Tommy

2
@Tommy Bu seçenekler birleştirildiğinde, kapsayıcı arka planda etkileşimli moda girer .
Yon

2
@Tommy, @ am17torres -di, düşük gerekliliktir -tile kullanıldığında seçenek gereksiz -değer doğru anlamak
Renaud

2
Aslında, -tetkinleştirmeden yeniden bağlarsanız isteminizi göremezsiniz ... ancak execher fark edemediğimde genellikle yeni bir bash olduğum için. Bir mac'tan ayrılırken sorun yaşadım ama belki de bunu yanlış yapıyorum ..
Renaud

65

Kampçı tarafından sözü edilen cevabı iyileştirmek ya da genişletmeye cesaret etmek istiyorum

Koştuğunda

docker run -dit ubuntu

temel olarak kapsayıcıyı arka planda etkileşimli modda çalıştırıyorsunuz.

Kapsayıcıyı CTRL + D (bunu yapmanın en yaygın yolu) ile ekleyip çıktığınızda, kapsayıcıyı durdurursunuz çünkü kapınızı başlattığınız ana işlemi yukarıdaki komutla yeni öldürdünüz.

Halihazırda çalışan bir konteynırdan yararlanarak, bash'ın başka bir sürecini çatallayabilir ve çalıştırarak sahte bir TTY alırım:

docker exec -it <container ID> /bin/bash

29

Ne zaman bir kapsayıcı komut dosyası yürütme bittikten sonra kadar kalmak istiyorum eklemek

&& tail -f /dev/null

komutun sonunda. Bu yüzden olmalı:

/usr/local/start-all.sh && tail -f /dev/null

19

Docker konteyneri neden hemen çıkıyor?

Görüntüyü takılmaya zorlamak istiyorsanız (bir şeyin hatalarını ayıklamak veya dosya sisteminin durumunu incelemek için) bir kabuk olarak değiştirmek için giriş noktasını geçersiz kılabilirsiniz:

docker run -it --entrypoint=/bin/bash myimagename

18

İşlemlerinizi ve hizmetlerinizi arka planda çalıştırarak başlatmak ve wait [n ...]komut dosyanızın sonundaki komutu kullanmak iyi bir yaklaşım olacaktır . Bash'da wait komutu geçerli işlemi şu şekilde zorlar:

Belirtilen her işlemi bekleyin ve sonlandırma durumunu döndürün. N verilmezse, o anda etkin olan tüm alt süreçler beklenir ve dönüş durumu sıfırdır.

Bu fikri Sébastien Pujadas'ın elk yapımı için başlangıç ​​senaryosundan aldım .

Orijinal sorudan yola çıkarak, start-all.sh dosyanız böyle bir şey olurdu

 #!/usr/bin/env bash
 /etc/init.d/hadoop-hdfs-namenode start &
 /etc/init.d/hadoop-hdfs-datanode start &
 /etc/init.d/hadoop-hdfs-secondarynamenode start &
 /etc/init.d/hadoop-0.20-mapreduce-tasktracker start &
 sudo -u hdfs hadoop fs -chmod 777 /
 /etc/init.d/hadoop-0.20-mapreduce-jobtracker start &
 wait

5

Bunu Dockerfile dosyasının sonuna ekleyin:

CMD tail -f /dev/null

Örnek Docker dosyası:

FROM ubuntu:16.04

# other commands

CMD tail -f /dev/null

Referans


CMD tail -f /dev/nullgeçiyor sh -c "...". execBunun yerine formu kullanabilir miyiz ? IeCMD ["tail", "-f", "/dev/null"]
Meglio

4

Benim pratik Dockerfile içinde hemen çıkmayacak bir kabuk başlatmak CMD [ "sh", "-c", "service ssh start; bash"], sonra çalıştırın docker run -dit image_name. Bu şekilde (ssh) hizmeti ve kapsayıcısı çalışmaya başlar.


1

readSonunda kabuk ifadesi ekledim . Bu, kabın ana işlemini (başlangıç ​​kabuğu betiği) çalışır durumda tutar.



1

Dockerfile'ı kaplardan kontrol ederseniz, örneğin fballiano / magento2-apache-php

dosyasının sonunda aşağıdaki komutu eklediğini göreceksiniz: while true; uyu 1; tamam

Şimdi, önerdiğim, bunu yapmanız

docker container ls --all | grep 127

Daha sonra, docker görüntünüzde bir hata olup olmadığını göreceksiniz, 0 ile çıkarsa, muhtemelen sonsuza kadar uyuyacak bu komutlardan birine ihtiyacı vardır.


0

Bir liman işçisinin hemen çıkmasına neden olmanın birçok yolu vardır. Benim için sorun benim Dockerfile. Bu dosyada bir hata oluştu. Bunun ENTRYPOINT ["dotnet", "M4Movie_Api.dll]yerine vardı ENTRYPOINT ["dotnet", "M4Movie_Api.dll"]. Gördüğünüz gibi sonunda bir teklifi (") kaçırmıştım.

Sorunu analiz etmek için konteynırımı başlattım ve sorunun tam olarak ne olduğunu görebilmem için kabımı hızla taktım.

C:\SVenu\M4Movie\Api\Api>docker start 4ea373efa21b


C:\SVenu\M4Movie\Api\Api>docker attach 4ea373efa21b

4ea373efa21b benim kapsayıcı kimliğim. Bu beni asıl konuya yönlendiriyor.

resim açıklamasını buraya girin

Sorunu bulduktan sonra konteynırımı yeniden oluşturmak, geri yüklemek, yayınlamak zorunda kaldım.


0

Yinelenenlerden gelirken, burada ana iş yükünüzü bir arka plan işi olarak çalıştırmanın ve sonra Docker'ın neden çıktığını merak eden yaygın bir karşıtlığı ele alan herhangi bir cevap görmüyorum.

Basit bir ifadeyle,

my-main-thing &

sonra &işi ön planda çalıştırmak için

wait

tüm arka plan işlerini bekletmek için komut dosyasının sonunda.

Ana iş yükü çıkarsa yine de çıkacaktır, bu yüzden while truebunu sonsuza kadar yeniden başlamaya zorlamak için bir döngüde çalıştırın :

while true; do
    my-main-thing &
    other things which need to happen while the main workload runs in the background
    maybe if you have such things
    wait
done

(Nasıl yazıldığına da dikkat edin while true. Tesadüfen işe yarayan while [ true ]ya while [ 1 ]da tesadüfen ortaya çıkan aptalca şeyleri görmek yaygındır , ancak yazarın muhtemelen ne demek istediklerini hayal ettiği anlamına gelmez.)


0

Arka planda daemon olarak çalışmasını sağlamak için -d bayrağıyla çalıştırmanız gerekir.

docker çalıştırmak -d -it ubuntu bash


-5

Bu yeniden başlatma bayrağını kullanarak kapsayıcıyı çalıştırabilirsiniz.

docker run -d --name=<some-name> -p xxxx:xxxx ... <image-name> --restart=unless-stopped

-8

Görüntü bir linux olduğundan, kontrol edilmesi gereken bir şey, kapta kullanılan kabuk komut dosyalarının unix satır sonlarına sahip olduğundan emin olmaktır. Eğer sonunda bir ^ M varsa o zaman windows satır sonları vardır. Onları düzeltmenin bir yolu /usr/local/start-all.sh dosyasındaki dos2unix'i pencerelerden unix'e dönüştürmektir. Bağlantı istasyonunu etkileşimli modda çalıştırmak, diğer sorunların çözülmesine yardımcı olabilir. Bir dosya adı yazım hatası ya da başka bir şey olabilir. bkz. https://en.wikipedia.org/wiki/Newline

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.