ทำไมนักเทียบท่าออกจากตู้ทันที


239

ฉันใช้คอนเทนเนอร์ในพื้นหลังโดยใช้

 docker run -d --name hadoop h_Service

มันออกอย่างรวดเร็ว แต่ถ้าฉันวิ่งไปเบื้องหน้ามันก็ใช้ได้ดี ฉันตรวจสอบบันทึกโดยใช้

docker logs hadoop

ไม่มีข้อผิดพลาด ความคิดใด ๆ

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
กฎทองคือคุณควรป้องกันเซิร์ฟเวอร์ที่ถูกปรับเทียบของคุณไม่ให้ทำการ daemonizing แพ็กเกจเซิร์ฟเวอร์ส่วนใหญ่มีตัวเลือกที่จะบังคับให้ทำงานส่วนหน้าเนื่องจาก daemonizing เป็นกรณีปกติ
Arnaud Meuret

สิ่งที่คุณหวังว่าจะบรรลุchmod 777คือไม่ปลอดภัยและไม่ถูกต้อง คุณควรกลับไปใช้สิทธิ์ที่มีสติ (อาจเป็น 755 ในกรณีนี้)
tripleee

คำตอบ:


125

คอนเทนเนอร์นักเทียบท่าออกเมื่อกระบวนการหลักเสร็จสิ้น

ในกรณีนี้มันจะออกเมื่อstart-all.shสคริปต์ของคุณสิ้นสุด ฉันไม่รู้เกี่ยวกับ hadoop มากพอที่จะบอกคุณถึงวิธีการทำในกรณีนี้ แต่คุณต้องปล่อยให้บางสิ่งบางอย่างทำงานในเบื้องหน้าหรือใช้ตัวจัดการกระบวนการเช่น runit หรือ supervisord เพื่อเรียกใช้กระบวนการ

ฉันคิดว่าคุณต้องเข้าใจผิดเกี่ยวกับการทำงานหากคุณไม่ได้ระบุ-d; มันควรจะมีผลเช่นเดียวกัน ฉันสงสัยว่าคุณเปิดตัวด้วยคำสั่งที่แตกต่างกันเล็กน้อยหรือใช้-itซึ่งจะเปลี่ยนสิ่งต่าง ๆ

วิธีแก้ไขปัญหาอย่างง่ายอาจเป็นการเพิ่มสิ่งต่าง ๆ เช่น:

while true; do sleep 1000; done

ถึงจุดสิ้นสุดของสคริปต์ ฉันไม่ชอบสิ่งนี้อย่างไรก็ตามเนื่องจากสคริปต์ควรตรวจสอบกระบวนการที่เริ่มต้นจริง

(ฉันควรจะบอกว่าฉันขโมยรหัสนั้นจากhttps://github.com/sequenceiq/hadoop-docker/blob/master/bootstrap.sh )


218

นี้ได้เคล็ดลับสำหรับฉัน:

docker run -dit ubuntu

หลังจากนั้นฉันตรวจสอบกระบวนการที่ทำงานโดยใช้:

docker ps -a

สำหรับการแนบคอนเทนเนอร์อีกครั้ง

docker attach CONTAINER_NAME

เคล็ดลับ: สำหรับการออกโดยไม่หยุดประเภทภาชนะ: ^P^Q


15
@Tommy จากdocs.docker.com/engine/reference/commandline/run -d, --detach โหมด Detached: run คำสั่งในพื้นหลัง, -i, - เปิดใช้งาน STDIN แม้ว่าจะไม่ได้เชื่อมต่อ -t, - -tty จัดสรรหลอก -TTY -ditเป็นเพียงชวเลข

3
@ am17torres ถูกต้องขออภัยให้ฉันอธิบายคำถามที่ทำให้สับสน d แยกออกและฉันเป็นแบบโต้ตอบดังนั้นการรวมกันของ d และฉันทำให้ฉันสับสน ฉันคิดว่า d คือการเปิดใช้เป็นกระบวนการพื้นหลัง (ไม่โต้ตอบ)
Tommy

2
@Tommy เมื่อตัวเลือกเหล่านี้รวมภาชนะที่จะเข้าสู่โหมดการโต้ตอบในพื้นหลัง
Yon

2
@Tommy @ am17torres -diเป็นขั้นต่ำที่จำเป็นที่-tตัวเลือกที่ซ้ำซ้อนเมื่อใช้กับ-dถ้าผมเข้าใจอย่างถูกต้อง
Renaud

2
ที่จริงแล้วคุณจะไม่เห็นพรอมต์ของคุณหากคุณไม่ได้-tเปิดใช้งานอีกครั้ง แต่เนื่องจากฉันมักจะexecทุบตีใหม่ทุกครั้งที่ฉันไม่สังเกตเห็น ฉันมีปัญหาในการแยกออกจากเครื่องแมค แต่บางทีฉันอาจทำผิดไป ..
Renaud

65

ฉันต้องการที่จะขยายหรือกล้าฉันพูดปรับปรุงคำตอบที่กล่าวถึงโดยcamposer

เมื่อคุณวิ่ง

docker run -dit ubuntu

โดยทั่วไปคุณใช้คอนเทนเนอร์ในพื้นหลังในโหมดโต้ตอบ

เมื่อคุณแนบและออกจากคอนเทนเนอร์ด้วย CTRL + D (วิธีทั่วไปในการทำ) คุณจะหยุดคอนเทนเนอร์เพราะคุณเพิ่งฆ่ากระบวนการหลักที่คุณเริ่มต้นคอนเทนเนอร์ด้วยคำสั่งด้านบน

การใช้ประโยชน์จากคอนเทนเนอร์ที่กำลังทำงานอยู่ฉันจะแยกกระบวนการทุบตีและรับ TTY หลอกโดยการเรียกใช้:

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

29

เมื่อใดก็ตามที่ฉันต้องการภาชนะเพื่อให้ทันหลังจากเสร็จสิ้นการดำเนินการสคริปต์ที่ฉันเพิ่ม

&& tail -f /dev/null

ในตอนท้ายของคำสั่ง ดังนั้นควรเป็น:

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

19

ทำไมนักเทียบท่าออกจากตู้คอนเทนเนอร์ทันที?

หากคุณต้องการบังคับให้รูปภาพวางรอบ (เพื่อดีบักบางสิ่งหรือตรวจสอบสถานะของระบบไฟล์) คุณสามารถแทนที่จุดเริ่มต้นเพื่อเปลี่ยนเป็นเชลล์:

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

18

แนวทางที่ดีคือการเริ่มกระบวนการและบริการของคุณโดยเรียกใช้งานในเบื้องหลังและใช้wait [n ...]คำสั่งเมื่อสิ้นสุดสคริปต์ของคุณ ใน bash คำสั่ง wait บังคับให้กระบวนการปัจจุบันไปที่:

รอแต่ละกระบวนการที่ระบุและส่งคืนสถานะการเลิกจ้าง หากไม่ได้รับ n กระบวนการลูกที่ทำงานอยู่ในปัจจุบันทั้งหมดจะถูกรอและสถานะการส่งคืนจะเป็นศูนย์

ผมมีความคิดนี้จากSébastien Pujadas' สคริปต์ที่เริ่มต้นสำหรับกวางเขาสร้าง

จากคำถามเดิม 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 &
 wait

5

เพิ่มลงในส่วนท้ายของ Dockerfile:

CMD tail -f /dev/null

ไฟล์ Docker ตัวอย่าง:

FROM ubuntu:16.04

# other commands

CMD tail -f /dev/null

การอ้างอิง


CMD tail -f /dev/nullsh -c "..."มันวิ่งผ่าน เราสามารถใช้execแบบฟอร์มแทนได้หรือไม่? IeCMD ["tail", "-f", "/dev/null"]
Meglio

4

pracitce ของฉันอยู่ใน Dockerfile เริ่มต้นเปลือกซึ่งจะไม่ออกทันทีแล้วใช้CMD [ "sh", "-c", "service ssh start; bash"] docker run -dit image_nameวิธีนี้เซอร์วิส (ssh) และคอนเทนเนอร์กำลังทำงาน


1

ฉันเพิ่มreadคำสั่งเชลล์ในตอนท้าย สิ่งนี้ทำให้กระบวนการหลักของคอนเทนเนอร์ - เชลล์สคริปต์เริ่มต้นทำงานอยู่


1

เพิ่ม

exec "$@"

ในตอนท้ายของสคริปต์เชลล์ของฉันคือการแก้ไขของฉัน!


นั่นเป็นเพียงความหมายมันจะเรียกใช้คำสั่งของคุณถ้าคำสั่งของคุณเป็นเพียง 'ทุบตี' จากนั้นก็ยังจะไม่ทำงาน
Shardj

1

หากคุณตรวจสอบ Dockerfile จากตู้คอนเทนเนอร์เช่น fballiano / magento2-apache-php

คุณจะเห็นว่าในตอนท้ายของไฟล์เขาเพิ่มคำสั่งต่อไปนี้: ในขณะที่จริง; นอนหลับ 1 เสร็จแล้ว

ตอนนี้สิ่งที่ฉันแนะนำคือคุณทำเช่นนี้

docker container ls --all | grep 127

จากนั้นคุณจะเห็นว่าภาพนักเทียบท่าของคุณมีข้อผิดพลาดหรือไม่หากออกจาก 0 แล้วมันอาจต้องใช้หนึ่งในคำสั่งเหล่านี้ที่จะนอนตลอดไป


0

มีหลายวิธีที่เป็นไปได้ที่จะทำให้นักเทียบท่าออกจากทันที Dockerfileสำหรับผมแล้วมันเป็นปัญหาที่เกิดขึ้นกับฉัน มีข้อผิดพลาดในไฟล์นั้น ฉันมีแทนENTRYPOINT ["dotnet", "M4Movie_Api.dll] ENTRYPOINT ["dotnet", "M4Movie_Api.dll"]อย่างที่คุณเห็นฉันพลาดคำพูดหนึ่งคำ (") ในตอนท้าย

เพื่อวิเคราะห์ปัญหาฉันเริ่มที่เก็บของฉันและติดที่เก็บของฉันอย่างรวดเร็วเพื่อที่ฉันจะได้เห็นว่าอะไรคือปัญหาที่แน่นอน

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


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

โดยที่ 4ea373efa21b คือรหัสประจำตัวของฉัน สิ่งนี้ทำให้ฉันเป็นปัญหาจริง

ป้อนคำอธิบายรูปภาพที่นี่

หลังจากพบปัญหาฉันต้องสร้างเรียกคืนเผยแพร่คอนเทนเนอร์ของฉันอีกครั้ง


0

มาจากรายการที่ซ้ำกันฉันไม่เห็นคำตอบใด ๆ ที่นี่ซึ่งระบุที่อยู่ร่วมกันโดยทั่วไปของการเรียกใช้งานปริมาณงานหลักของคุณเป็นงานพื้นหลังแล้วสงสัยว่าทำไมนักเทียบท่าถึงออก

ในแง่ง่าย ๆ ถ้าคุณมี

my-main-thing &

จากนั้นนำออก&เพื่อรันงานในเบื้องหน้าหรือเพิ่ม

wait

ในตอนท้ายของสคริปต์เพื่อให้รองานพื้นหลังทั้งหมด

จากนั้นจะยังคงออกหากมีเวิร์กโหลดหลักออกดังนั้นอาจรันด้วยการwhile trueวนซ้ำเพื่อบังคับให้รีสตาร์ทอย่างถาวร:

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

(สังเกตด้วยว่าจะเขียนยังไงwhile trueมันเป็นเรื่องธรรมดาที่จะเห็นสิ่งที่โง่ ๆ เหมือนwhile [ true ]หรือwhile [ 1 ]เกิดขึ้นโดยบังเอิญในการทำงาน แต่ไม่ได้หมายความว่าผู้เขียนคิดว่าพวกเขาควรจะหมายถึงอะไร)


0

คุณต้องรันด้วยแฟล็ก -d เพื่อให้มันรันเป็น daemon ในพื้นหลัง

นักเทียบท่าวิ่ง -d -it อูบุนตูทุบตี


-5

คุณสามารถเรียกใช้คอนเทนเนอร์โดยใช้การตั้งค่าสถานะเริ่มต้นนี้

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

-8

เนื่องจากอิมเมจนั้นเป็น linux สิ่งหนึ่งที่ต้องตรวจสอบก็คือเพื่อให้แน่ใจว่าเชลล์สคริปต์ใด ๆ ที่ใช้ในคอนเทนเนอร์นั้นมีจุดสิ้นสุดบรรทัดยูนิกซ์ หากพวกเขามี ^ M ในตอนท้ายพวกเขาจะเป็นจุดสิ้นสุดของบรรทัดหน้าต่าง วิธีหนึ่งในการแก้ไขด้วย dos2unix บน /usr/local/start-all.sh เพื่อแปลงจาก windows เป็น unix การรันตัวเทียบท่าในโหมดการโต้ตอบสามารถช่วยแก้ปัญหาอื่น ๆ ได้ คุณสามารถพิมพ์ชื่อไฟล์หรืออะไรก็ได้ ดูhttps://en.wikipedia.org/wiki/Newline

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.