Mengapa wadah buruh pelabuhan segera keluar

239

Saya menjalankan wadah di latar belakang menggunakan

 docker run -d --name hadoop h_Service

keluar dengan cepat. Tetapi jika saya berlari di latar depan, itu berfungsi dengan baik. Saya memeriksa log menggunakan

docker logs hadoop

tidak ada kesalahan. Ada ide?

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
Gibbs
sumber
1
Aturan utamanya adalah Anda harus mencegah server galangan Anda dari daemonisasi. Sebagian besar paket server memiliki opsi untuk memaksa mereka di latar depan karena daemonisasi adalah kasus normal.
Arnaud Meuret
Apa pun yang Anda berharap untuk mencapai, chmod 777adalah tidak aman dan salah. Anda harus kembali ke izin waras (mungkin 755 dalam kasus ini).
tripleee

Jawaban:

125

Wadah buruh pelabuhan keluar saat proses utamanya selesai.

Dalam hal ini, ia akan keluar ketika start-all.shskrip Anda berakhir. Saya tidak cukup tahu tentang hadoop untuk memberi tahu Anda bagaimana melakukannya dalam kasus ini, tetapi Anda harus membiarkan sesuatu berjalan di latar depan atau menggunakan manajer proses seperti runit atau supervisor untuk menjalankan proses.

Saya pikir Anda pasti salah tentang hal itu berfungsi jika Anda tidak menentukan -d; seharusnya memiliki efek yang persis sama. Saya menduga Anda meluncurkannya dengan perintah yang sedikit berbeda atau menggunakan -ityang akan mengubah segalanya.

Solusi sederhana mungkin dengan menambahkan sesuatu seperti:

while true; do sleep 1000; done

sampai akhir skrip. Saya tidak suka ini, karena skrip harus benar-benar memantau proses yang dimulai.

(Saya harus mengatakan saya mencuri kode itu dari https://github.com/ followingenceiq/hadoop-docker/blob/master/ bootstrap.sh )

Adrian Mouat
sumber
218

Ini melakukan trik untuk saya:

docker run -dit ubuntu

Setelah itu, saya memeriksa proses yang berjalan menggunakan:

docker ps -a

Untuk memasang kembali wadah

docker attach CONTAINER_NAME

TIP: Untuk keluar tanpa menghentikan jenis wadah: ^P^Q

camposer
sumber
15
@Tommy, dari docs.docker.com/engine/reference/commandline/run -d, --detach Detached mode: jalankan perintah di latar belakang, -i, --interactive Tetap buka STDIN walaupun tidak terpasang, -t, - -tty Mengalokasikan pseudo-TTY -dithanya singkatan
3
@ am17torres benar, maaf izinkan saya mengklarifikasi pertanyaan saya yang membingungkan; d terpisah dan saya interaktif, jadi kombinasi dari d dan saya membingungkan bagi saya. Saya pikir saya akan meluncurkannya sebagai proses latar belakang (non-interaktif).
Tommy
2
@Tommy Ketika opsi-opsi ini digabungkan, kontainer akan memasuki mode interaktif di latar belakang .
Yon
2
@Tommy, @ am17torres -diadalah minimum yang diperlukan, -topsi ini berlebihan jika digunakan dengan -djika saya mengerti dengan benar
Renaud
2
Sebenarnya Anda tidak akan dapat melihat permintaan Anda jika Anda memasang kembali tanpa -tmengaktifkan ... tapi karena saya biasanya execbash baru setiap kali saya tidak melihat. Saya memiliki masalah melepaskan diri dari mac tetapi mungkin saya melakukan ini salah ..
Renaud
65

Saya ingin memperpanjang atau berani saya katakan, tingkatkan jawaban yang disebutkan oleh camposer

Ketika kamu berlari

docker run -dit ubuntu

Anda pada dasarnya menjalankan wadah di latar belakang dalam mode interaktif.

Ketika Anda melampirkan dan keluar dari wadah dengan CTRL + D (cara paling umum untuk melakukannya), Anda menghentikan wadah karena Anda baru saja membunuh proses utama yang Anda mulai wadah Anda dengan perintah di atas.

Memanfaatkan wadah yang sudah berjalan, saya hanya akan melakukan proses bash lain dan mendapatkan TTY semu dengan menjalankan:

docker exec -it <container ID> /bin/bash
Krishna Gupta
sumber
29

setiap kali saya ingin sebuah wadah tetap terjaga setelah menyelesaikan skrip saya tambahkan

&& tail -f /dev/null

di akhir perintah. Jadi seharusnya:

/usr/local/start-all.sh && tail -f /dev/null
Thiago Ramos
sumber
19

Mengapa wadah buruh pelabuhan segera keluar?

Jika Anda ingin memaksa gambar untuk nongkrong (untuk men-debug sesuatu atau memeriksa keadaan sistem file) Anda dapat mengganti titik masuk untuk mengubahnya menjadi shell:

docker run -it --entrypoint=/bin/bash myimagename
RJFalconer
sumber
18

Pendekatan yang bagus adalah memulai proses dan layanan Anda menjalankannya di latar belakang dan menggunakan wait [n ...]perintah di akhir skrip Anda. Dalam bash, perintah tunggu memaksa proses saat ini untuk:

Tunggu setiap proses yang ditentukan dan kembalikan status penghentiannya. Jika n tidak diberikan, semua proses anak yang sedang aktif menunggu, dan status pengembalian adalah nol.

Saya mendapat ide ini dari skrip awal Sébastien Pujadas untuk build elk-nya .

Mengambil dari pertanyaan awal, start-all.sh Anda akan terlihat seperti ini ...

 #!/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
Brian Olsen
sumber
5

Tambahkan ini ke akhir Dockerfile:

CMD tail -f /dev/null

Contoh file Docker:

FROM ubuntu:16.04

# other commands

CMD tail -f /dev/null

Referensi

Kert Kukk
sumber
CMD tail -f /dev/nullmenjalankannya sh -c "...". Bisakah kita menggunakan execformulir saja? YaituCMD ["tail", "-f", "/dev/null"]
Meglio
4

Praktik saya adalah di Dockerfile memulai shell yang tidak akan segera keluar CMD [ "sh", "-c", "service ssh start; bash"], kemudian jalankan docker run -dit image_name. Dengan cara ini layanan (ssh) dan wadah berjalan

Leon
sumber
1

Saya menambahkan readpernyataan shell di akhir. Ini menjaga proses utama wadah - skrip startup shell - berjalan.

Jaydeep Ranipa
sumber
1

Menambahkan

exec "$@"

pada akhir skrip shell saya adalah perbaikan saya!

Adam k
sumber
Itu hanya berarti itu akan menjalankan cmd Anda, jika cmd Anda hanya 'bash' maka itu masih tidak akan berhasil
Shardj
1

Jika Anda memeriksa Dockerfile dari wadah, misalnya fballiano / magento2-apache-php

Anda akan melihat bahwa di akhir file-nya ia menambahkan perintah berikut: while true; tidurlah 1; selesai

Sekarang, apa yang saya rekomendasikan, adalah Anda melakukan ini

docker container ls --all | grep 127

Kemudian, Anda akan melihat apakah gambar buruh pelabuhan Anda memiliki kesalahan, jika keluar dengan 0, maka mungkin perlu salah satu dari perintah ini yang akan tidur selamanya.

xavierbaez
sumber
0

Ada banyak cara yang memungkinkan galangan untuk segera keluar. Bagi saya, itu adalah masalah saya Dockerfile. Ada bug di file itu. Saya ENTRYPOINT ["dotnet", "M4Movie_Api.dll]bukannya ENTRYPOINT ["dotnet", "M4Movie_Api.dll"]. Seperti yang Anda lihat, saya telah melewatkan satu kutipan (") di akhir.

Untuk menganalisis masalah saya memulai wadah saya dan dengan cepat memasang wadah saya sehingga saya bisa melihat apa masalah sebenarnya.

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


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

Di mana 4ea373efa21b adalah id wadah saya. Ini mendorong saya ke masalah sebenarnya.

masukkan deskripsi gambar di sini

Setelah menemukan masalah, saya harus membangun, mengembalikan, menerbitkan wadah saya lagi.

Sibeesh Venu
sumber
0

Berasal dari duplikat, saya tidak melihat jawaban apa pun di sini yang membahas antipattern yang sangat umum dalam menjalankan beban kerja utama Anda sebagai pekerjaan latar belakang, dan kemudian bertanya-tanya mengapa Docker keluar.

Secara sederhana, jika Anda punya

my-main-thing &

lalu keluarkan &untuk menjalankan pekerjaan di latar depan, atau tambahkan

wait

di akhir skrip untuk membuatnya menunggu semua pekerjaan latar belakang.

Itu kemudian akan tetap keluar jika beban kerja utama keluar, jadi mungkin jalankan ini dalam satu while truelingkaran untuk memaksanya restart selamanya:

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

(Perhatikan juga cara menulis while true. Adalah umum untuk melihat hal-hal konyol seperti while [ true ]atau while [ 1 ]yang kebetulan bekerja, tetapi tidak berarti apa yang mungkin dibayangkan oleh penulis.)

tripleee
sumber
0

Anda perlu menjalankannya dengan -d flag untuk membiarkannya berjalan sebagai daemon di latar belakang.

buruh pelabuhan menjalankan -d -it bash ubuntu

Vivek
sumber
-5

Anda dapat menjalankan wadah menggunakan flag restart ini.

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

Karena gambar tersebut adalah linux, satu hal yang perlu diperiksa adalah memastikan setiap skrip shell yang digunakan dalam wadah memiliki akhiran baris unix. Jika mereka memiliki ^ M di akhir maka mereka adalah ujung baris windows. Salah satu cara untuk memperbaikinya adalah dengan dos2unix di /usr/local/start-all.sh untuk mengubahnya dari windows ke unix. Menjalankan docker dalam mode interaktif dapat membantu memecahkan masalah lain. Anda dapat memiliki salah ketik nama file atau sesuatu. lihat https://en.wikipedia.org/wiki/Newline

dskow
sumber