วิธีป้อนในคอนเทนเนอร์ Docker ที่ใช้งาน TTY ใหม่อยู่แล้ว


545

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

เป็นไปได้หรือไม่ที่จะแนบ tty อื่นกับคอนเทนเนอร์ที่รันอยู่? อาจเป็นไปได้ว่าฉันสามารถใช้ประโยชน์จากข้อเท็จจริงที่ว่านักเทียบท่าเป็นเพียงห่อรอบภาชนะ LXC? ฉันลองแล้วsudo lxc-console -n [container-id] -t [1-4]แต่ดูเหมือนว่ามีเพียง tty เดียวเท่านั้นที่ใช้ได้และนั่นคืออันที่ใช้ apache daemon อาจมีวิธีการเปิดใช้งานคอนโซล lxc หลายตัวในระหว่างการสร้างหรือไม่

ฉันไม่ต้องการกำหนดค่าและสร้างคอนเทนเนอร์ด้วยบริการ openssh ถ้าเป็นไปได้


7
คุณลองdocker attach [conainer-id]ไหม
shabbychef

13
@shabbychef หากไม่ได้แนบตัวเชื่อมต่อ Docker คำสั่ง attach จะแนบกับ tty ที่รันอยู่ไม่ใช่ชื่อใหม่ดังนั้นชื่อคำถามคือ "... with TTY ใหม่" นี่คือเหตุผลที่คำตอบด้านล่างไม่ได้ใช้คำสั่งแนบ
Programster

1
ตั้งแต่ 1.3 มีวิธีที่ง่ายกว่าดังที่อธิบายไว้ในคำตอบนี้
Thomasleveil

คำตอบ:


1061

กับนักเทียบท่า 1.3 docker execมีคำสั่งใหม่ สิ่งนี้ช่วยให้คุณป้อนนักเทียบท่าที่กำลังทำงานอยู่:

docker exec -it [container-id] bash

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

3
โปรดสังเกตว่าexecมันไม่ได้ทำหน้าที่เหมือนเทอร์มินัลปกติ ตัวอย่างเช่นคุณไม่สามารถเปลี่ยนผู้ใช้ครั้งเดียวภายในคอนเทนเนอร์
Pithikos

3
@Pithikos: ฉันสามารถใช้ exec เพื่อเรียกใช้เชลล์แล้วsu someuserเปลี่ยนผู้ใช้ เล่นนักเทียบท่า 1.4.1
lsh

2
หมายเหตุสำหรับทุกคนที่อ่านการสนทนานี้ ฉันแน่ใจว่าdocker exec -itในที่สุดจะให้หลอกหลอกเต็มฟังก์ชั่น แต่ตอนนี้ (นักเทียบท่ารุ่น 1.9.1) มีข้อบกพร่องบางอย่าง: github.com/docker/docker/issues/8755
blong

18
หากคุณได้รับข้อผิดพลาด 'exec: "bash": ไม่พบไฟล์เรียกทำงานใน $ PATH' คุณสามารถลองได้:
docker exec -it

42

คุณควรใช้เครื่องมือของJérôme Petazzoni ที่เรียกว่า 'nsenter' เพื่อป้อนคอนเทนเนอร์โดยไม่ใช้ SSH ดู: https://github.com/jpetazzo/nsenter

ติดตั้งเพียงใช้งาน: docker run -v /usr/local/bin:/target jpetazzo/nsenter

จากนั้นใช้คำสั่งdocker-enter <container-id>เพื่อเข้าสู่คอนเทนเนอร์


นี่เป็นวิธีที่ถูกต้อง ดูบล็อก
Jesse Glick

5
กับนักเทียบท่า 1.3 docker execมีคำสั่งใหม่ วิธีนี้ช่วยให้คุณสามารถป้อนนักเทียบท่าทำงาน: docker exec -it <container-id> bash(ดูคำตอบของฉันด้านล่าง)
Michael_Scharf

5
ไม่docker-enterยังคงอยู่? command not foundมันทำให้ฉัน
Snowcrash

22

ปรับปรุง

ในฐานะของนักเทียบท่า 0.9 สำหรับขั้นตอนด้านล่างที่จะใช้งานได้ตอนนี้ต้องอัปเดต/etc/default/dockerไฟล์ด้วย'-e lxc'ตัวเลือกการเริ่มต้นไปที่ตัวเชื่อมต่อ daemon daemon ก่อนที่จะรีสตาร์ท daemon (ฉันทำสิ่งนี้โดยรีบูตโฮสต์)

อัพเดตเป็นไฟล์ / etc / default / docker

ทั้งหมดนี้เป็นเพราะ ...

... มัน [นักเทียบท่า 0.9] มี "abstraction" ตัวขับใหม่เพื่อให้สามารถใช้ API อื่นที่ไม่ใช่ LXC เพื่อเริ่มต้นคอนเทนเนอร์ นอกจากนี้ยังมีโปรแกรมควบคุมเครื่องยนต์ใหม่ตามไลบรารี API ใหม่ (libcontainer) ซึ่งสามารถจัดการกลุ่มควบคุมได้โดยไม่ต้องใช้เครื่องมือ LXC ปัญหาหลักคือถ้าคุณใช้ lxc-attach เพื่อดำเนินการกับคอนเทนเนอร์ของคุณเช่นเริ่มต้นเชลล์ภายในคอนเทนเนอร์ซึ่งมีประโยชน์อย่างมากสำหรับสภาพแวดล้อมการพัฒนา ...

แหล่ง

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


ปรากฎว่าวิธีแก้ปัญหาสำหรับคำถามที่แตกต่างก็เป็นวิธีแก้ปัญหาสำหรับปัญหานี้เช่นกัน:

... คุณสามารถใช้นักเทียบท่าps -notruncเพื่อรับรหัสคอนเทนเนอร์ lxc แบบเต็มจากนั้นใช้การlxc-attach -n <container_id>ใช้ bash ในคอนเทนเนอร์นั้นเป็นรูท

อัปเดต:คุณจะต้องใช้ps --no-truncแทนps -notruncใช้เลิกใช้

ป้อนคำอธิบายรูปภาพที่นี่ ค้นหา ID คอนเทนเนอร์แบบเต็ม

ป้อนคำอธิบายรูปภาพที่นี่ ป้อนคำสั่ง lxc attach

ป้อนคำอธิบายรูปภาพที่นี่ ด้านบนแสดงกระบวนการ Apache ของฉันที่เรียกใช้นักเทียบท่าที่เริ่มต้น


ดังนั้นไม่มีทางที่จะทำเช่นนี้กับนักเทียบท่าใช่มั้ย โดยส่วนตัวฉันไม่ต้องการผสมใน LXC ด้วยตัวเอง
qkrijger

มีวิธีรันคำสั่งที่มี lxc-attach แทนเพื่อเปิด bash หรือไม่? ขอบคุณ!!
joselo

@qkrijger เท่าที่ฉันทราบว่าถูกต้อง ทำไมต้องกังวลเกี่ยวกับ "การผสม" LXC คุณรู้หรือไม่ว่านักเทียบท่านั้นถูกสร้างขึ้นบน LXC ใช่ไหม?
Programster

@joselo ฉันไม่เข้าใจคำถามของคุณ แต่ฉันขอแนะนำให้คุณสร้างโพสต์ใหม่พร้อมรายละเอียดเพิ่มเติมใช่ไหม มีหลายวิธีที่จะเริ่มต้นกระบวนการนักเทียบท่าเช่นเดียวกับทุบตีหรือเป็นภูตที่มี -d ฯลฯ
Programster

@ โปรแกรมใช่ฉันรู้ว่า :) ยังใช้ LXC โดยตรงร่วมกับ Docker รู้สึกเหมือนแฮ็ค สนุก แต่ไม่สามารถบำรุงรักษาได้จริงๆ โดยทั่วไปหนึ่งควรรหัสในชั้นนามธรรมที่หนึ่งเลือกที่จะทำงานในถ้าคุณต้องการจริงๆ LXC ตัวเองก็อาจจะมีเวลาสำหรับคำขอดึงหาง :).
qkrijger

7

ขั้นตอนแรกรับ ID คอนเทนเนอร์:

docker ps

สิ่งนี้จะแสดงให้คุณเห็นเช่น

รหัสภาพภาชนะบรรจุคำสั่งสร้างชื่อพอร์ตสถานะ

1170fe9e9460 localhost: 5,000 / python: env-7e847468c4d73a0f35e9c5164046ad88 "./run_notebook.sh" 26 วินาทีที่แล้วขึ้น 25 วินาที 0.0.0.0:8989->9999/tcp SLURM_TASK-303337_0

1170fe9e9460 คือ ID คอนเทนเนอร์ในกรณีนี้

ประการที่สองป้อนนักเทียบท่า:

docker exec -it [container_id] bash

ดังนั้นในกรณีข้างต้น: docker exec -it 1170fe9e9460 bash


5

สิ่งที่เกี่ยวกับการใช้หน้าจอ tmux / GNU ภายในภาชนะ? ดูเหมือนวิธีที่ราบรื่นในการเข้าถึง vty ได้มากเท่าที่คุณต้องการด้วยวิธีง่ายๆ:

$ docker attach {container id}

นี่เป็นวิธีการแก้ปัญหาที่ดีถ้าคุณรู้ว่าคุณต้องการเข้าถึงคอนเทนเนอร์ (ตัวอย่างเช่นเพื่อดีบัก) แต่จะไม่ช่วย OP ที่ระบุว่าพวกเขาต้องการดูคอนเทนเนอร์ที่มีอยู่
Luca Spiller

1
ปัญหาของฉันกับคำตอบนี้คือผู้คนได้ถามเกี่ยวกับการใช้docker attachแล้วและฉันชี้ให้เห็นว่า:...the attach command attaches to the running tty, not a new one, hence the question title is "...with new TTY"
โปรแกรมเตอร์

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

4

nsenterทำอย่างนั้น อย่างไรก็ตามฉันก็ต้องใส่ภาชนะในวิธีที่ง่ายและ nsenter ไม่พอสำหรับความต้องการของฉัน มันเป็นรถในบางโอกาส (หน้าจอสีดำบวกกับธง -wd ไม่ทำงาน) นอกจากนี้ฉันต้องการเข้าสู่ระบบในฐานะผู้ใช้เฉพาะและในไดเรกทอรีเฉพาะ

ฉันลงเอยด้วยการทำเครื่องมือของตัวเองเพื่อป้อนคอนเทนเนอร์ คุณสามารถค้นหาได้ที่: https://github.com/Pithikos/docker-enter

การใช้งานเป็นเรื่องง่ายเหมือน

./docker-enter [-u <user>] [-d <directory>] <container ID>

แค่ลองเจ๋งมาก! บน Ubuntu ต้องเรียกใช้ sudo apt-get build-essential -y gcc docker-enter.c -o docker-ป้อน sudo ./docker-enter <short-container-id> ดีที่ฉันไม่ต้องใช้ ID แบบเต็มเช่นเดียวกับ lxc-attach -n Codebase นั้นสั้นพอที่จะสแกนได้อย่างรวดเร็วเพื่อค้นหาสิ่งที่เป็นอันตราย
Programster

ฉันสร้าง ebuild บน gentoo ได้ที่github.com/steveeJ/personal-portage-overlayเป็น app-emulation / docker-enter
stefanjunker

ฉันได้เพิ่มการกวดวิชา / script สำหรับอัตโนมัตินี้สำหรับผู้ใช้อูบุนตูที่programster.blogspot.co.uk/2014/01/...
Programster

2

วิธี "nsinit" คือ:

ติดตั้ง nsinit

git clone git@github.com:dotcloud/docker.git
cd docker
make shell

จากภายในคอนเทนเนอร์:

go install github.com/dotcloud/docker/pkg/libcontainer/nsinit/nsinit

จากด้านนอก:

docker cp id_docker_container:/go/bin/nsinit /root/

ใช้มัน

cd /var/lib/docker/execdriver/native/<container_id>/
nsinit exec bash

2
docker exec -t -i container_name /bin/bash

จะพาคุณไปที่คอนโซลคอนเทนเนอร์


ฉันลงจอดคำถามนี้เพราะฉันมีปัญหาเดียวกัน คำตอบที่ดูเหมือนคล้ายกันใช้ไม่ได้สำหรับฉันจนกว่าฉันจะแก้ไข ฉันสามารถลบได้
Danstan


1

ฉันเริ่ม powershell บน microsoft / iis ที่ทำงานเป็น daemon โดยใช้

docker exec -it <nameOfContainer> powershell

ดูเหมือนว่าคำถามเกี่ยวกับภาชนะที่ใช้ลินุกซ์ คำตอบนี้อาจใช้ได้เฉพาะเมื่อคุณมีคอนเทนเนอร์ที่ใช้ windows หรือถ้าคุณติดตั้ง PowerShell เวอร์ชัน. NET Core เช่น PowerShell 6 หรือใหม่กว่า
Manfred

0

ในWindows 10ฉันได้ติดตั้งตัวเชื่อมต่อแล้ว ฉันใช้ Jnekins บนคอนเทนเนอร์และฉันพบข้อความแสดงข้อผิดพลาดเดียวกัน นี่คือคำแนะนำทีละขั้นตอนเพื่อแก้ไขปัญหานี้:

ขั้นตอนที่ 1:เปิด gitbash และเรียกใช้ตัวเรียกใช้ -p 8080: 8080 -p 50000: 50000 เจนกินส์

ขั้นตอนที่ 2:เปิดเทอร์มินัลใหม่

ขั้นตอนที่ 3:ทำ "นักเทียบท่า PS" เพื่อรับรายการคอนเทนเนอร์ที่ใช้งานอยู่ คัดลอก id คอนเทนเนอร์

ขั้นตอนที่ 4:ตอนนี้ถ้าคุณทำ "docker exec -it {container id} sh" หรือ "docker exec -it {container id} bash" คุณจะได้รับข้อความแสดงข้อผิดพลาดคล้ายกับ "อุปกรณ์อินพุตไม่ใช่ TTY หากคุณเป็น ใช้ mintty ให้ลองนำหน้าคำสั่งด้วย 'winpty' "

ขั้นตอนที่ 5:เรียกใช้คำสั่ง " $ winpty docker exec -it {container id} sh "

ปลาไหล !! ตอนนี้คุณอยู่ในอาคารผู้โดยสารแล้ว

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