วิธีรับ bash หรือ ssh ลงใน container ที่กำลังรันในโหมดเบื้องหลัง


933

ฉันต้องการ ssh หรือทุบตีลงในคอนเทนเนอร์นักเทียบท่าที่กำลังวิ่งอยู่ โปรดดูตัวอย่าง:

$ sudo docker run -d webserver
webserver is clean image from ubuntu:14.04
$ sudo docker ps
CONTAINER ID  IMAGE            COMMAND    CREATED STATUS  PORTS          NAMES
665b4a1e17b6  webserver:latest /bin/bash  ...     ...     22/tcp, 80/tcp loving_heisenberg 

ตอนนี้ฉันต้องการได้รับบางสิ่งเช่นนี้ (เข้าไปในคอนเทนเนอร์ที่ทำงาน):

$ sudo docker run -t -i webserver (or maybe 665b4a1e17b6 instead)
$ root@665b4a1e17b6:/# 
However when I run the line above I get new CONTAINER ID
$ root@42f1e37bd0e5:/#

vagrant sshผมใช้จรจัดและฉันต้องการที่จะได้รับเป็นพฤติกรรมที่คล้ายกัน


อีกทางเลือกหนึ่งsudo docker exec -i -t 665b4a1e17b6 /bin/shเพื่อให้สามารถติดตั้งโปรแกรมและแพ็คเกจ apt
fonjeekay

1
โปรดทราบว่าการใช้ SSH ทุบตีเข้าทำงานภาชนะคือการปฏิบัติที่ไม่ดี - เห็นเหตุผลที่นี่ sudo docker exec -i -t container-name /bin/bashเป็นวิธีที่จะไป
patryk.beza

คำตอบ:


1306

คำตอบคือattachคำสั่งของ Docker ดังนั้นสำหรับตัวอย่างข้างต้นการแก้ปัญหาจะเป็น:

$ sudo docker attach 665b4a1e17b6 #by ID
or
$ sudo docker attach loving_heisenberg #by Name
$ root@665b4a1e17b6:/#

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

$ sudo docker exec -i -t 665b4a1e17b6 /bin/bash #by ID

หรือ

$ sudo docker exec -i -t loving_heisenberg /bin/bash #by Name
$ root@665b4a1e17b6:/#

5
หรือมิฉะนั้นให้ดำเนินการsudo docker attach loving_heisenberg
Thiago Perrotta

51
คำสั่งแนบไม่ทำงานสำหรับฉันมันทำให้นักเทียบท่าหยุด ... ความคิดใด ๆ ว่าทำไมมันเกิดขึ้น?
Mo J. Mughrabi

10
คำเตือนสำหรับผู้ใช้ boot2docker: ลบ sudo :)
Henno

17
-i -tเท่ากับ-it
pasha.zhukov

47
นี่เป็นคำตอบที่อันตรายที่จะเลือกและลงคะแนนอย่างมาก docker attachตัวอย่างเช่นไปยัง MongoDB จะฆ่าอินสแตนซ์ ตามที่อธิบายในรายละเอียดเพิ่มเติมในคำถามนี้ attachและexecเป็นสัตว์ที่แตกต่างกัน
fwc

675

จาก Docker 1.3 เป็นต้นไป:

docker exec -it <containerIdOrName> bash

โดยทั่วไปถ้าภาชนะเทียบท่าเริ่มต้นโดยใช้คำสั่งคุณสามารถเข้าถึงได้โดยใช้/bin/bash ถ้าไม่เช่นนั้นคุณจะต้องดำเนินการคำสั่งในการสร้างอินสแตนซ์ทุบตีภายในภาชนะที่ใช้attachexec

นอกจากนี้เมื่อต้องการออกจาก Bash โดยไม่ปล่อยให้ Bash ทำงานในกระบวนการโกง:

exit

ใช่มันเป็นเรื่องง่าย


ยังไม่ได้คิดวิธีการทำงานของนาโน คิดว่าอาจเกี่ยวข้องกับนักเทียบท่าจาก phusion
WiR3D

มีวิธีการตั้งค่าทุบตีโดยค่าเริ่มต้นในนักเทียบท่า?
ipeacocks

@ipeacocks ใช่ถ้าRUNคำสั่งใน dockerfile /bin/bashคือ แต่ขึ้นอยู่กับว่าคุณหมายถึงอะไร หากคุณต้องการเรียกใช้คอนเทนเนอร์และมีทุบตีพร้อมใช้งานทันทีในเทอร์มินัลเดียวกันดังนั้นการรันด้วย-itควรทำ
WiR3D

10
การใช้กลุ่มนักเทียบท่าเป็นการฝึกฝนที่ไม่ดี ผู้ใช้ที่อยู่ในกลุ่มนักเทียบท่าส่วนใหญ่จะใช้กับการอนุญาตรูทโดยไม่จำเป็นต้องใช้ sudo projectatomic.io/blog/2015/08/...
Maiku Mori

1
ฉันคิดว่ามันไม่ได้สร้างความแตกต่างมากนักจากมุมมองความปลอดภัยของโฮสต์ไม่ว่าคุณจะใช้กลุ่มsudoVS dockerไม่ว่าจะด้วยวิธีใดก็ตามจะมีช่องโหว่ด้านความปลอดภัยที่ติดตั้งไว้ในตัวเทียบท่าซึ่งสามารถให้สิทธิพิเศษอย่างเต็มรูปแบบในระบบไฟล์โฮสต์จากแขก - ไม่ว่าคุณจะใช้กลุ่มนักเทียบท่าหรือsudoเปิดตัวคอนเทนเนอร์
สูงศักดิ์

123

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

docker run -i -t --entrypoint /bin/bash <imageID>


10
นั่นให้คอนเทนเนอร์ที่แตกต่างกันเหมือนกับคำตอบของ @ kraxor
Blaisorblade

27

ลองสิ่งนี้:

sudo docker run -i -t webserver /bin/bash

ที่มา: https://docs.docker.com/articles/basics/#running-an-interactive-shell


14
มันไม่เหมาะสมเพราะฉันได้รับ ID คอนเทนเนอร์ที่แตกต่างกัน ( root@42f1e37bd0e5:/#และไม่root@665b4a1e17b6:/#)
Timur Fayzrakhmanov

ลิงก์นั้นตายแล้วคุณควรอัปเดต
Ahmet Karakaya

19

จากคำตอบของ @ Timur ฉันได้สร้างสคริปต์ที่มีประโยชน์ต่อไปนี้

ติดตั้ง

ใส่docker-sshไฟล์ของคุณ$PATHด้วยเนื้อหาดังต่อไปนี้

#!/bin/bash -xe

# docker container id or name might be given as a parameter
CONTAINER=$1

if [[ "$CONTAINER" == "" ]]; then
  # if no id given simply just connect to the first running container
  CONTAINER=$(docker ps | grep -Eo "^[0-9a-z]{8,}\b")
fi

# start an interactive bash inside the container
# note some containers don't have bash, then try: ash (alpine), or simply sh
# the -l at the end stands for login shell that reads profile files (read man)
docker exec -i -t $CONTAINER bash -l

หมายเหตุ : ภาชนะบางคนไม่ได้มีbashแต่ash, shฯลฯ ในกรณีเหล่านี้bashจะถูกแทนที่ในสคริปต์ดังกล่าวข้างต้น

การใช้

หากคุณมีอินสแตนซ์ที่ใช้งานอยู่เพียงตัวเดียวให้เรียกใช้

$> docker-ssh 

มิฉะนั้นให้ระบุพารามิเตอร์ docker id ที่คุณได้รับจากdocker ps(col แรก)

$> docker-ssh 50m3r4nd0m1d

ฉันขอทราบได้ไหมว่าทำไมเราถึงต้องการ -l ในตอนท้าย
Nam G VU

เพื่อเริ่มต้นทุบตีเป็นเปลือกเข้าสู่ระบบการอ่านพารามิเตอร์สภาพแวดล้อม (อธิบายไว้ในบรรทัดด้านบนคำสั่ง)
Matyas

13

หากคอนเทนเนอร์ของคุณไม่มีทุบตีติดตั้งคุณสามารถลอง sh:

docker exec -it CONTAINER /bin/sh

หรือค้นหาเชลล์ใน / bin ก่อน:

docker export CONTAINER|tar -t|egrep ^bin/

คืออะไร"กงสุล" ? คุณมีการอ้างอิงสำหรับมันหรือไม่? คุณหมายถึง"console"หรือไม่
Peter Mortensen

9

ฉันสร้างเซิร์ฟเวอร์ SSH containerized ที่ให้ความสามารถ SSH กับคอนเทนเนอร์ที่ใช้งานอยู่ คุณไม่จำเป็นต้องเปลี่ยนตู้คอนเทนเนอร์ ความต้องการเพียงอย่างเดียวคือภาชนะที่มีการทุบตี

หากคุณมีที่บรรจุชื่อ 'web-server1' คำสั่งเรียกใช้นักเทียบท่าต่อไปนี้จะเริ่มต้นคอนเทนเนอร์ที่สองที่จะจัดเตรียม SSH สำหรับคอนเทนเนอร์แรก

docker run -ti --name sshd-web-server1 -e CONTAINER=web-server1 -p 2222:22 \
-v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker \
jeroenpeeters/docker-ssh

สำหรับตัวชี้เพิ่มเติมให้ชำระเงินhttps://github.com/jeroenpeeters/docker-ssh


นี่ควรเป็นคำตอบที่ยอมรับ ^
Nam G VU

อย่างไรก็ตามเราจะโหลดอัตโนมัติ. bashrc อย่างไรเมื่อเริ่มเซสชัน ssh โดยใช้โซลูชันของคุณ ยังโพสต์ปัญหาเกี่ยวกับ github github.com/jeroenpeeters/docker-ssh/issues/30
Nam G VU

6

@jpetazzo มีโพสต์ที่ยอดเยี่ยมเกี่ยวกับเรื่องนี้ คำตอบสั้น ๆ น่าจะใช้nsenter:

PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid

PS: อย่าลืมตรวจสอบการสนทนาในความคิดเห็นของโพสต์ ...

ไชโย


1
นั่นคือการโพสต์ค่อนข้างเก่าที่ไม่จำเป็นจริงๆ @ docker execโซลูชั่นของ WiR3D ค่อนข้างสะดวกกว่า
drevicko

4

นอกจากนี้คุณยังสามารถให้ที่อยู่ IP ที่สามารถกำหนดเส้นทางได้ด้วย Pipework และหลังจากนั้น SSH นั้นลงในเครื่องด้วยที่อยู่ IP ใหม่นั้น

นี่จะเป็น "ดั้งเดิม" (ssh) มากกว่าแทนที่จะใช้คำสั่งเฉพาะแอปพลิเคชันเช่นdocker attachและในที่สุดจะทำให้ 'พกพา' มากกว่าในระบบและเวอร์ชัน


กรุณาเพิ่มวิธี simples วิธีการทำ ถ้าพูดตามตรงฉันต้องการจริงๆ แต่ฉันไม่มีเวลาที่จะค้นหาทางออกที่ง่ายที่สุดสำหรับสิ่งนั้น คุณช่วยโพสต์คำตอบของคุณที่นี่ได้ไหม? มันจะดีมาก ..
Timur Fayzrakhmanov

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

คุณถูกต้อง - ไม่มีวิธีที่ชัดเจนและง่ายต่อการทำ (ขอบคุณสำหรับลิงก์ฉันคิดว่าฉันจะกลับมาใหม่ในภายหลัง
Timur Fayzrakhmanov

3

บางครั้งมันจะมีประโยชน์ที่จะสามารถ ssh ลงในภาชนะ Docker โดยเฉพาะอย่างยิ่งในระหว่างการพัฒนา อิมเมจ Docker ต่อไปนี้อนุญาตให้ ssh ลงในคอนเทนเนอร์โดยใช้ไพรเวตคีย์:

UbuntuWithSSH-เทียบท่า

สรุปสาระสำคัญของ Dockerfile เป็นhttps://gist.github.com/devbkhadka/98792f7bca57f9778793b2db758b3d07



1

GOINSIDE

ติดตั้งgoinsideเครื่องมือบรรทัดคำสั่งด้วย:

sudo npm install -g goinside

และเข้าไปในคอนเทนเนอร์นักเทียบท่าที่มีขนาดเทอร์มินัลที่เหมาะสมด้วย:

goinside docker_container_name

สำหรับรายละเอียดเพิ่มเติมตรวจสอบนี้ออก


0

หากต้องการทุบตีลงในภาชนะที่ใช้งานให้พิมพ์สิ่งนี้:

docker exec -t -i container_name /bin/bash

1
นี่เป็นคำตอบเดียวกับ @AdamKalnas แม้ว่า
Bruni

0

สำหรับข้อมูลเท่านั้น หากคุณต้องการเข้าสู่ระบบในภาชนะง่าย ๆ ที่ไม่ใช่ภูตคุณต้องใช้คำสั่งต่อไปนี้:

docker start {id}
docker attach {id}

-1

หากคอนเทนเนอร์หยุดเหมือนที่เก็บข้อมูลเท่านั้นวิธีการแก้ปัญหาที่ดีก็คือการเรียกใช้ตู้เก็บของทิ้งทุกครั้งที่คุณต้องการแนบกับตู้เก็บข้อมูล ในกรณีนี้คอนเทนเนอร์ข้อมูลอาจว่างเปล่าทั้งหมดเนื่องจากคอนเทนเนอร์ชั่วคราวจะมีเครื่องมือระบบปฏิบัติการ

$ docker run --rm --volumes-from mydata -it ubuntu bash
root@645045d3cc87:/# ls /mydata
root@645045d3cc87:/# touch /mydata/foo
root@645045d3cc87:/# exit
exit
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.