Bagaimana cara memasukkan bash atau ssh ke wadah yang sedang berjalan dalam mode latar belakang?

933

Saya ingin ssh atau menabrak wadah buruh pelabuhan berjalan. Silakan, lihat contoh:

$ 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 

sekarang saya ingin mendapatkan sesuatu seperti ini (masuk ke dalam wadah yang sedang berjalan):

$ 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:/#

Saya menggunakan Vagrant dan saya ingin mendapatkan perilaku yang sama vagrant ssh.

Timur Fayzrakhmanov
sumber
atau sudo docker exec -i -t 665b4a1e17b6 /bin/shdapat menginstal program dan paket apt
fonjeekay
1
Perhatikan bahwa menggunakan SSH untuk menampar ke dalam wadah yang sedang berjalan adalah praktik yang buruk - lihat alasannya di sini . sudo docker exec -i -t container-name /bin/bashadalah cara untuk pergi.
patryk.beza

Jawaban:

1306

Jawabannya adalah attachperintah Docker . Jadi untuk contoh saya di atas, solusinya adalah:

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

Untuk Docker versi 1.3 atau yang lebih baru: Terima kasih kepada pengguna WiR3D yang menyarankan cara lain untuk mendapatkan shell penampung. Jika kita menggunakan, attachkita hanya bisa menggunakan satu instance dari shell. Jadi jika kita ingin membuka terminal baru dengan instance baru dari shell penampung, kita hanya perlu menjalankan yang berikut:

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

atau

$ sudo docker exec -i -t loving_heisenberg /bin/bash #by Name
$ root@665b4a1e17b6:/#
Timur Fayzrakhmanov
sumber
5
Atau, jalankansudo docker attach loving_heisenberg
Thiago Perrotta
51
perintah attach tidak bekerja untuk saya, itu menyebabkan buruh pelabuhan membeku .. ada ide mengapa itu terjadi?
Mo J. Mughrabi
10
Pengingat untuk pengguna boot2docker: hapus sudo :)
Henno
17
-i -tsama dengan-it
pasha.zhukov
47
Ini adalah jawaban berbahaya untuk dipilih dan sangat dipilih. docker attachmisalnya, ke instance MongoDB, akan mematikan instance tersebut. Seperti dijelaskan lebih terinci dalam pertanyaan ini attach dan execmerupakan binatang yang berbeda.
fwc
675

Dari Docker 1.3 dan selanjutnya:

docker exec -it <containerIdOrName> bash

Pada dasarnya, jika wadah Docker mulai menggunakan /bin/bashperintah Anda dapat mengaksesnya menggunakan attach. Jika tidak, maka Anda perlu menjalankan perintah untuk membuat instance Bash di dalam wadah menggunakan exec.

Juga untuk keluar dari Bash tanpa membiarkan Bash berjalan dalam proses jahat:

exit

Yap, sesederhana itu.

WiR3D
sumber
masih belum menemukan cara agar nano bekerja. Pikirkan yang mungkin melibatkan docker-ssh dari phusion
WiR3D
Apakah ada cara untuk mengatur bash secara default di buruh pelabuhan?
ipeacocks
@ipeacocks ya, jika RUNperintah di dockerfile adalah /bin/bash. Tetapi tergantung apa yang Anda maksud. Jika Anda ingin menjalankan wadah dan memiliki bash segera tersedia di terminal yang sama maka jalankan dengan -itharus melakukannya
WiR3D
10
Menggunakan grup buruh pelabuhan adalah praktik yang buruk. Setiap pengguna yang ada dalam grup buruh pelabuhan pada dasarnya digunakan dengan izin root tanpa perlu menggunakan sudo. projectatomic.io/blog/2015/08/...
Maiku Mori
1
Saya pikir itu tidak membuat banyak perbedaan, dari sudut pandang keamanan host, apakah Anda menggunakan sudovs dockergrup. Apa pun itu, ada lubang keamanan yang dibangun ke dalam buruh pelabuhan yang dapat memberikan hak istimewa penuh dalam sistem file host dari tamu - terlepas dari apakah Anda menggunakan grup buruh pelabuhan atau sudountuk meluncurkan wadah.
nobar
123

Meskipun penulis pertanyaan secara khusus mengatakan bahwa mereka tertarik pada sebuah wadah yang sedang berjalan, ada baiknya juga dicatat bahwa jika wadah itu tidak berjalan, tetapi Anda ingin menjalankannya untuk melihat-lihat Anda dapat berlari:

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

Adam Kalnas
sumber
10
Itu memberikan wadah yang berbeda, sama seperti jawaban @ kraxor.
Blaisorblade
19

Berdasarkan jawaban @ Timur, saya telah membuat skrip praktis berikut

Mempersiapkan

Masukkan docker-sshfile Anda $PATHdengan konten berikut

#!/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

Catatan : Beberapa wadah tidak mengandung bash, tetapi ash, shdll. Dalam kasus ini bashharus diganti dalam skrip di atas.

Pemakaian

Jika Anda hanya memiliki satu instance yang berjalan, jalankan saja

$> docker-ssh 

Jika tidak, berikan parameter id buruh pelabuhan yang Anda dapatkan dari docker ps(kolom pertama)

$> docker-ssh 50m3r4nd0m1d
Matya
sumber
Bolehkah saya tahu mengapa kita perlu -l pada akhirnya?
Nam G VU
untuk memulai bash sebagai shell login, membaca parameter lingkungan (dijelaskan pada baris di atas perintah)
Matyas
13

Jika wadah Anda belum memasang bash, Anda dapat mencoba sh:

docker exec -it CONTAINER /bin/sh

Atau cari dulu kerang di / bin:

docker export CONTAINER|tar -t|egrep ^bin/
laktak
sumber
Apa itu "konsul" ? Apakah Anda punya referensi untuk itu? Apakah maksud Anda "konsol" ?
Peter Mortensen
9

Saya telah membuat server SSH kemas yang menyediakan kemampuan SSH untuk wadah yang berjalan. Anda tidak perlu mengubah wadah Anda. Satu-satunya persyaratan adalah bahwa wadah memiliki bash.

Jika Anda memiliki wadah dengan nama 'web-server1'. Perintah run docker berikut akan memulai container kedua yang akan menyediakan SSH untuk container pertama.

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

Untuk petunjuk lebih lanjut, checkout https://github.com/jeroenpeeters/docker-ssh

Jeroen Peeters
sumber
Ini seharusnya jawaban yang diterima ^
Nam G VU
Ngomong-ngomong, bagaimana kita bisa .bashrc otomatis dimuat ketika memulai sesi ssh menggunakan solusi Anda? Juga memposting masalah di github github.com/jeroenpeeters/docker-ssh/issues/30
Nam G VU
6

@jpetazzo memiliki pos yang luar biasa tentang subjek ini . Jawaban singkatnya adalah menggunakan nsenter:

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

PS: Jangan lupa cek diskusi di komentar postingan ...

Tepuk tangan

Richard
sumber
1
Itu posting yang agak lama yang tidak lagi benar-benar diperlukan . Solusi @ WiR3D docker execagak lebih nyaman.
drevicko
4

Anda juga dapat memberi wadah Docker alamat IP yang dapat dirutekan dengan Pipework, dan setelah itu SSH ke dalam mesin dengan alamat IP baru itu.

Ini akan lebih "tradisional" (ssh), daripada menggunakan perintah khusus aplikasi seperti docker attach, dan pada akhirnya akan membuatnya lebih 'portabel' di seluruh sistem dan versi.

radriaanse
sumber
Tolong, tambahkan cara sederhana bagaimana melakukannya. Kalau jujur, saya benar-benar membutuhkannya, tetapi saya tidak punya waktu untuk mencari solusi paling sederhana untuk itu. Bisakah Anda memposting jawaban Anda di sini? Ini akan menjadi luar biasa ..
Timur Fayzrakhmanov
2
Ada 2 cara untuk mencapai ini, tetapi itu tidak sederhana, dan akan menjadi posting besar. Anda dapat memeriksa tautan ini sendiri, untuk menggunakan pipework atau tautan ini , witch pada dasarnya menyelesaikan hal yang sama dengan Pipework dan sedikit lebih sederhana, tetapi Anda harus melakukannya secara manual. Jadi itu tergantung berapa banyak server tempat berbicara. Jika Anda tidak dapat menemukan sesuatu yang lebih spesifik, beri tahu saya. Tetapi saya juga tidak punya waktu untuk menulis tutorial lengkap.
radriaanse
Anda benar - tidak ada cara yang jelas dan sederhana untuk melakukannya (Terima kasih atas
tautannya
2
docker run -it openjdk:8

Ini bekerja :-)

Kishan B
sumber
1

MASUK KE DALAM

instal goinsidealat baris perintah dengan:

sudo npm install -g goinside

dan masuk ke dalam wadah buruh pelabuhan dengan ukuran terminal yang tepat dengan:

goinside docker_container_name

untuk lebih jelasnya lihat ini .

Soorena
sumber
0

Untuk menabrak wadah yang sedang berjalan, ketik ini:

docker exec -t -i container_name /bin/bash
Agustí Sánchez
sumber
1
ini adalah jawaban yang sama dengan @AdamKalnas
Bruni
0

Hanya untuk informasi. Jika Anda perlu masuk dalam wadah sederhana yang bukan daemon, Anda perlu menggunakan perintah berikut:

docker start {id}
docker attach {id}
Nek
sumber
-1

jika wadah dihentikan seperti misalnya wadah data saja, maka solusi yang baik adalah dengan menjalankan wadah sekali pakai setiap kali Anda ingin melampirkan ke wadah data. Dalam hal ini wadah data itu sendiri bisa sepenuhnya kosong, karena wadah sementara akan memiliki alat OS.

$ docker run --rm --volumes-from mydata -it ubuntu bash
root@645045d3cc87:/# ls /mydata
root@645045d3cc87:/# touch /mydata/foo
root@645045d3cc87:/# exit
exit
David Dehghan
sumber