วิธีที่ถูกต้องในการแยกออกจากภาชนะโดยไม่หยุด


313

ใน Docker 1.1.2 (ล่าสุด) วิธีที่ถูกต้องในการแยกออกจากภาชนะโดยไม่หยุดคืออะไร?

ตัวอย่างเช่นถ้าฉันลอง:

  • docker run -i -t foo /bin/bash หรือ
  • docker attach foo (สำหรับการเรียกใช้คอนเทนเนอร์แล้ว)

ทั้งสองอย่างนี้พาฉันไปที่เทอร์มินัลในคอนเทนเนอร์ฉันจะออกจากเทอร์มินัลของคอนเทนเนอร์โดยไม่หยุดได้อย่างไร

exitและCTR+Cทั้งสองหยุดภาชนะ


"คอนเทนเนอร์" เป็นเพียงชุดของเนมสเปซที่ถูก จำกัด (เนมสเปซกระบวนการ, เนมสเปซระบบไฟล์, ฯลฯ ) ที่กระบวนการสามารถทำงานได้หากคุณไม่มีกระบวนการภายในเนมสเปซ มันไม่เหมือนเครื่องเสมือนที่มีเคอร์เนลตอบรับนาฬิกาขัดจังหวะ & c ไม่คำนึงถึง
Charles Duffy

คำตอบ:


166

ปรับปรุง:ตามที่ระบุไว้ด้านล่างในคำตอบCtrl+ p, Ctrl+ qตอนนี้จะเปิดโหมดโต้ตอบเข้าสู่โหมดภูต


ดีCtrl+ C(หรือCtrl+ \) ควรแยกคุณจากภาชนะ แต่มันจะฆ่าภาชนะเพราะกระบวนการหลักของคุณคือทุบตี

บทเรียนเล็กน้อยเกี่ยวกับนักเทียบท่า คอนเทนเนอร์ไม่ใช่ระบบปฏิบัติการที่ใช้งานได้จริง เมื่อคุณเรียกใช้คอนเทนเนอร์กระบวนการที่คุณเรียกใช้จะใช้ PID 1 และใช้พลังงานเริ่มต้น ดังนั้นเมื่อกระบวนการนั้นถูกยกเลิก daemon จะหยุดคอนเทนเนอร์จนกว่าจะมีการเปิดตัวกระบวนการใหม่ (ผ่านจุดเริ่มต้นของนักเทียบท่า) (คำอธิบายเพิ่มเติมเกี่ยวกับเรื่องhttp://phusion.github.io/baseimage-docker/#intro )

หากคุณต้องการภาชนะที่ทำงานในโหมดเดี่ยวตลอดเวลาฉันขอแนะนำให้คุณใช้

docker run -d foo

ด้วยเซิร์ฟเวอร์ ssh บนภาชนะ (วิธีที่ง่ายที่สุดคือการติดตาม dockerizing กวดวิชา openssh https://docs.docker.com/engine/examples/running_ssh_service/ )

หรือคุณสามารถเปิดใช้งานคอนเทนเนอร์ของคุณใหม่ได้

docker start foo

(มันจะถูกถอดออกโดยค่าเริ่มต้น)


3
+1 สำหรับ baseimage-docker เป็นเรื่องดีที่รู้ว่ามีเทมเพลตพร้อมคำแนะนำเกี่ยวกับชิ้นส่วนที่แข็งของ Docker
mtmacdonald

โปรดทราบว่า ssh ไม่จำเป็นอย่างเคร่งครัด: blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker
Adrian Mouat

1
การทำงานในโหมด -d นั้นมีประโยชน์มาก นอกจากนี้ลิงค์เพื่อเริ่ม ssh ผ่าน Dockerfile ทำให้ชีวิตของฉันง่ายขึ้น
Ravi

56
แยกออกโดยใช้ Ctrl-p, Ctrl-q คำแนะนำของคำตอบนี้จะฆ่าที่เก็บ
taranaki

4
สิ่งนี้ใช้ได้สำหรับฉัน (นำมาจากคำตอบด้านล่าง): เริ่มต้นด้วย-ti -dจากนั้นแนบกับdocker attachแล้วแยกออกด้วยctrl + p แรกแล้ว ctrl + q ฉันคิดว่าฉันสามารถใช้แป้นพิมพ์ลัดอย่างใดอย่างหนึ่งได้
CGFoX

526

พิมพ์Ctrl+ pจากนั้นCtrl+q +มันจะช่วยให้คุณเปลี่ยนโหมดการโต้ตอบเป็นโหมดภูต

ดูhttps://docs.docker.com/v1.7/articles/basics/#running-an-interactive-shell

# To detach the tty without exiting the shell,
# use the escape sequence Ctrl-p + Ctrl-q
# note: This will continue to exist in a stopped state once exited (see "docker ps -a")

4
ดูเหมือนว่าจะไม่ทำงานด้วย (พยายามที่จะออกจากคอนเทนเนอร์ Wekan ที่แนบมา)
อันตราย 89

7
ฉันเคยไปที่หน้านี้แล้วครั้งเพราะฉันจำไม่ได้ว่าการผสมคีย์นี้แม่นยำ! :-D
Thamme Gowda

10
@ danger89 ctrl-p, ctrl-q จะทำงานเฉพาะเมื่อคุณเริ่มต้นคอนเทนเนอร์ด้วยโหมดโต้ตอบ (-it) หากคุณเริ่มใช้งานในโหมด deamon (-d) และเชื่อมต่อกับมันคุณสามารถออกได้เลยและมันจะยังคงทำงานในพื้นหลัง
Riscie

1
@SlimShady กด Ctrl + P จากนั้นกด Ctrl + Q เพื่อออกไม่ใช่หนึ่งในนั้น แต่อยู่ในลำดับนั้น
Mohyaddin Alaoddin

160

ฉันขุดลงไปในนี้และคำตอบทั้งหมดข้างต้นถูกต้องบางส่วน ทุกอย่างขึ้นอยู่กับวิธีเปิดตัวคอนเทนเนอร์ มันลงมาดังต่อไปนี้เมื่อเปิดตัวคอนเทนเนอร์:

  • ได้รับการจัดสรร TTY (-t )
  • ถูก stdin เปิดทิ้งไว้ ( -i)

^P^Q ทำงานได้ แต่เมื่อ-tและ-iใช้เพื่อเปิดคอนเทนเนอร์:

[berto@g6]$ docker run -ti -d --name test python:3.6 /bin/bash -c 'while [ 1 ]; do sleep 30; done;'
b26e39632351192a9a1a00ea0c2f3e10729b6d3e22f8e0676d6519e15c08b518

[berto@g6]$ docker attach test
# here I typed ^P^Q
read escape sequence

# i'm back to my prompt
[berto@g6]$ docker kill test; docker rm -v test
test
test

ctrl+c ทำงานได้ แต่จะใช้เมื่อ-t( โดยไม่มี -i ) เปิดใช้คอนเทนเนอร์เท่านั้น:

[berto@g6]$ docker run -t -d --name test python:3.6 /bin/bash -c 'while [ 1 ]; do sleep 30; done;'
018a228c96d6bf2e73cccaefcf656b02753905b9a859f32e60bdf343bcbe834d

[berto@g6]$ docker attach test
^C

[berto@g6]$    

วิธีที่สามในการแยกออก

มีวิธีแยกออกโดยไม่ฆ่าภาชนะแม้ว่า; คุณต้องการเชลล์อื่น โดยสรุปการรันสิ่งนี้ในเชลล์อื่นที่แยกออกและปล่อยให้คอนเทนเนอร์ทำงานpkill -9 -f 'docker.*attach':

[berto@g6]$ docker run -d --name test python:3.6 /bin/bash -c 'while [ 1 ]; do sleep 30; done;'
b26e39632351192a9a1a00ea0c2f3e10729b6d3e22f8e0676d6519e15c08b518

[berto@g6]$ docker attach test
# here I typed ^P^Q and doesn't work
^P
# ctrl+c doesn't work either
^C
# can't background either
^Z

# go to another shell and run the `pkill` command above

# i'm back to my prompt
[berto@g6]$

ทำไม? เนื่องจากคุณกำลังฆ่ากระบวนการที่เชื่อมโยงคุณเข้ากับคอนเทนเนอร์ไม่ใช่คอนเทนเนอร์เอง


2
วิธีที่สามใช้งานได้สำหรับฉัน ขอบคุณ หากคุณกำลังติดกับหลายอินสแตนซ์และต้องการแยกออกจากหนึ่งเดียว สามารถฆ่ากระบวนการเฉพาะ: ps -ef | grep แนบ -> รับ pid แล้ว: kill -9 <pid>
phanhuy152

pkill เป็นสิ่งเดียวที่ใช้ได้ผลสำหรับฉันหลังจากนักเทียบท่าแนบ
sm4rk0

ทำไมเราต้องมี -9 ฉันสังเกตว่าถ้าเราไม่ใช้ -9 มันจะปิดการทำงานของคอนเทนเนอร์
อันเจโล

สัญญาณอื่น ๆ ก็คือสัญญาณ พวกเขาบอกกระบวนการว่าสัญญาณประเภทใดและให้โอกาสทำและทำอะไรบางอย่าง kill -9สัญญาณไม่ได้ กระบวนการถูกยกเลิกและไม่มีการขอความช่วยเหลือ ฉันเดาว่าสัญญาณอื่น ๆ ให้โอกาสในการปิดตู้คอนเทนเนอร์ในขณะที่-9ไม่
berto

1
นี่เป็นประโยชน์อย่างมาก ขอบคุณ!
Evan Zamir

40

หากคุณทำ "นักเทียบท่าแนบ" รหัสภาชนะ "คุณจะได้รับในภาชนะเพื่อออกจากภาชนะโดยไม่ต้องหยุดภาชนะที่คุณต้องป้อนCtrl+ P+Q


6
ดีกว่าไปที่ Ctrl + P และ Ctrl + Q
sib10

4
Ctrl + P, Q (ยังถือ Ctrl);)
dimpiax

มันส่งคืนฉัน:Error response from daemon: Container f560a0ad6806150b2775d0b6e6d5f7065a03775bae858fb4fb7df05a277976db is not running
Webwoman

31

ฉันคิดว่าคำตอบของ Ashwin นั้นถูกต้องที่สุดคำตอบเก่าของฉันอยู่ด้านล่าง


ฉันต้องการเพิ่มตัวเลือกอื่นที่นี่เพื่อเรียกใช้คอนเทนเนอร์ดังต่อไปนี้

docker run -dti foo bash

จากนั้นคุณสามารถป้อนคอนเทนเนอร์และเรียกใช้ bash ด้วย

docker exec -ti ID_of_foo bash

ไม่จำเป็นต้องติดตั้ง sshd :)


ฉันคิดว่าในคำสั่งที่สองคุณต้องแทนที่ foo ด้วย id คอนเทนเนอร์ของ foo
Nehal J Wani

ในบริบทนี้ฉันคิดว่าdocker attachจะเป็นมาตรฐานมากขึ้นโดยใส่กลับไปรัน bash ครั้งแรก docker execยังใช้งานได้ที่นี่ แต่จะสร้างกระบวนการทุบตีใหม่นอกเหนือจากกระบวนการแรก แน่นอนว่ากระบวนการถูกสร้างขึ้นภายในบริบท / สภาพแวดล้อม / คอนเทนเนอร์เดียวกันของกระบวนการแรกอย่างไรก็ตามเป็นกระบวนการที่แตกต่างกัน (การเปรียบเทียบจะเป็นการเปิดแท็บเทอร์มินัลใหม่ในเทอร์มินัลอีมูเลเตอร์ที่คุณชื่นชอบ)
thiagowfx

20

วิธีการเริ่มต้นที่จะแยกออกจากภาชนะโต้ตอบCtrl+ P Ctrl+ Qแต่คุณสามารถแทนที่มันเมื่อใช้ภาชนะใหม่หรือแนบกับคอนเทนเนอร์ที่มีอยู่โดยใช้ธง --detach คีย์


16

หากคุณเชื่อมต่อผ่านdocker attachคุณสามารถแยกออกได้โดยการฆ่ากระบวนการแนบนักเทียบท่า วิธีที่ดีกว่าคือใช้พารามิเตอร์ sig-proxy เพื่อหลีกเลี่ยงการส่งผ่าน Ctrl + C ไปยังคอนเทนเนอร์ของคุณ:

docker attach --sig-proxy=false [container-name]

มีตัวเลือกเดียวกันสำหรับdocker runคำสั่ง


6
แม้ว่า--sig-proxy = falseมีประโยชน์อย่างยิ่ง แต่ก็ไม่สามารถใช้งานได้กับคอนเทนเนอร์ที่แนบมาแล้วซึ่งไม่ได้ระบุไว้ ปัญหาคือหลังจากติดดูเหมือนว่าจะไม่มีทางที่จะแยกออกโดยไม่ฆ่ากระบวนการรวมถึง "การฆ่ากระบวนการแนบนักเทียบท่า" Cp, Cq ไม่ทำงานกับคอนเทนเนอร์ที่แนบมามีเพียงแบบโต้ตอบ (เช่นคำถามใช้)
taranaki

1
นี่ควรเป็นคำตอบที่ได้รับการยอมรับรวมถึงความคิดเห็นของ @taranaki, Ctrl + P, Q ไม่สามารถใช้ได้สำหรับphp:7.3-apache
MKaama

10

docker container logs -f <container id>ถ้าคุณเพียงต้องการเห็นผลลัพธ์ของกระบวนการทำงานจากภายในภาชนะที่คุณสามารถทำได้ง่ายๆ

การ-fตั้งค่าสถานะทำให้มันเพื่อให้การส่งออกของภาชนะที่เป็นfollowedและการปรับปรุงในเวลาจริง มีประโยชน์มากสำหรับการดีบักหรือตรวจสอบ


8

คุณสามารถใช้--detach-keysตัวเลือกเมื่อคุณเรียกใช้docker attachเพื่อแทนที่ลำดับ+ , CTRL+ เริ่มต้น(ที่ไม่ได้ทำงานเสมอ)PCTRLQ

ตัวอย่างเช่นเมื่อคุณเรียกใช้docker attach --detach-keys="ctrl-a" testและคุณกดCTRL+ Aคุณจะออกจากคอนเทนเนอร์โดยไม่ฆ่ามัน

ตัวอย่างอื่น ๆ :

  • docker attach --detach-keys="ctrl-a,x" test- กดCTRL+Aและจากนั้นXเพื่อออก
  • docker attach --detach-keys="a,b,c" test- กดAแล้วBแล้วCไปสู่ทางออก

แยกจากเอกสารอย่างเป็นทางการ:

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

หากต้องการแทนที่ลำดับสำหรับคอนเทนเนอร์แต่ละตัวให้ใช้--detach-keys="<sequence>"แฟล็กพร้อมกับคำสั่ง docker attach รูปแบบของการ<sequence>เป็นตัวอักษร[a-Z]หรือctrl-รวมกับสิ่งใด ๆ ต่อไปนี้:

  • az (ตัวอักษรตัวพิมพ์เล็กหนึ่งตัว)
  • @ (ที่เครื่องหมาย)
  • [(วงเล็บเหลี่ยมซ้าย)
  • \ (สองแบ็กซ้าย)
  • _ (ขีดล่าง)
  • ^ (คาเร็ต)

เหล่านี้a, ctrl-a, Xหรือctrl-\\ค่าเป็นตัวอย่างของคีย์ลำดับที่ถูกต้อง ในการกำหนดค่าลำดับคีย์เริ่มต้นของการกำหนดค่าที่แตกต่างกันสำหรับคอนเทนเนอร์ทั้งหมดดูส่วนไฟล์คอนฟิกูเรชัน

หมายเหตุ: สามารถใช้งานได้ตั้งแต่รุ่น docker 1.10+ (ในเวลาที่ตอบคำถามนี้เวอร์ชันปัจจุบันคือ 18.03)


0

โพสต์เก่า แต่เพิ่งออกจากนั้นเริ่มต้นอีกครั้ง ... ปัญหาคือถ้าคุณอยู่บนเครื่อง windows Ctrl p หรือ Ctrl P จะเชื่อมโยงกับการพิมพ์ ... ออกจากการเริ่มต้นภาชนะที่ไม่ควรทำร้ายอะไร

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